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.
The complete rename user functionality will be delivered in 5.3. However the schema and API changes necessary will be released in 5.2 and recommend developers begin updating their add-ons now.
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.
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.
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 UserAccessor#getUserByKey(key)
or UserAccessor#getUser(username)
.
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 getUser(User)
method.
See the FindUserHelper
Javadoc for more information.
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 and Active Objects upgrade tasks to migrate existing data containing usernames to contain user keys:
If you want to create plugins that are compatible with both Confluence 4.3 and Confluence 5.2 onwards, you have a few options:
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.
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 pom.xml:
1 2<dependency> <groupId>com.atlassian.usercompatibility</groupId> <artifactId>usercompatibility-confluence</artifactId> <version>2.1.4</version> </dependency>
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 UserCompatibilityHelper.isRenameUserImplemented()
returns 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 0
if UserCompatibilityHelper.isRenameUserImplemented()
returns true
.
Making PluginUpgradeTask Conditional
1 2public int getBuildNumber() { return UserCompatibilityHelper.isRenameUserImplemented() ? 8 : 0; }
You can make the Active Objects upgrade task conditional, by making getModelVersion()
return 0
if UserCompatibilityHelper.isRenameUserImplemented()
returns true
.
Making ActiveObjectsUpgradeTask Conditional
1 2public ModelVersion getModelVersion() { return ModelVersion.valueOf(UserCompatibilityHelper.isRenameUserImplemented() ? "8" : "0"); }
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.
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.
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.
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.
Rate this page: