Repository: lldap/lldap (language: rust)

Issue:
[BUG] First name and Last name are empty
**Describe the bug**
Version: 0.5.1-alpha
When viewing the user details, the fields "First name" and "Last name" are always empty

**To Reproduce**
Steps to reproduce the behavior:
1. Spin up a fresh 0.5.1-alpha installation, no external database
2. Create a new user
3. Go back to the user list
4. Click on the user id to view details
5. See empty fields (though, the database itself contains the correct values :)

**Expected behavior**
Fields show the current database value

**Logs**

Do not contain anything useful I would say, but I will still add them:

```
2024-01-31T04:09:06.691235305+00:00  DEBUG    HTTP request [ 21.2µs | 100.00% ] method: "GET" | uri: "/"
2024-01-31T04:09:06.691256505+00:00  DEBUG    ┕━ 🐛 [debug]:  | status_code: 200
2024-01-31T04:09:13.286811009+00:00  DEBUG    HTTP request [ 28.7ms | 60.07% / 100.00% ] method: "POST" | uri: "/api/graphql"
2024-01-31T04:09:13.288012493+00:00  DEBUG    ┝━ check_if_token_is_valid [ 874µs | 3.04% ]
2024-01-31T04:09:13.288885616+00:00  DEBUG    │  ┕━ 🐛 [debug]:  | return: ValidationResults { user: UserId(CaseInsensitiveString("admin")), permission: Admin }
2024-01-31T04:09:13.296693404+00:00  DEBUG    ┝━ [GraphQL mutation] create_user [ 10.6ms | 2.05% / 36.89% ]
2024-01-31T04:09:13.296700804+00:00  DEBUG    │  ┝━ 🐛 [debug]: "pgriffin"
2024-01-31T04:09:13.309889452+00:00  DEBUG    │  ┝━ create_user [ 9.27ms | 32.29% ] request: CreateUserRequest { user_id: UserId(CaseInsensitiveString("pgriffin")), email: Email("peter.griffin@foobar.com"), display_name: Some("Griffin"), first_name: Some("Peter"), last_name: Some("Griffin"), avatar: None, attributes: [] } | user_id: "pgriffin"
2024-01-31T04:09:13.347839508+00:00  DEBUG    │  ┕━ get_user_details [ 733µs | 2.55% ] user_id: "pgriffin"
2024-01-31T04:09:13.349730115+00:00  DEBUG    │     ┕━ 🐛 [debug]:  | return: Ok(User { user_id: UserId(CaseInsensitiveString("pgriffin")), email: Email("peter.griffin@foobar.com"), display_name: Some("Griffin"), creation_date: 2024-01-31T04:09:13.310054492, uuid: Uuid("a275f75c-b0cd-3859-aa23-a36b77a630c6"), attributes: [AttributeValue { name: AttributeName(CaseInsensitiveString("first_name")), value: Serialized("Peter") }, AttributeValue { name: AttributeName(CaseInsensitiveString("last_name")), value: Serialized("Griffin") }] })
2024-01-31T04:09:13.351045480+00:00  DEBUG    ┕━ 🐛 [debug]:  | status_code: 200
2024-01-31T04:09:13.446455422+00:00  DEBUG    HTTP request [ 5.04ms | 6.22% / 100.00% ] method: "POST" | uri: "/auth/opaque/register/start"
2024-01-31T04:09:13.446486343+00:00  DEBUG    ┝━ opaque_register_start [ 4.72ms | 25.42% / 93.78% ]
2024-01-31T04:09:13.446488743+00:00  DEBUG    │  ┝━ check_if_token_is_valid [ 32.3µs | 0.64% ]
2024-01-31T04:09:13.446520343+00:00  DEBUG    │  │  ┕━ 🐛 [debug]:  | return: ValidationResults { user: UserId(CaseInsensitiveString("admin")), permission: Admin }
2024-01-31T04:09:13.447820307+00:00  DEBUG    │  ┝━ get_user_groups [ 748µs | 14.85% ] user_id: "pgriffin"
2024-01-31T04:09:13.448909591+00:00  DEBUG    │  │  ┕━ 🐛 [debug]:  | return: {}
2024-01-31T04:09:13.449141792+00:00  DEBUG    │  ┕━ registration_start [ 2.66ms | 52.87% ]
2024-01-31T04:09:13.451833442+00:00  DEBUG    ┕━ 🐛 [debug]:  | status_code: 200
2024-01-31T04:09:13.657641221+00:00  DEBUG    HTTP request [ 4.04ms | 17.47% / 100.00% ] method: "POST" | uri: "/auth/opaque/register/finish"
2024-01-31T04:09:13.658338384+00:00  DEBUG    ┝━ opaque_register_finish [ 3.34ms | 8.40% / 82.53% ]
2024-01-31T04:09:13.658341784+00:00  DEBUG    │  ┕━ registration_finish [ 3.00ms | 74.13% ]
2024-01-31T04:09:13.702884664+00:00  DEBUG    ┕━ 🐛 [debug]:  | status_code: 200
2024-01-31T04:09:13.801359178+00:00  DEBUG    HTTP request [ 61.0µs | 100.00% ] method: "GET" | uri: "/favicon.ico"
2024-01-31T04:09:13.801423858+00:00  DEBUG    ┕━ 🐛 [debug]:  | status_code: 200
2024-01-31T04:09:13.801750819+00:00  DEBUG    HTTP request [ 2.14ms | 57.78% / 100.00% ] method: "POST" | uri: "/api/graphql"
2024-01-31T04:09:13.801781179+00:00  DEBUG    ┝━ check_if_token_is_valid [ 31.0µs | 1.45% ]
2024-01-31T04:09:13.801812020+00:00  DEBUG    │  ┕━ 🐛 [debug]:  | return: ValidationResults { user: UserId(CaseInsensitiveString("admin")), permission: Admin }
2024-01-31T04:09:13.802489822+00:00  DEBUG    ┝━ [GraphQL query] users [ 873µs | 16.87% / 40.77% ]
2024-01-31T04:09:13.802492462+00:00  DEBUG    │  ┝━ 🐛 [debug]:  | filters: None
2024-01-31T04:09:13.803207225+00:00  DEBUG    │  ┕━ list_users [ 512µs | 23.90% ] filters: None | _get_groups: false
2024-01-31T04:09:13.804555509+00:00  DEBUG    │     ┕━ 🐛 [debug]:  | return: [UserAndGroups { user: User { user_id: UserId(CaseInsensitiveString("admin")), email: Email(""), display_name: Some("Administrator"), creation_date: 2024-01-30T16:23:14.444961545, uuid: Uuid("6381e06a-36bb-3e5c-9bda-38ce20675ce7"), attributes: [] }, groups: Some([GroupDetails { group_id: GroupId(1), display_name: GroupName("lldap_admin"), creation_date: 2024-01-30T16:23:14.356956508, uuid: Uuid("b5289316-a12b-3483-ad5a-4209398392ed"), attributes: [] }]) }, UserAndGroups { user: User { user_id: UserId(CaseInsensitiveString("pgriffin")), email: Email("peter.griffin@foobar.com"), display_name: Some("Griffin"), creation_date: 2024-01-31T04:09:13.310054492, uuid: Uuid("a275f75c-b0cd-3859-aa23-a36b77a630c6"), attributes: [AttributeValue { name: AttributeName(CaseInsensitiveString("first_name")), value: Serialized("Peter") }, AttributeValue { name: AttributeName(CaseInsensitiveString("last_name")), value: Serialized("Griffin") }] }, groups: Some([]) }, UserAndGroups { user: User { user_id: UserId(CaseInsensitiveString("test1")), email: Email("test1@outlook.de"), display_name: Some("test1"), creation_date: 2024-01-31T03:58:12.622065848, uuid: Uuid("c96387ba-4263-3ed4-bb5a-518b1892638d"), attributes: [AttributeValue { name: AttributeName(CaseInsensitiveString("first_name")), value: Serialized("Testing") }, AttributeValue { name: AttributeName(CaseInsensitiveString("last_name")), value: Serialized("McTestTest") }] }, groups: Some([GroupDetails { group_id: GroupId(3), display_name: GroupName("lldap_strict_readonly"), creation_date: 2024-01-30T16:23:14.417820047, uuid: Uuid("ba3ee65f-2a25-3ecf-8436-4cca3d3292d0"), attributes: [] }]) }]
2024-01-31T04:09:13.804908551+00:00  DEBUG    ┕━ 🐛 [debug]:  | status_code: 200
2024-01-31T04:09:16.690403601+00:00  DEBUG    HTTP request [ 58.7µs | 100.00% ] method: "GET" | uri: "/"
2024-01-31T04:09:16.690464361+00:00  DEBUG    ┕━ 🐛 [debug]:  | status_code: 200
2024-01-31T04:09:16.691122043+00:00  DEBUG    HTTP request [ 37.1µs | 100.00% ] method: "GET" | uri: "/"
2024-01-31T04:09:16.691160204+00:00  DEBUG    ┕━ 🐛 [debug]:  | status_code: 200
2024-01-31T04:09:17.580075558+00:00  DEBUG    HTTP request [ 68.8µs | 100.00% ] method: "GET" | uri: "/favicon.ico"
2024-01-31T04:09:17.580146678+00:00  DEBUG    ┕━ 🐛 [debug]:  | status_code: 200
2024-01-31T04:09:17.580825681+00:00  DEBUG    HTTP request [ 1.38ms | 60.94% / 100.00% ] method: "POST" | uri: "/api/graphql"
2024-01-31T04:09:17.580858201+00:00  DEBUG    ┝━ check_if_token_is_valid [ 31.8µs | 2.30% ]
2024-01-31T04:09:17.580889641+00:00  DEBUG    │  ┕━ 🐛 [debug]:  | return: ValidationResults { user: UserId(CaseInsensitiveString("admin")), permission: Admin }
2024-01-31T04:09:17.581327043+00:00  DEBUG    ┝━ [GraphQL query] user [ 325µs | 12.96% / 23.54% ]
2024-01-31T04:09:17.581330163+00:00  DEBUG    │  ┝━ 🐛 [debug]:  | user_id: "pgriffin"
2024-01-31T04:09:17.581833564+00:00  DEBUG    │  ┕━ get_user_details [ 146µs | 10.59% ] user_id: "pgriffin"
2024-01-31T04:09:17.582207726+00:00  DEBUG    │     ┕━ 🐛 [debug]:  | return: Ok(User { user_id: UserId(CaseInsensitiveString("pgriffin")), email: Email("peter.griffin@foobar.com"), display_name: Some("Griffin"), creation_date: 2024-01-31T04:09:13.310054492, uuid: Uuid("a275f75c-b0cd-3859-aa23-a36b77a630c6"), attributes: [AttributeValue { name: AttributeName(CaseInsensitiveString("first_name")), value: Serialized("Peter") }, AttributeValue { name: AttributeName(CaseInsensitiveString("last_name")), value: Serialized("Griffin") }] })
2024-01-31T04:09:17.582258726+00:00  DEBUG    ┝━ [GraphQL query] user::groups [ 182µs | 0.65% / 13.21% ]
2024-01-31T04:09:17.582260806+00:00  DEBUG    │  ┝━ 🐛 [debug]:  | user_id: UserId(CaseInsensitiveString("pgriffin"))
2024-01-31T04:09:17.582263966+00:00  DEBUG    │  ┕━ get_user_groups [ 173µs | 12.55% ] user_id: "pgriffin"
2024-01-31T04:09:17.582519127+00:00  DEBUG    │     ┕━ 🐛 [debug]:  | return: {}
2024-01-31T04:09:17.582802928+00:00  DEBUG    ┕━ 🐛 [debug]:  | status_code: 200
2024-01-31T04:09:17.681163401+00:00  DEBUG    HTTP request [ 2.72ms | 21.45% / 100.00% ] method: "POST" | uri: "/api/graphql"
2024-01-31T04:09:17.681226842+00:00  DEBUG    ┝━ check_if_token_is_valid [ 30.6µs | 1.12% ]
2024-01-31T04:09:17.681257162+00:00  DEBUG    │  ┕━ 🐛 [debug]:  | return: ValidationResults { user: UserId(CaseInsensitiveString("admin")), permission: Admin }
2024-01-31T04:09:17.681538323+00:00  DEBUG    ┝━ [GraphQL query] groups [ 2.11ms | 15.75% / 77.42% ]
2024-01-31T04:09:17.681801964+00:00  DEBUG    │  ┕━ list_groups [ 1.68ms | 61.67% ] filters: None
2024-01-31T04:09:17.683937931+00:00  DEBUG    │     ┕━ 🐛 [debug]:  | return: [Group { id: GroupId(1), display_name: GroupName("lldap_admin"), creation_date: 2024-01-30T16:23:14.356956508, uuid: Uuid("b5289316-a12b-3483-ad5a-4209398392ed"), users: [UserId(CaseInsensitiveString("admin"))], attributes: [] }, Group { id: GroupId(2), display_name: GroupName("lldap_password_manager"), creation_date: 2024-01-30T16:23:14.392497916, uuid: Uuid("ebeb5941-e25e-37ce-836b-f1d832de57d5"), users: [], attributes: [] }, Group { id: GroupId(3), display_name: GroupName("lldap_strict_readonly"), creation_date: 2024-01-30T16:23:14.417820047, uuid: Uuid("ba3ee65f-2a25-3ecf-8436-4cca3d3292d0"), users: [UserId(CaseInsensitiveString("tibeer"))], attributes: [] }]
2024-01-31T04:09:17.684190132+00:00  DEBUG    ┕━ 🐛 [debug]:  | status_code: 200
2024-01-31T04:09:26.690167738+00:00  DEBUG    HTTP request [ 57.6µs | 100.00% ] method: "GET" | uri: "/"
2024-01-31T04:09:26.690228658+00:00  DEBUG    ┕━ 🐛 [debug]:  | status_code: 200
2024-01-31T04:09:26.690523379+00:00  DEBUG    HTTP request [ 21.6µs | 100.00% ] method: "GET" | uri: "/"
2024-01-31T04:09:26.690544779+00:00  DEBUG    ┕━ 🐛 [debug]:  | status_code: 200
2024-01-31T04:09:36.690289115+00:00  DEBUG    HTTP request [ 52.4µs | 100.00% ] method: "GET" | uri: "/"
2024-01-31T04:09:36.690343755+00:00  DEBUG    ┕━ 🐛 [debug]:  | status_code: 200
2024-01-31T04:09:36.690471515+00:00  DEBUG    HTTP request [ 20.3µs | 100.00% ] method: "GET" | uri: "/"
2024-01-31T04:09:36.690491555+00:00  DEBUG    ┕━ 🐛 [debug]:  | status_code: 200
2024-01-31T04:09:46.690163529+00:00  DEBUG    HTTP request [ 57.9µs | 100.00% ] method: "GET" | uri: "/"
2024-01-31T04:09:46.690374010+00:00  DEBUG    ┕━ 🐛 [debug]:  | status_code: 200
2024-01-31T04:09:46.690802531+00:00  DEBUG    HTTP request [ 20.9µs | 100.00% ] method: "GET" | uri: "/"
2024-01-31T04:09:46.690823852+00:00  DEBUG    ┕━ 🐛 [debug]:  | status_code: 200

```

