This page is a considered
complete and accurate. However, if you find an error, please take the time
report it.
In this short article we are going to learn how to write a simple Users Storage Provider for ScrewTurn Wiki 3.0 (STW from now on). A User Storage Provider is a type of plugin that handles users-related data such as user accounts and groups.
Introduction to Users Storage Providers
This brief section assumes you have already a
general knowledge on STW providers.
The main task a Users Storage Provider performs is handling the following data on behalf of the wiki application:
- user accounts
- user groups
- user group membership
- user data (e.g. user preferences such as the time-zone).
Each of those data groups can be read-only, meaning that the wiki application will only read data from the provider and will not attempt to edit it.
Note: in case of
read-only data, as described below, the wiki application should never call methods that are intended for altering data. However, such methods that return collections should return empty collections instead of
null. Methods that return single elements (e.g.
UserInfo) should return
null instead.
Important note: all providers should be totally thread-safe.
User Accounts
User accounts are described by the
UserInfo class, that contains relevant information such as the username, the email address, the full/display name. The password is not stored in the
UserInfo class as its management is entirely demanded to the provider.
When returning an instance of
UserInfo, the provider must set the
Provider property to itself, so that the wiki application can easily identify the provider that handles a given
UserInfo instance.
Managing User Accounts
The following methods are used by the wiki application to list, add, remove and update user accounts:
GetUsers should return all user accounts, sorted by usernameGetUser finds a user by username (case-insensitive)GetUserByEmail finds a user by email (generally, no duplicate email is allowed)AddUser adds a new user accountModifyUser modifies an existing user account (note: the username is immutable)RemoveUser removes an existing user.
If the provider's
UserAccountsReadOnly property returns
true, the wiki will consider user accounts handled by the provider as
read-only, i.e. the wiki application will only call
GetUsers/
GetUser/
GetUserByEmail and the login control methods, guaranteeing that methods that alter users are never called. This setting is useful when integrating the user store with another, external application.
Login Control
Logins are controlled via the following methods:
TestAccount is generally used to validate a user's password, but generally not when logging inTryManualLogin is called when the user tries to login via username and passwordTryAutoLogin is called every time a user starts a browsing session, so that the provider can start an external authentication procedure, using information available in the HttpContextNotifyCookieLogin is called when the wiki application has logged in a user via an authentication cookieNotifyLogout is called when a user logs out (might not be called in some cases).
User Groups and Membership¶
User groups allows to easily manage permissions for groups of users. Groups are described by instances of the
UserGroup class, that contains a name, a description and the list of users that are member of the group (array of strings, which are the usernames). Such member users can only be managed by the same provider (e.g. the wiki application will not allow to set a user managed by provider A as a member of a group managed by provider B).
When returning an instance of
UserGroup, the provider must set the
Provider property to itself, so that the wiki application can easily identify the provider that handles a given
UserGroup instance.
Managing User Groups
The following methods are used by the application to list, add, remove, update user groups, as well as to set the group membership of users:
GetUserGroups should return all user groups, sorted by nameAddUserGroup adds a new user groupModifyUserGroup modifies an existing group (note: the name is immutable)RemoveUserGroup removes an existing user groupSetUserMembership sets the groups a user is member of.
If the provider's
UserGroupsReadOnly property returns
true, the wiki will consider user groups handled by the provider as
read-only, i.e. the wiki application will only call
GetUserGroups, guaranteeing that methods that alter groups are never called. This setting is useful when integrating the user store with another, external application.
Additionally, if the provider's
GroupMembershipReadOnly property returns
true, the wiki will never call
SetUserMembership on the provider.
User Data
User's data consists in a simple
key, value store (both
strings, no new-lines or pipes are allowed). There is no backend class for this data, as a generic
IDictionary<string, string> is used.
Managing User Data
The following methods allow the wiki application to manage user data:
StoreUserData stores a key, value pair for a user; if value is null, the pair is deletedRetrieveUserData retrieves a key, value pair for a userGetUsersWithData gets the list of all users that have a specific key in their data.
If the provider's
UserDataReadOnly returns
true, the wiki application will never call
StoreUserData.