Show last authors
1 {{toc/}}
2
3 Package: ##org.xwiki.user##
4 Modules:
5 * ##xwiki-platform-user-api##
6 * ##xwiki-platform-user-script##
7 * ##xwiki-platform-user-resource##
8
9 = Use Cases =
10
11 Here are use cases that drove the design of the User API:
12
13 * Requirement 1: Make the API as simple and short to use as possible (e.g. ##$services.user.resolveUser('...').configuration.editor## is more complex than ##$services.user.properties.editor##)
14 * Requirement 2: Make the API as performant as possible in 2 areas:
15 ** Execution time: make it be as fast as possible to execute for the main needs (i.e. getting user properties)
16 ** Memory: Make it use the less memory possible
17 * Requirement 3: Ability to retrieve user properties
18 * Requirement 4: Ability to create, delete, update users and their properties and check for user existence
19 * Requirement 5: Ability to generate URLs that points to User profile pages
20 * Requirement 6: Ability to resolve not only direct user properties but also with fallbacks at different levels (current space, current wiki, xwiki.properties, etc)
21 * Requirement 7: The API has to be independent of the User store implementation (ie users stored in wiki pages or elsewhere)
22 * Requirement 8: The API has to be both read (get properties) and write (create users, update properties)
23
24 = Iteration N =
25
26 See:
27 * https://forum.xwiki.org/t/replace-concept-of-user-in-new-user-api-and-more/6470
28 * https://forum.xwiki.org/t/user-api-and-urls/6467
29
30 = Iteration 2 =
31
32 See https://github.com/xwiki/xwiki-platform/commit/d361507b181272ed37c57e7aaf2c64338e2c8b01
33
34 = Iteration 1 =
35
36 {{code language="java"}}
37 /**
38 * Represents an XWiki user. Note that it's independent from where users are stored, and should remain that way, so
39 * that we can switch the user store in the future.
40 *
41 * @version $Id$
42 * @since 12.2RC1
43 */
44 @Unstable
45 public interface User
46 {
47 /**
48 * @return true if the user is configured to display hidden documents in the wiki
49 */
50 boolean displayHiddenDocuments();
51
52 /**
53 * @return true if the user is active in the wiki. An active user can log in.
54 */
55 boolean isActive();
56
57 /**
58 * @return the first name of the user or null if not set
59 */
60 String getFirstName();
61
62 /**
63 * @return the last name of the user or null if not set
64 */
65 String getLastName();
66
67 /**
68 * @return the email address of the user and null if not set
69 */
70 String getEmail();
71
72 /**
73 * @return the type of the user (simple user, advanced user)
74 * @see <a href="https://bit.ly/37TUlCp">user profile</a>
75 */
76 UserType getType();
77
78 /**
79 * @return true if the user's email has been checked. In some configurations, users must have had their emails
80 * verified before they can access the wiki. Also, disabled users must have their emails checked to be
81 * able to view pages.
82 */
83 boolean isEmailChecked();
84
85 /**
86 * @return true if this user is the guest user (i.e. not a real user)
87 */
88 boolean isGuest();
89
90 /**
91 * @return true if this user is registered in the main wiki (i.e. it's a global user)
92 */
93 boolean isGlobal();
94
95 /**
96 * @return true if this user is the {@code superadmin} user
97 */
98 boolean isSuperAdmin();
99
100 /**
101 * @param propertyName the name of the user property to look for
102 * @return the value of the passed user property
103 */
104 Object getProperty(String propertyName);
105
106 /**
107 * @return the reference to his user (i.e. a way to retrieve this user's data)
108 */
109 UserReference getUserReference();
110 }
111 {{/code}}
112
113 {{code language="java"}}
114 /**
115 * CRUD operations on users.
116 *
117 * @version $Id$
118 * @since 12.2RC1
119 */
120 @Unstable
121 @Role
122 public interface UserManager
123 {
124 /**
125 * @param userReference the user to retrieve and if null then retrieve the current user
126 * @return the user object representing the user pointed to by the passed reference
127 */
128 User getUser(UserReference userReference);
129 }
130 {{/code}}
131
132 {{code language="java"}}
133 /**
134 * The type of the user (simple user, advanced user).
135 *
136 * @see <a href="https://bit.ly/37TUlCp">user profile</a>
137 * @version $Id$
138 * @since 12.2RC1
139 */
140 @Unstable
141 public enum UserType
142 {
143 /**
144 * Simple user (hides complex actions in the UI for simplicity).
145 */
146 SIMPLE,
147
148 /**
149 * Advanced user (sees all possible actions in the UI).
150 */
151 ADVANCED;
152
153 /**
154 * @param typeAsString the user type represented as a string ("simple", "advanced")
155 * @return the {@link UserType} object matching the passed string representation. All values different than
156 * {@code advanced} are considered to represent a simple user
157 */
158 public static UserType fromString(String typeAsString)
159 {
160 UserType result;
161 if (typeAsString != null && "advanced".equals(typeAsString)) {
162 result = ADVANCED;
163 } else {
164 result = SIMPLE;
165 }
166 return result;
167 }
168 }
169 {{/code}}
170
171 {{code language="java"}}
172 /**
173 * Abstracts the concept of User reference. This allows to support several store implementations for users.
174 * For example for an implementation storing the users in wiki pages, the internal reference would be a
175 * {@link org.xwiki.model.reference.DocumentReference}. The reference allows retrieving all the data about a user.
176 * Another internal reference implementation could be an ActivityPub URL for example.
177 *
178 * @version $Id$
179 * @since 12.2RC1
180 */
181 @Unstable
182 public interface UserReference
183 {
184 /**
185 * @param <T> the internal type of the reference
186 * @return the internal reference (e.g. a {@link org.xwiki.model.reference.DocumentReference} for an implementation
187 * storing users in wiki pages)
188 */
189 <T> T getReference();
190 }
191 {{/code}}
192
193 == Notes ==
194
195 * I've removed the UserManager#getCurrentUser() because it's not the purpose of UserManager to do that. Normally the current User should be put in the Execution Context and retrieved directly from there. However I don't know how to implement this for the moment. Currently the old XWikiUser object is put in the XWikiContext and it's complex to replace it with the User object (This requires changing the Authentication code (which currently returns a XWikiUser object). The other problem is that XWikiContext is in oldcore and thus we cannot have it depend on the user-default module (since that modules depends on oldcore itself). So we need to refactor how the user is set in the context and find a way to inject that information from either some authentication module (ie move authentication code currently located in oldcore - XWikiAuthServiceImpl - to some other module outside of oldcore) or from the user-default module. Thus FTM, I've chosen to offer a convenience way to get the current User object, by passing ##null## to UserManager#getUser(). This should be modified in the future when we can directly get the current User object from the context.
196
197 = TODO =
198
199 * Store the current User object in the Execution Context (or in the XWikiContext as a start)
200 * Add createUser() and deleteUser() to UserManager
201 * Add setters to User and add a saveUser() (or updateUser() to UserManager)

Get Connected