11"""Nextcloud API for working with users."""
22
3+ import dataclasses
4+ import datetime
35import typing
46
57from ._misc import kwargs_to_params
68from ._session import NcSessionBasic
79
810
11+ @dataclasses .dataclass
12+ class UserInfo :
13+ """User information description."""
14+
15+ def __init__ (self , raw_data : dict ):
16+ self ._raw_data = raw_data
17+
18+ @property
19+ def enabled (self ) -> bool :
20+ """Flag indicating whether the user is enabled."""
21+ return self ._raw_data .get ("enabled" , True )
22+
23+ @property
24+ def storage_location (self ) -> str :
25+ """User's home folder. Can be empty for LDAP or when the caller does not have administrative rights."""
26+ return self ._raw_data .get ("storageLocation" , "" )
27+
28+ @property
29+ def user_id (self ) -> str :
30+ """User ID."""
31+ return self ._raw_data ["id" ]
32+
33+ @property
34+ def last_login (self ) -> datetime .datetime :
35+ """Last user login time."""
36+ return datetime .datetime .utcfromtimestamp (int (self ._raw_data ["lastLogin" ] / 1000 )).replace (
37+ tzinfo = datetime .timezone .utc
38+ )
39+
40+ @property
41+ def backend (self ) -> str :
42+ """The type of backend in which user information is stored."""
43+ return self ._raw_data ["backend" ]
44+
45+ @property
46+ def subadmin (self ) -> list [str ]:
47+ """IDs of groups of which the user is a subadmin."""
48+ return self ._raw_data .get ("subadmin" , [])
49+
50+ @property
51+ def quota (self ) -> dict :
52+ """Quota for the user, if set."""
53+ return self ._raw_data ["quota" ] if isinstance (self ._raw_data ["quota" ], dict ) else {}
54+
55+ @property
56+ def manager (self ) -> str :
57+ """The user's manager UID."""
58+ return self ._raw_data .get ("manager" , "" )
59+
60+ @property
61+ def email (self ) -> str :
62+ """Email address of the user."""
63+ return self ._raw_data ["email" ] if self ._raw_data ["email" ] is not None else ""
64+
65+ @property
66+ def additional_mail (self ) -> list [str ]:
67+ """List of additional emails."""
68+ return self ._raw_data ["additional_mail" ]
69+
70+ @property
71+ def display_name (self ) -> str :
72+ """The display name of the new user."""
73+ return self ._raw_data ["displayname" ] if "displayname" in self ._raw_data else self ._raw_data ["display-name" ]
74+
75+ @property
76+ def phone (self ) -> str :
77+ """Phone of the user."""
78+ return self ._raw_data ["phone" ]
79+
80+ @property
81+ def address (self ) -> str :
82+ """Address of the user."""
83+ return self ._raw_data ["address" ]
84+
85+ @property
86+ def website (self ) -> str :
87+ """Link to user website."""
88+ return self ._raw_data ["website" ]
89+
90+ @property
91+ def twitter (self ) -> str :
92+ """Twitter handle."""
93+ return self ._raw_data ["twitter" ]
94+
95+ @property
96+ def fediverse (self ) -> str :
97+ """Fediverse(e.g. Mastodon) in the user profile."""
98+ return self ._raw_data ["fediverse" ]
99+
100+ @property
101+ def organisation (self ) -> str :
102+ """Organisation in the user profile."""
103+ return self ._raw_data ["organisation" ]
104+
105+ @property
106+ def role (self ) -> str :
107+ """Role in the user profile."""
108+ return self ._raw_data ["role" ]
109+
110+ @property
111+ def headline (self ) -> str :
112+ """Headline in the user profile."""
113+ return self ._raw_data ["headline" ]
114+
115+ @property
116+ def biography (self ) -> str :
117+ """Biography in the user profile."""
118+ return self ._raw_data ["biography" ]
119+
120+ @property
121+ def profile_enabled (self ) -> bool :
122+ """Flag indicating whether the user profile is enabled."""
123+ return str (self ._raw_data ["profile_enabled" ]).lower () in ("1" , "true" )
124+
125+ @property
126+ def groups (self ) -> list [str ]:
127+ """ID of the groups the user is a member of."""
128+ return self ._raw_data ["groups" ]
129+
130+ @property
131+ def language (self ) -> str :
132+ """The language to use when sending something to a user."""
133+ return self ._raw_data ["language" ]
134+
135+ @property
136+ def locale (self ) -> str :
137+ """The locale set for the user."""
138+ return self ._raw_data .get ("locale" , "" )
139+
140+ @property
141+ def notify_email (self ) -> str :
142+ """The user's preferred email address.
143+
144+ .. note:: The primary mail address may be set be the user to specify a different
145+ email address where mails by Nextcloud are sent to. It is not necessarily set.
146+ """
147+ return self ._raw_data ["notify_email" ] if self ._raw_data ["notify_email" ] is not None else ""
148+
149+ @property
150+ def backend_capabilities (self ) -> dict :
151+ """By default, only the ``setDisplayName`` and ``setPassword`` keys are available."""
152+ return self ._raw_data ["backendCapabilities" ]
153+
154+
9155class _UsersAPI :
10- """The class provides the user, user groups, user status API on the Nextcloud server.
156+ """The class provides the user API on the Nextcloud server.
11157
12- .. note:: In NextcloudApp mode, only ``get_list`` and ``get_details `` methods are available.
158+ .. note:: In NextcloudApp mode, only ``get_list``, ``editable_fields`` and ``get_user `` methods are available.
13159 """
14160
15161 _ep_base : str = "/ocs/v1.php/cloud/users"
@@ -30,28 +176,25 @@ def get_list(
30176 response_data = self ._session .ocs (method = "GET" , path = self ._ep_base , params = data )
31177 return response_data ["users" ] if response_data else {}
32178
33- def get_details (self , user_id : str = "" ) -> dict :
179+ def get_user (self , user_id : str = "" ) -> UserInfo :
34180 """Returns detailed user information.
35181
36182 :param user_id: the identifier of the user about which information is to be returned.
37183 """
38- if not user_id :
39- user_id = self ._session .user
40- if not user_id :
41- raise ValueError ("user_id can not be empty." )
42- return self ._session .ocs (method = "GET" , path = f"{ self ._ep_base } /{ user_id } " )
184+ url_path = f"{ self ._ep_base } /{ user_id } " if user_id else "/ocs/v1.php/cloud/user"
185+ return UserInfo (self ._session .ocs (method = "GET" , path = url_path ))
43186
44- def create (self , user_id : str , ** kwargs ) -> None :
187+ def create (self , user_id : str , display_name : typing . Optional [ str ] = None , ** kwargs ) -> None :
45188 """Create a new user on the Nextcloud server.
46189
47190 :param user_id: id of the user to create.
191+ :param display_name: display name for a created user.
48192 :param kwargs: See below.
49193
50194 Additionally supported arguments:
51195
52196 * ``password`` - password that should be set for user.
53197 * ``email`` - email of the new user. If ``password`` is not provided, then this field should be filled.
54- * ``displayname`` - display name of the new user.
55198 * ``groups`` - list of groups IDs to which user belongs.
56199 * ``subadmin`` - boolean indicating is user should be the subadmin.
57200 * ``quota`` - quota for the user, if needed.
@@ -62,9 +205,11 @@ def create(self, user_id: str, **kwargs) -> None:
62205 if not password and not email :
63206 raise ValueError ("Either password or email must be set" )
64207 data = {"userid" : user_id }
65- for k in ("password" , "displayname" , " email" , "groups" , "subadmin" , "quota" , "language" ):
208+ for k in ("password" , "email" , "groups" , "subadmin" , "quota" , "language" ):
66209 if k in kwargs :
67210 data [k ] = kwargs [k ]
211+ if display_name is not None :
212+ data ["displayname" ] = display_name
68213 self ._session .ocs (method = "POST" , path = self ._ep_base , json = data )
69214
70215 def delete (self , user_id : str ) -> None :
0 commit comments