Update: This has been fixed.
The current implementation is unsafe in a variety of ways and limits flexibility so a better implementation is desired.
The core requirement is to separate the connection between a username at identity service X or identify service Y from the username used at Tank. Luckily there's already a plugin that allows this sort of thing, but some additional jiggery pokery is needed to map the identity at X.
One possibility is including the name of the service in the username that is mapped from. In magicuser the MAPUSER
tiddlers are titles with the external username. The internal username is in a field.
Thus a registration and login process would go like this, using Github as an example:
- User arrives with no cookie and asks to log in or sign up.
- They choose Github
- The oauth2 process proceeds
- The consumer (tank) gets a successful response and maps the data to a username
- The service name is prepended to the username
- The string is used as a title to look in the
MAPUSER
bag, if found, this user exists and should be logged in (see below). - If there is no mapped user a registration form is presented
- If there is a User (user in the tiddlyweb store) with the username from above, have the form announce that username is not available and give empty username input field. Otherwise present the field with username, but let them change if they like.
- Elsewhere in the form will need to be the original username, signed
- Upon registration:
- mapping between service name, username and new User with new username is created
- a User is created (with null password, this username cannot log in directly)
- then the user is logged in
Logged in means setting a tiddlyweb_user
cookie with the server name, username combo with the usual hashing.
The main challenge in this situation is making sure that the registration form's data is submitted in a secure fashion. One way to do that is to send a signature of parts of the data in a hidden field. It would sign the service name and service username aspects against a server secret so that those submissions could be validated on submit. Otherwise it would be possible for someone to register an inappropriate mapping.
Another way to do would be to maintain some transient tiddlers on the server.
In either case the upshot of this is that multiple identity services can be used for login and the option to associate multiple external identities with one internal identity is preserved.
But it does mean that the change needs to be made before there are too many users.