User API

Version 26.1 by Admin on 2021/03/17 17:35

cogAPIs to manipulate users and groups
TypeJAR
CategoryAPI
Developed by

XWiki Development Team

Rating
0 Votes
LicenseGNU Lesser General Public License 2.1
Bundled With

XWiki Standard

Compatibility

Since 10.8RC1

Installable with the Extension Manager

Description

Users

Since 12.2 Concepts:

  • This API is independent from where the users are stored (in wiki pages, etc). This allows plugging other implementations to store the users elsewhere than in wiki pages (the default).
  • This API supports properties for the Guest and SuperAdmin users (i.e. even though these users do not have wiki pages for them, they still have properties, which are pre-defined, but can be configured, see below).
  • A user is pointed to with a UserReference. There are 3 special user references:
    • SuperAdminUserReference#INSTANCE: points to the SuperAdmin user
    • GuestUserReference#INSTANCE: points to the Guest user (i.e. not logged-in user)
    • CurrentUserReference#INSTANCE: special reference pointing to the current user
  • The UserProperties class represents the properties of a user (Editor to use, Advanced or Simple user, First name, etc), offering both a typed and untyped APIs.
    • Example of typed API: UserProperties#showHiddenDocuments()
    • Example of untyped API: UserProperties#getProperty('showHiddenDocuments')
  • Since 12.4RC1It's also possible to modify user properties by using setters in UserProperties and then calling save(). For example from Velocity (note that this will work even though setEmail accepts an InternetAddress because we have an InternetAddress Converter):
    #set ($props = $services.user.getProperties('user'))
    Current email: $props.email
    #set ($discard = $props.setEmail('john@doe.com'))
    #set ($discard = $props.save())
  • To get a UserProperties object, you use a UserPropertiesResolver. For example from a Java component:
    @Inject
    private UserPropertiesResolver userPropertiesResolver;
    ...
    UserProperties currentUserProperties = userPropertiesResolver.resolve(CurrentUserReference.INSTANCE);
    • There are different UserPropertiesResolver, depending on whether you need to get properties explicitly defined for the user or whether you also want to check fallback properties (for example user properties defined for the current space - <space>.WebPreferences -, for the current wiki - XWiki.XWikiPreferences -, and ultimately in the xwiki.properties configuration file). Examples:
      // Resolver to get explicitly-defined properties without fallbacks:
      @Inject
      private UserPropertiesResolver userPropertiesResolver;

      // Resolver to get properties with full fallbacks:
      @Inject
      @Named("all")
      private UserPropertiesResolver userPropertiesResolver;
  • To test if a UserReference is pointing to the SuperAdmin user, you'll write:
    ...
    UserReference userReference = ...
    if (SuperAdminUserReference.INSTANCE == userReference()) {
       ...
    }
  • To test if a UserReference is pointing to the Guest user, you'll write:
    ...
    UserReference userReference = ...
    if (GuestUserReference.INSTANCE == userReference()) {
       ...
    }
  • To test if the current user is pointing to the Guest user, you'll first need to resolve the user, as in:
    @Inject
    private UserReferenceResolver<CurrentUserReference> resolver;
    ...
    UserReference userReference = this.resolver.resolve(CurrentUserReference.INSTANCE);
    if (GuestUserReference.INSTANCE == userReference()) {
       ...
    }

    This is currently needed because XWikiContext#getUserReference() doesn't return a UserReference (it returns a DocumentReference). When this is fixed in the future, it'll be as simple as writing:

    UserReference userReference = xwikiContext.apiToGetTheUserReference()
    if (GuestUserReference.INSTANCE == userReference()) {
       ...
    }
  • UserManager: Component to perform CUD operations (the R from CRUD is done with the UserPropertiesResolver). Right now, only offers an exist() method, as in:
    @Inject
    private UserManager userManager;
    ...
    userManager.exists(CurrentUserReference.INSTANCE);

Full API in the javadoc.

Configuration

The UserConfiguration component provides a way to access the User module's configuration from Java.

It's possible to configure the default preferences for the Super Admin and Guest users. This is done through the xwiki.properties configuration file:

#-# [Since 12.2]
#-# Define preferences for the SuperAdmin user.
#-#
#-# The format is:
#-# user.preferences.superadmin.<preference name> = <value>
#-#
#-# Examples:
#-# user.preferences.superadmin.displayHiddenDocuments = 0
#-# user.preferences.superadmin.editor = Wysiwyg

#-# [Since 12.2]
#-# Define preferences for the Guest user.
#-#
#-# The format is:
#-# user.preferences.guest.<preference name> = <value>
#-#
#-# Examples:
#-# user.preferences.guest.displayHiddenDocuments = 1
#-# user.preferences.guest.editor = Text

