Feature #12626

Updated by Tom Clegg over 3 years ago

New API endpoint: @POST /arvados/v1/users/merge@
* Authorization header has valid API token for the "old" account
* new_user_token (post form param in request body) has valid API token for the "new" account
* new_owner_uuid (post form param in request body) has either new user's UUID, or a group UUID writable by the new user
* redirect_to_new_user=true (optional)

Security checks
* Current token ("old account") has scopes=["all"]
* new_user_token ("new account") has scopes=["all"]
* API logs show the UUID of the corresponding api_client_auth record instead of merge_into_token

* Move all records (groups, links, collections, jobs, pipelines, container requests, etc) owned by the old user into new_owner_uuid (this is typically a new empty project or a new user who doesn't own anything, so name conflicts would be a surprise/error)
* Update links set tail_uuid=new_user_uuid where tail_uuid=old_user_uuid

Additional actions if redirect_to_new_user=true
* Set old user's redirect_to_user_uuid field to the new user's UUID
* Move old user's SSH keys to the new user
* Ensure API tokens associated with old user are left alone. After the merge, they will give access to the new account.
* Update links with head_uuid = old user to point to new user

...if redirect_to_new_user=false
* Leave old user's redirect_to_user_uuid field alone
* Delete old user's SSH keys
* Leave old user's API tokens alone
* Leave links with head_uuid = old user alone.

This is all done in a transaction: if anything fails, the entire operation is cancelled.

* New column (users.redirect_to_user_uuid) is needed.
* #12995 and #12703 are blocked only by the redirect_to_new_user=true case.