Jira Server 8.2 GDPR UserKey changes - What about UserRenamedEvent? Does the userKey change over time?

Hi,

I just read the blogpost Important: GDPR changes in Jira Server - Atlassian Developer Blog
and I like the approach of only storing userKeys instead of userNames.

I have some questions :slight_smile:

Let’s assume we have Jira 8.3 and later and this feature is fully active.
What happens for:

(a a new user with username “jim” with key “JIRAUSER1111” when he is renamed to “jimmy”
=> Does the userkey change too? (I do not hope so…)
=> Is the com.atlassian.crowd.event.user.UserRenamedEvent triggered as usual?

(b an old user with username “bob” with key “bob” when he is renamed to “bobby”
=> Does the userkey change too? (I do not hope so… but here it would make sense to get a new userkey like JIRAUSER11112)
=> Is the com.atlassian.crowd.event.user.UserRenamedEvent triggered as usual?

(c UPDATE: I noticed the UserDeletedEvent only gives you the username. The com.atlassian.jira.user.UserKeyService has methods to get userKey :slight_smile:

Are there any new events to listen to?

@drauf Since you wrote this great blogpost, maybe you could please tell me what exactly happens, thx :slight_smile:

thanks,
Bernhard

1 Like

I’m pretty sure nothing will change from the current functionality. The user key is automatically generated when a user is created. The userkey of a user won’t change when you change a username or any other information related to the user. There is no way to change the userkey after a user is created. The only thing Atlassian will be changing is how the key is generated.

It is also stated that this will only be done for new users in the blogpost. Many configurations and other settings are tied to the userkey so they can’t just change it without the possibility of breaking a lot of 3rd party apps and possible other things.

1 Like

Hello Bernhard!

Sorry for the very late reply - I’ve only now noticed the notification.

In general, the answers provided by Jeffrey above are correct, that the user key does not change with renames and that this change only affects newly created users.

However, as stated in the first part of the blogpost, we are also developing the GDPR’s “right to be forgotten”, that can actually modify user keys to anonymized values. To handle that change (which will only happen if an administrator decides to anonymize a user), you will need to implement and register a UserKeyChangeHandler.

For more details, you can refer to GDPR changes in Jira | Atlassian Support | Atlassian Documentation.

Hope this helps!

Hi,

Thanks for the answer :slight_smile: And this really helps a lot. I will put this on my apps roadmap :slight_smile:
thx,
Bernhard

Hi all,

Can we test “Anonymizing users” feature on Jira 8.3 EAP ?
https://confluence.atlassian.com/adminjira/gdpr-changes-in-jira-968684265.html#GDPRchangesinJira-anonymizing

Best,
Takayuki

Hey @hirota.takayuki,

I described how you can set-up integration tests for the anonymization process here: Server GDPR timeline and questions - #4 by drauf

There is currently no possibility to trigger the process from the UI, and as of Jira 8.3 we only call the service from test code.

Cheers!

Hi @drauf,

Thanks for the clarification!
I will check your test code.

If I activate the dark feature, new users are still created with userKeys that are lowercase usernames. I did:

  1. Go to <Jira_URL>/secure/SiteDarkFeatures!default .jspa
  2. Enable the com.atlassian.jira.user.dbIdBasedKeyGenerationStrategy flag.

tested with Jira 8.3.0-m0003 and MySQL and PostgreSQL.
Did I miss something? Do I need to do anything else to activate it?

thx

@clouless this feature flag was added in Jira 8.2 - Preparing for Jira 8.2 | Atlassian Support | Atlassian Documentation. :slight_smile:

sorry typo :frowning: I mean 8.3.0-m0003 :slight_smile:

Ah, I see the mistake - dark feature flags in Jira follow a scheme where you enable them by adding an entry like <name>.enabled and disable them by adding an entry like <name>.disabled. It’s made this way to allow disabling features that are on by default without flooding the UI with a lot of irrelevant entries.

I’ve updated GDPR changes in Jira | Atlassian Support | Atlassian Documentation to be more specific:

  1. Go to <Jira_URL>/secure/SiteDarkFeatures!default .jspa
  2. Add the com.atlassian.jira.user.dbIdBasedKeyGenerationStrategy.enabled flag.
1 Like

ok thanks a lot, I really thought I was going nuts ^^

And I have implemented my UserKeyChangeHandler now, and all tests run fine so far. I just wanted to ask as few questions

A: Should the getNumberOfTasks return a number conditionally?
Meaning: Should I check if I need to run the task in the getNumberOfTasks so that it will reduce load on Jira? I mean something like so:

public int getNumberOfTasks(@Nonnull UserPropertyChangeParameter userPropertyChangeParameter) {
  if (myService.doesSomethingForUserExist(userPropertyChangeParameter.getOriginal()) {
    return 1;		    
  } else {
    return 0;
  }
}

That way (at least I think it works that way) we could reduce the number of tasks started, when running the anonymize stuff. Or should I return 1 hardcoded?

B: What is this AffectedEntity exactly? Is it ok to just return something like below to show “The user permissions of my plugin will be updated”? Is the descriptionKey an i18n entry? Should I provide translations?

getAffectedEntities(@Nonnull UserPropertyChangeParameter userPropertyChangeParameter) {
     return ImmutableList.of(
       AffectedEntity
         .newBuilder(AffectedEntityType.ANONYMIZE)		                  
         .descriptionKey("myplugin.user.key.permission.anonymize")
     );
}

C: I have seen that If I call the anonymizeUser backdoor the user will be anonymized and set to inactive. Meaning he is basically “deleted”.
Will there be a case where the userKey changes and the user will still be active?

thanks a lot :slight_smile:

(I just had my morning coffee and I think I started going into too many details due to this, sorry for that ;))

A:
The getNumberOfTasks method is used only to assess how much of the progress bar to allocate for the given handler - even if it returns 0, Jira will still call the update method.

As such, I would say that if myService.doesSomethingForUserExist returns very fast (e.g. it reads everything from caches) it makes sense to use it, but if it has to go to the database, it’s probably easier (and more performant) to just hardcode 1.

As for us, in some cases we opted for returning the exact number of entries we will update (mostly for handlers that will update thousands of entities or ones that need to reindex some values) and in others, we simply return a hardcoded number (when the handler is doing trivial tasks that will finish in milliseconds and there’s no point in allocating it a visible part of the progress bar).

B:
When an admin selects the option to anonymize a user, we will show them a new UI page containing a summary of what will happen before they start the actual operation.

This page will contain a few sections (this will be removed, this will be updated, this you might have to check manually, etc.) that will basically be lists/tables containing the data collected from collecting those AffectedEntity objects.

As such, those items are groups of objects that the handler will update, e.g. there might be an AffectedEntity called “Issue comments” with some bigger number of occurrences (instead of actually returning thousands of separate objects, one per every comment).

The example you provided is perfectly fine, as it will be informative for the administrator.
The descriptionKey is an i18n entry, and you might provide translations if you want to, although we are not forcing this now.

C:
We do not currently plan to provide such feature - user key is an internal representation that shouldn’t leak to the UI (although it does sometimes :frowning:), an should be as immutable as it can be.

Unfortunately, we have to touch it during the anonymization, as prior to Jira 8.4 it is generated based on the username, and as such often contains personal data.

thanks for all the details - I always want all the details - especially when I am on my second coffee of the day :smiley:
I am really excited for the next EAP release to see this magical new UI page :slight_smile:

@drauf I have had this working for Jira 8.2 and Jira 8.3 now in my app.
I had setup an automated test using a my own variant of the “UserAnonymizeBackdoor.java” provided in the Jira Source Code.

This test now fails with Jira 8.4.0-m0003.
Two things happened:

(1) The API Changed of AnonymizeUserService.perform() => ok I handled that
(2) My UserKeyChangeHandler is not triggered anymore (I have not changed any code)

Is there any new API I need to abide? Or Should the UserKeyChangeHandler be implemented differently starting Jira 8.4?

I hope you can help me out again :slight_smile:

@clouless starting from Jira 8.4, the new user key generation strategy is enabled by default, so that when you create new users, their keys will look like JIRAUSER<numbers>.
The anonymization process detects this format and skips the user key change step entirely (the key doesn’t contain any personal data, so there’s no point in running an expensive operation).

You have two options to make for testing it easily:

  • First, before creating user in your test, you can the disable feature flag to generate user keys like before:
    backdoor.darkFeatures().disableForSite(FeatureFlag.featureFlag(DB_ID_BASED_KEY_GENERATION_STRATEGY.featureKey()));
  • Second, you can restore the default dataset (@RestoreBlankInstance) or your own dataset from older Jira version, and use one of the users there (in the default dataset that would be the user with name fred).

@drauf ok sure makes sense. When userKey is already anonymized, then it will not trigger facepalm. It was a long week or too less coffee today ^^

Thanks for the hints :smiley: I will try them.

I knew the answer because our CI blew up and I had to debug this recently, so you are not alone… :wink:

1 Like