The authenticator class is in fact an interface. UDS authenticators must derive from this, and must provide the logic so UDS can manage the users and groups that an authenticator provides.
This class represents the base interface to implement authenticators.
An authenticator is responsible for managing user and groups of a kind inside UDS. As so, it must provide a number of method and mechanics to allow UDS to manage users and groups using that kind of authenticator.
Some samples of authenticators are LDAP, Internal Database, SAML, CAS, ...
As always, if you override __init__, do not forget to invoke base __init__ as this:
super(self.__class__, self).__init__(self, dbAuth, environment, values)
This is a MUST, so internal structured gets filled correctly, so don’t forget it!.
The preferred method of doing initialization is to provide the initialize(), and do not override __init__ method. This (initialize) will be invoked after all internal initialization.
There are basically two kind of authenticators, that are “Externals” and “Internals”.
Internal authenticators are those where and administrator has created manually the user at admin interface. The users are not created from an external source, so if an user do not exist at UDS database, it will not be valid. In other words, if you have an authenticator where you must create users, you can modify them, you must assign passwords manually, and group membership also must be assigned manually, the authenticator is not an externalSource.
As you can notice, almost avery authenticator except internal db will be external source, so, by default, attribute that indicates that is an external source is set to True.
In fact, internal source authenticator is intended to allow UDS to identify if the users come from internal DB (just the case of local authenticator), or the users come from other sources. Also, this allos UDS to know when to “update” group membership information for an user whenever it logs in.
External authenticator are in fact all authenticators except local database, so we have defined isExternalSource as True by default, that will be most cases.
Note: | All attributes that are “_” here means that they will be translated when provided to administration interface, so remember to mark them in your own authenticators as “_” using ugettext_noop. We have aliased it here to “_” so it’s easier to understand. |
---|
A group is simply a database group associated with its authenticator instance
It’s only constructor expect a database group as parameter.
Returns the database group associated with this
Returns the database authenticator associated with this group
An user represents a database user, associated with its authenticator (instance) and its groups.
Returns the database user
Returns the valid groups for this user. To do this, it will validate groups throuht authenticator instance using uds.core.auths.Authenticator.getGroups() method.
Note: | Once obtained valid groups, it caches them until object removal. |
---|
Returns the authenticator instance
There is a view inside UDS, an url, that will redirect the petition to this callback.
If someone gets authenticated via this callback, the method will return an “username” must be return. This username will be used to:
- Add user to UDS
- Get user groups.
So, if this callback is called, also get the membership to groups of the user, and keep them. This method will have to keep track of those until UDS request that groups using getGroups. (This is easy, using storage() provided with the environment (env())
If this returns None, or empty, the authentication will be considered “invalid” and an error will be shown.
You can also return an exception here and, if you don’t wont to check the user login, you can raise :py:class:uds.core.auths.Exceptions.Redirect to redirect user to somewhere. In this case, no user checking will be done. This is usefull to use this url to provide other functionality appart of login, (such as logout)
Note: | Keeping user information about group membership inside storage is highly recommended. There will be calls to getGroups one an again, and also to getRealName, not just at login, but at future (from admin interface, at user editing for example) |
---|
This method must be overriden, and is responsible for authenticating users.
We can have to different situations here:
- The authenticator is external source, what means that users may be unknown to system before callig this
- The authenticator isn’t external source, what means that users have been manually added to system and are known before this call. This will only happen at Internal DB Authenticator.
We receive the username, the credentials used (normally password, but can be a public key or something related to pk) and a group manager.
The group manager is responsible for letting know the authenticator which groups we currently has active.
See uds.core.auths.GroupsManager
Note: | This method must check not only that the user has valid credentials, but also check the valid groups from groupsManager. If this method returns false, of method getValidGroups of the groupsManager passed into this method has no elements, the user will be considered invalid. So remember to check validity of groups this user belongs to (inside the authenticator, not inside UDS) using groupsManager.validate(group to which this users belongs to). This is done in this way, because UDS has only a subset of groups for this user, and we let the authenticator decide inside wich groups of UDS this users is included. |
---|
Helper method to return callback url for self (authenticator).
This method will allow us to know where to do redirection in case we need to use callback for authentication
Helper method to query if a class can do a login using credentials
This method is used when creating a new group to allow the authenticator:
- Check that the name inside groupData is fine
- Fill other (not name, if you don’t know what are you doing) usrData dictionary values.
This will be invoked from admin interface, when admin wants to create a new group.
modified groupData will be used to store values at database.
Raises an exception if things didn’t went fine, return value is ignored, but modified groupData is used if this does not raises an exception.
Take care with whatever you modify here, you can even modify provided name (group name) to a new one!
This method is used when creating an user to allow the authenticator:
- Check that the name inside usrData is fine
- Fill other (not name, if you don’t know what are you doing) usrData dictionary values.
This will be invoked from admin interface, when admin wants to create a new user
modified usrData will be used to store values at database.
Raises an exception if things didn’t went fine, return value is ignored, but modified usrData is used if this does not raises an exception.
Take care with whatever you modify here, you can even modify provided name (login name!) to a new one!
Note: | If you have an SSO where you can’t create an user from admin interface, raise an exception here indicating that the creation can’t be done. Default implementation simply raises “AuthenticatorException” and says that user can’t be created manually |
---|
Helper method to access the Authenticator database object
Process the username for this authenticator and returns it. This transformation is used for transports only, not for transforming anything at login time. Transports that will need the username, will invoke this method. For example, an authenticator can add '@domain‘ so transport use the complete 'user@domain‘ instead of ‘user’.
Right now, all authenticators keep this value “as is”, i mean, it simply returns the unprocessed username
Looks for the real groups to which the specified user belongs.
You MUST override this method, UDS will call it whenever it needs to refresh an user group membership.
The expected behavior of this method is to mark valid groups in the uds.core.auths.GroupsManager provided, normally calling its uds.core.auths.GroupsManager.validate() method with groups names provided by the authenticator itself (for example, LDAP, AD, ...)
If you override this method, and returns something different of None, UDS will consider your authenticator as “Owner draw”, that is, that it will not use the standard form for user authentication.
We have here a few things that we should know for creating our own html for authenticator:
- We use jQuery, so your javascript can use it
- The id of the username input field is id_user
- The id of the password input field is id_password
- The id of the login form is loginform
- The id of the “back to login” link is backToLogin
This is what happens when an authenticator that has getHtml method is selected in the front end (from the combo shown):
- The div with id login is hidden.
- The div with id nonStandard is shown
- Using Ajax, the html provided by this method is requested for the authenticator
- The returned html is rendered inside nonStandardLogin div.
- The nonStandard div is shown.
nonStandard div has two inner divs, nonStandardLogin and divBackToLogin. If there is no standard auths, divBackToLogin is erased.
With this, and :py:meth:.authCallback method, we can add SSO engines to UDS with no much problems.
This method is invoked whenever the authinfo url is invoked, with the name of the authenticator If this is implemented, information returned by this will be shown via web.
Note: | You can return here a single element or a list (or tuple), where first element will be content itself, and second will be the content type (i.e. “text/plain”). |
---|
Tries to get the real name of an user
Default implementation returns just the same user name that is passed in.
Helper method to return info url for this authenticator
This method will be invoked from __init__ constructor. This is provided so you don’t have to provide your own __init__ method, and invoke base methods. This will get invoked when all initialization stuff is done
Default implementation does nothing
This method is provided so “plugins” (For example, a custom dispatcher), can test the username/credentials in an alternative way.
For example, ip authenticator generates, inside the custom html, a 1 time password that will be used to authenticate the ip. If we create a custom dispatcher and we want to auth the user without the html part being displayed, we have a big problem.
Using this method, the authenticator has the oportunitiy to, (for example, in case of IP auth), ignore “credentials”
See uds.core.auths.GroupsManager
Note: | This method must check not only that the user has valid credentials, but also check the valid groups from groupsManager. If this method returns false, of method getValidGroups of the groupsManager passed into this method has no elements, the user will be considered invalid. So remember to check validity of groups this user belongs to (inside the authenticator, not inside UDS) using groupsManager.validate(group to which this users belongs to). This is done in this way, because UDS has only a subset of groups for this user, and we let the authenticator decide inside wich groups of UDS this users is included. |
---|
Helper to query if a class is custom (implements getHtml method)
Invoked whenever an user logs out.
Notice that authenticators that provides getHtml method are considered “custom”, and these authenticators will never be used to allow an user to access administration interface (they will be filtered out)
By default, this method does nothing.
Args:
username: Name of the user that logged out
Returns:
None if nothing has to be done by UDS. An URL (absolute or relative), if it has to redirect the user to somewhere.
Note: | This method will be invoked also for administration log out (it it’s done), but return result will be passed to administration interface, that will invoke the URL but nothing will be shown to the user. Also, notice that this method will only be invoked “implicity”, this means that will be invoked if user requests “log out”, but maybe it will never be invoked. |
---|
This method is used when modifying group to allow the authenticator:
- Check that the name inside groupData is fine
- Fill other (not name, if you don’t know what are you doing) usrData dictionary values.
This will be invoked from admin interface, when admin wants to create a new group.
modified groupData will be used to store values at database.
Note: ‘name’ output parameter will be ignored
This method is used when modifying an user to allow the authenticator:
- Check that the name inside usrData is fine
- Fill other (not name, if you don’t know what are you doing) usrData dictionary values.
Raises an exception if things didn’t went fine, return value is ignored, but modified usrData is used if this does not raises an exception.
Take care with whatever you modify here, you can even modify provided name (login name!) to a new one!
Note: | By default, this will do nothing, as we can only modify “accesory” internal data of users. |
---|
Helper method, not needed to be overriden. It simply checks if the source is external and if so, recreates the user groups for storing them at database.
user param is a database user object
Remove user is used whenever from the administration interface, or from other internal workers, an group needs to be removed.
This is a notification method, whenever an group gets removed from UDS, this will get called.
You can do here whatever you want, but you are not requested to do anything at your authenticators.
If this method raises an exception, the group will not be removed from UDS
Remove user is used whenever from the administration interface, or from other internal workers, an user needs to be removed.
This is a notification method, whenever an user gets removed from UDS, this will get called.
You can do here whatever you want, but you are not requested to do anything at your authenticators.
If this method raises an exception, the user will not be removed from UDS
Returns an array of groups that match the supplied pattern If none found, returns empty array. Items returned are BaseGroups (or derived) If you override this method, the admin interface will allow the use of “search” at group form. If not overriden, the search will not be allowed.
Must return array of dictionaries that must contains ‘id’ and ‘name’ example: [ {‘id’: ‘user1’, ‘name’: ‘Nombre 1’} ]
Default implementation returns empty array, but is never used because if not overriden, search of groups will not be allowed.
If you provide this method, the user will be allowed to search users, that is, the search button at administration interface, at user form, will be enabled.
Returns an array of users that match the supplied pattern If none found, returns empty array.
Must return is an array of dictionaries that must contains ‘id’ and ‘name’ example: [ {‘id’: ‘user1’, ‘name’: ‘Nombre 1’} ]
On login, this method get called so we can “transform” provided user name.
Note: | You don’t need to implement this method if your authenticator (as most authenticators does), does not transforms username. |
---|