History

There are various APIs in XWiki for retrieving user properties. A lot of them are historical and old and shouldn't be used. Here are all possibilities:

  1. Direct XWiki.XWikiUsers XObject access: This is totally not recommended and you shouldn't do that. Use this API instead.
  2. XWiki#getUserPreference(): Gets a user property and if it doesn't exist fallback to looking in the current space's WebPreferences and if it doesn't exist, fallback to looking in the current wiki's XWikiPreferences. It has been retrofitted to call this User API and is thus safe to use. However don't use it, and, instead, use this API which also implements fallbacks.
  3. com.xpn.xwiki.user.api.XWikiUser & XWikiContext#getXWikiUser(): Old API, based on users stored in wiki pages and part of oldcore. Shouldn't be used.
  4. user ConfigurationSource: Low-level and untyped API for getting user properties. It's recommended to not use it because 1) it's not typed and 2) it only supports users stored in wiki documents (except for SuperAdmin and Guest users).
  5. UserProperties: This new API described on this page: This is the recommended API to use!

Bridge

The following explanations can help you bride from old APIs to the new API.

  • If you need to retrieve properties for an old XWikiUser, you can do it like this:
    @Inject
    private UserReferenceResolver<XWikiUser> xwikiUserUserReferenceResolver

    @Inject
    private UserPropertiesResolver userPropertiesResolver;
    ...
    XWikiUser oldXWikiUser = ...
    UserProperties properties = userPropertiesResolver.resolve(xwikiUserUserReferenceResolver.resolve(oldXWikiUser));
  • If you need to get a UserReference from a DocumentReference you'll need a UserReferenceResolver. For example:
    @Inject
    @Named("document")
    private UserReferenceResolver<DocumentReference> userReferenceResolver;
    ...
    DocumentReference documentReference = ...
    UserReference reference = userReferenceResolver.resolve(documentReference);
  • If you need to get a UserReference from a user represented as String, you can write:

    Example 1:

    @Inject
    private UserReferenceResolver<String> userReferenceResolver;
    ...
    UserReference reference = userReferenceResolver.resolve("XWiki.superadmin");

    Example 2: user reference without the space

    @Inject
    private UserReferenceResolver<String> userReferenceResolver;
    ...
    UserReference reference = userReferenceResolver.resolve("superadmin");

    Example 3: User in a specific wiki

    @Inject
    private UserReferenceResolver<String> userReferenceResolver;
    ...
    UserReference reference = userReferenceResolver.resolve("SomeUser", new WikiReference("somewiki"));
    // OR
    UserReference reference = userReferenceResolver.resolve("somewiki:XWiki.SomeUser");

Groups

The org.xwiki.user.group.GroupManager component allows getting information about the groups and their members.

Everything you request trough this component is cached for fast access.

Member's groups

/**
     * Search groups the passed user or group is member of.
     * <p>
     * {code wikis} controls where to search for the groups and {@code recurse} only the direct group should be
     * returned or the whole hierarchy.
     *
     * @param member the group member (user or group)
     * @param wikiTarget the wikis where to search. The following types are supported:
     *            <ul>
     *            <li>{@link org.xwiki.user.group.WikiTarget}</li>
     *            <li>{@link String}</li>
     *            <li>{@code Collection<String>}</li>
     *            <li>{@code org.xwiki.model.reference.WikiReference}</li>
     *            <li>{@code Collection<org.xwiki.model.reference.WikiReference>}</li>
     *            </ul>
     * @param recurse false if only the direct groups should be returned, true to take into account groups of groups
     * @return the groups the passed user or group is member of
     * @throws GroupException when failing to get groups
     */

    Collection<DocumentReference> getGroups(DocumentReference member, Object wikiTarget, boolean recurse)
       throws GroupException;

Group's members

    /**
     * Retrieve the users and groups which are the members of the passed group.
     *
     * @param group the group for which to return the members
     * @param recurse false if only the direct members should be returned, true to take into account groups of groups
     * @return the members of the passed group
     * @throws GroupException when failing to get members
     */

    Collection<DocumentReference> getMembers(DocumentReference group, boolean recurse) throws GroupException;

Prerequisites & Installation Instructions

We recommend using the Extension Manager to install this extension (Make sure that the text "Installable with the Extension Manager" is displayed at the top right location on this page to know if this extension can be installed with the Extension Manager).

You can also use the manual method which involves dropping the JAR file and all its dependencies into the WEB-INF/lib folder and restarting XWiki.

Dependencies

Dependencies for this extension (org.xwiki.platform:xwiki-platform-user-api 13.1):

Get Connected