**Additional context**
Nothing to add :)



Discussion / hints:
It should be solved by #832 (when that's ready)
Avatar is not saved also.
It should be saved (you don't see the old one, do you?) but it's not fetched properly by the frontend.
They are saved as attributes as `first_name` and `last_name`:
```
        {
            "id": "john.doe",
            "email": "john.doe@example.com",
            "displayName": "John Doe",
            "firstName": "",
            "lastName": "",
            "avatar": null,
            "creationDate": "2024-06-24T13:41:21.947054920+00:00",
            "uuid": "571a5944-56e9-3234-a51c-b8ade55b433e",
            "attributes": [
                {
                    "name": "first_name",
                    "value": [
                        "John"
                    ]
                },
                {
                    "name": "last_name",
                    "value": [
                        "Doe"
                    ]
                }
            ],
            "groups": [
                {
                    "id": 3,
                    "displayName": "lldap_strict_readonly",
                    "creationDate": "2024-06-24T13:39:02.227155013+00:00",
                    "uuid": "9450a72a-dba6-38d8-890c-7939db5fcc01"
                }
            ]
        }
```
attributes still empty via webui with 2024-07-20 , which version will fix it?
The next stable one :)

It's not fixed yet

On Mon, 22 Jul 2024, 17:34 star liu, ***@***.***> wrote:

