Switching to SSO by transferring 'external_ids'
Transferring SSO external_ids
to original users
If you have previously used EMS prior to setting up SSO, you will likely want to continue using your existing Matrix accounts instead of migrating over to newly created SSO accounts. You can do this by transferring the 'external_ids' from these new accounts, to your original accounts instead. To do this, you will need to use the Admin API.
Getting an Access Token
Before being able to use the Admin API, you will need an admin account and it's 'Access Token', you can make a user an admin by either following the steps in the link above, or following these steps on the EMS Control Panel:
- Access the 'Server Admin' tab
- Under the 'Users' tab, select the user that should be made Synapse Admin
- Click the checkbox, next to 'Synapse Admin' and click 'Yes' to confirm
Once a user is a Synapse Admin, you can retrieve their 'Access Token' by logging in via the Element Matrix client:
- Click on the users' profile icon in the top-left and select 'All Settings'
- Open the 'Help & About' settings page, then scroll down to the 'Advanced' section
- Click 'Access Token' to reveal the token, copy this to interact with the Admin API
Using an Access Token
Access tokens will need to be passed into all API requests as an Authorization Bearer token, see examples below:
cURL:
-H 'Authorization: Bearer syt_b25l_example_2RCMR1'
Python:
import requests
headers = {
'Authorization': 'Bearer syt_b25l_example_2RCMR1',
}
Getting SSO users' external_ids
-
Using the link above, you can use a GET request to
/_synapse/admin/v2/users
to retrieve a list of all accounts on your home server. Follow the guidance on pagination to ensure all users are retrieved.cURL:
curl -X GET -H 'Authorization: Bearer syt_b25l_example_2RCMR1' 'https://example.ems.host:443/_synapse/admin/v2/users?from=60&limit=10&guests=false'
-
For each user you can then use their
name
in another GET request to/_synapse/admin/v2/users/<user_id>
, replacing<user_id>
withname
.cURL:
curl -X GET -H 'Authorization: Bearer syt_b25l_example_2RCMR1' https://example.ems.host:443/_synapse/admin/v2/users/@exampleuser:example.ems.host
-
You will find the
external_ids
for each user within the JSON output. You can programatically run through all users and generate a list of only those withexternal_ids
, removing unneeded information. (See example below)Python:
import requests # REPLACE THESE VALUES WITH ACCESS TOKEN AND HOME SERVER URL headers = { 'Authorization': 'Bearer syt_b25l_example_2RCMR1', } url = 'https://example.ems.host' # GET LIST OF ALL USERS ON HOME SERVER # OUTPUT: 'all_users' contains a list of all users next_token = '0' last_token = '' all_users = [] get_users = requests.get(url + '/_synapse/admin/v2/users?from=' + next_token + '&limit=10&guests=false', headers=headers).json() for user in get_users['users']: all_users.append(user['name']) while ('next_token' in get_users) and (next_token != last_token): next_token = get_users['next_token'] get_users = requests.get(url + '/_synapse/admin/v2/users?from=' + next_token + '&limit=10&guests=false', headers=headers).json() for user in get_users['users']: all_users.append(user['name']) # FOR EACH USER, GET ALL INFO, EXCLUDE THOSE WITHOUT 'external_ids' # OUTPUT: 'all_external_ids' contains a list of all users with external ids all_external_ids = [] for user in all_users: get_user = requests.get(url + '/_synapse/admin/v2/users/' + user, headers=headers).json() if get_user['external_ids'].__len__() != 0: all_external_ids.append( { 'sso_username': user, 'original_username': '', 'external_ids': get_user['external_ids'] } )
Transferring SSO external_ids
information
Admin API Create or Modify Account
With all external_ids
collected, you will need to identify each SSO Account and the associated original account that you'd like to transfer the associated SSO information over too.
If using the Python example above, you will need to store the original username within all_external_ids[X]['original_username']
, replacing X with the index of the SSO user. If you create a dictionary with keys
named of the SSO username, and values
of the desired Original username you could use the following to update all_external_ids
:
Python:
# ADD REQUIRED ORIGINAL USERNAME
for user in all_external_ids:
dict_storing_sso2orig = {'@example_sso_user:example.ems.host': '@example_orig_user:example.ems.host'}
user['original_username'] = dict_storing_sso2orig[str(user['sso_username'])]
Once you have related all SSO Usernames to Original Usernames you can then, using the link above, use a PUT request to /_synapse/admin/v2/users/<user_id>
to change the external_ids
data for each account. (Remember to remove the external_ids
information from the soon to be defunct SSO accounts)
cURL:
curl -X PUT -H 'Authorization: Bearer syt_example_2RCMR1' -d '{"external_ids":[]}' https://example.ems.host:443/_synapse/admin/v2/users/@exampleuser:example.ems.host
Continuing with the Python example, you can now use this to remove the external_ids
from each SSO account, and add that information to the associated Original account.
Python:
# REMOVE 'external_ids' from 'sso_username' ACCOUNTS FROM 'all_external_ids' THEN
# UPDATE ALL 'original_username' ACCOUNTS FROM 'all_external_ids' WITH 'external_ids' FROM 'sso_username'
for user in all_external_ids:
data = '{"external_ids":' + str(user['external_ids']).replace("'", '"').replace(" ", "") + '}'
remove_sso = requests.put(url + '/_synapse/admin/v2/users/' + user['sso_username'], headers=headers, data='{"external_ids":[]}')
if remove_sso.status_code == 200:
add_sso = requests.put(url + '/_synapse/admin/v2/users/' + user['original_username'], headers=headers, data=data)