In TiddlyWeb, authentication and authorization is modeled around users, bags, policies, challengers and credentials extractors.
By default, managing users is done with server side code. Users, passwords, challengers and credentials extractors and configuration are managed either from the command line using twanager or in plugin code.
There is no core HTTP API exposure of the user datastore entities in the core code. TiddlySpace uses a plugin called {{{tidldywebplugins.socialusers}}} to remotely create users and allow them to change their password. It can be used with any TiddlyWeb instance. It is available from PyPI.
Here are a list of facts about users:
- If a request is authenticated using OpenID or some other external service, there is no requirement for a user to exist in the store, the OpenID will be placed in tiddlyweb.usersign.
- If you want to create a user in the store from the command line, setting a password, roles, or both, you can use the twanager command adduser. See also addrole and userpass.
- In TiddlyWeb plugin code it is possible to create a user by instantiating a new user object. See How do I create or update a User object in code?
- Users can have roles. If you want a user to have a role you can set it when creating a user using adduser or use addrole on an existing user. If you are using OpenID, and want to use roles, you can create a user in the store with an id corresponding to the OpenID and an empty password.
- Access to content is controlled by policies: there are policies on both bags and recipes.
- If a policy does not allow an action, and the action involves a {{{GET}}} request, the request will be redirected to the challenger system. If the requested action is a write operation the response will be an HTTP 403 (the current user can't do that) or 401 (we have no user and need one). This difference allows an interactive user to have a reasonable experience (when loading a page for which they need to be authenticated, they will get the chance to authenticate).
- Once a request successfully passes through a challenger it is redirected back to the original page requested. When the page is requested again (in fact when any request is made) the credentials extractor system looks at the incoming request. This determines the current user and then carries on with the request.
- When we get back to the previous point where the policy constraint was not met, we now have a user and assuming the constaint is passed, the code carries on.
TiddlyWebWiki tries to make it so challenges happen before a user enters into the TiddlyWiki space. That is, if we know there is going to be a need for a user, they get challenged outside of TiddlyWiki. However this is not at all required. A TiddlyWiki plugin could use XHR to make posts to the existing challenger forms and deal with the results (i.e. accept the cookie or other magic the challenger provides). Figuring out how to use the forms is as simple as looking at them.
Challengers are by design triggered only when unauthorized content is accessed but can be explicitly triggered by going to the {{{/challenge}}} URL on your installation.
TiddlyWeb goes to great lengths to make very few assumptions about who or what is talking to it. If you want to auth with JavaScript, curl, Python, a browser, carrier pigeons, as long as you are sending HTTP to the server, you've got a chance of getting it right.