Renamable Users in Confluence 5.2
With Confluence 5.2, we are introducing schema and API changes necessary to support the ability to change usernames. To make that possible, users will have a new, unique, permanent key as well as the already-existing, unique, changeable username.
As usernames will be able to change, your plugin will need to migrate its existing data to user keys instead of usernames.
Introducing the user key
Previously the username field was used as a display value and also stored as the primary key of the user. In order to allow usernames to be changed, we need a separate identifier that is unchangeable.
We have introduced a new field on the user, called "key". It is a case-sensitive UUID string and will never change for a given user.
When to use the key, when to use the username
The key should be considered the primary key of the user.
Whenever you want to store a reference to a user in long-term storage (for example, the Confluence database DB or the Lucene index) you should use the key, because it can never change.
However, the key should never be shown to the end user. Only the username should be displayed.
The username is a unique secondary key, but should not be stored in long-term storage because it can change over time.
The new ConfluenceUser object
We have introduced a new Interface to represent users, called
com.atlassian.confluence.user.ConfluenceUser. It extends the existing
com.atlassian.user.User interface with a new method called
getKey() that returns the key for the user.
To get hold of a
ConfluenceUser object you can call either
Converting the User object to the ConfluenceUser object
To support backwards compatibility, all of the existing API still allows the use of the legacy User interface. We're allowing for the possibility that you want to migrate your existing code over time, as and when required.
We have provided a helper Class (
com.atlassian.confluence.user.persistence.dao.compatibility.FindUserHelper) that allows you to quickly convert User objects to ConfluenceUser objects using the
FindUserHelper Javadoc for more information.
Important changes to be aware of
When storing information in the database, you must now use the key of the user, not the username.
Confluence API methods that previously accepted or returned a username or User object are in some cases now deprecated and replaced with alternatives based on ConfluenceUser.
You should check the API of such methods and consider using alternative methods that take or return the ConfluenceUser object.
Where applicable, you should write SAL andupgrade tasks to migrate existing data containing usernames to contain user keys:
- SAL: Writing a Plugin Upgrade Task to Migrate User Data to New User Keys
- Active Objects: Upgrading your plugin and handling data model updates
If you want to create plugins that are compatible with both Confluence 4.3 and Confluence 5.2 onwards, you have a few options:
- Option 1: Continue using usernames
- Option 2: Use the Confluence compatibility library and execute upgrade tasks conditionally
- Option 3: Use the SAL compatibility library
Option 1. Continue using usernames
If your plugin does not persist usernames at all, or if user-related data can safely be lost for renamed users, your plugin can continue using the Confluence 4.3 API.
Option 2. Use the compatibility library and execute upgrade tasks conditionally
We provide a compatibility library that your plugin can include, so that it can interact with Confluence 4.3 or 5.2 in a safe manner.
To add the compatibility library as a Maven dependency, add the following to your
See the comments on the helper class
UserCompatibilityHelper for details.
When using the compatibility library, the plugin should also ensure that SAL and Active Objects upgrade tasks that perform user migration are executed only when
true. This is because
UserCompatibilityHelper will process usernames in Confluence versions earlier than 5.2, and userKeys thereafter.
You can make SAL plugin upgrade tasks conditional, by making the
getBuildNumber() method return
You can make the Active Objects upgrade task conditional, by making
If you later add other upgrade tasks, you must update the conditional user key migration upgrade tasks to have the highest build number or model version, and to make them idempotent (runnable multiple times without changing the end result), because changing the build number or model version might cause the upgrade tasks to run again.
Option 3. Use the SAL compatibility library
If you are working on a cross-product plugin you will probably prefer to use the SAL User Compatibility Library. You can also use this library for a Confluence-only plugin, instead of following option 1 above.
Cross-product plugin development using Shared Access Layer (SAL)
If you develop a cross-product plugin, you are probably using the Shared Access Layer to interact with the different products in a generic way.
Note: From version 2.10, SAL will be updated to better handle the fact that a user's username can change.
UserManager and UserProfile
For access to a user's key, the UserProfile interface now includes a
getUserKey() method. As explained above, if you need to store a reference to a user, you should do so by storing the user key, not the username.
Most of the methods in UserManager that used to take a username as a parameter are now deprecated in favour of methods that take a UserKey object. Similarly, the
getRemoteUsername() methods in UserManager, which return a username as a String, are now deprecated in favour of methods that return a UserProfile or a UserKey object.
All the methods in UserSettingsService and SearchProvider have been similarly modified: methods that take a username as a parameter are now deprecated, and new methods taking a UserKey have been added.