> attributes still empty via webui with 2024-07-20 , which version will fix
> it?
>
> —
> Reply to this email directly, view it on GitHub
> <https://github.com/lldap/lldap/issues/822#issuecomment-2243250957>, or
> unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AAGCPWJI3Q2SGIF3GGMOVOLZNUQ6PAVCNFSM6AAAAABCSLVTGGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENBTGI2TAOJVG4>
> .
> You are receiving this because you commented.Message ID:
> ***@***.***>
>


Fix patch:
diff --git a/server/src/infra/graphql/query.rs b/server/src/infra/graphql/query.rs
index 4e34fced..5332d703 100644
--- a/server/src/infra/graphql/query.rs
+++ b/server/src/infra/graphql/query.rs
@@ -296,29 +296,26 @@ impl<Handler: BackendHandler> User<Handler> {
     }
 
     fn first_name(&self) -> &str {
-        self.user
-            .attributes
+        self.attributes
             .iter()
-            .find(|a| a.name.as_str() == "first_name")
-            .map(|a| a.value.unwrap())
+            .find(|a| a.attribute.name.as_str() == "first_name")
+            .map(|a| a.attribute.value.unwrap())
             .unwrap_or("")
     }
 
     fn last_name(&self) -> &str {
-        self.user
-            .attributes
+        self.attributes
             .iter()
-            .find(|a| a.name.as_str() == "last_name")
-            .map(|a| a.value.unwrap())
+            .find(|a| a.attribute.name.as_str() == "last_name")
+            .map(|a| a.attribute.value.unwrap())
             .unwrap_or("")
     }
 
     fn avatar(&self) -> Option<String> {
-        self.user
-            .attributes
+        self.attributes
             .iter()
-            .find(|a| a.name.as_str() == "avatar")
-            .map(|a| String::from(&a.value.unwrap::<JpegPhoto>()))
+            .find(|a| a.attribute.name.as_str() == "avatar")
+            .map(|a| String::from(&a.attribute.value.unwrap::<JpegPhoto>()))
     }
 
     fn creation_date(&self) -> chrono::DateTime<chrono::Utc> {
@@ -716,6 +713,8 @@ mod tests {
             id
             email
             creationDate
+            firstName
+            lastName
             uuid
             attributes {
               name
@@ -831,6 +830,8 @@ mod tests {
                         "email": "bob@bobbers.on",
                         "creationDate": "1970-01-01T00:00:00.042+00:00",
                         "uuid": "b1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
+                        "firstName": "Bob",
+                        "lastName": "Bobberson",
                         "attributes": [{
                             "name": "first_name",
                             "value": ["Bob"],


Test patch: