16.2.1.17. UserIdResolvers

The useridresolver is responsible for getting userids for loginnames and vice versa.

This base module contains the base class UserIdResolver.UserIdResolver and also the community class PasswdIdResolver.IdResolver, that is inherited from the base class.

16.2.1.17.1. Base class

class privacyidea.lib.resolvers.UserIdResolver.UserIdResolver[source]
add_user(attributes: dict = None)[source]

Add a new user in the useridresolver. This is only possible, if the UserIdResolver supports this and if we have write access to the user store.

Parameters:

attributes – Attributes according to the attribute mapping

Returns:

The new UID of the user. The UserIdResolver needs to determine the way how to create the UID.

checkPass(uid, password)[source]

This function checks the password for a given uid. returns true in case of success false if password does not match

Parameters:
  • uid (string or int) – The uid in the resolver

  • password (string) – the password to check. Usually in cleartext

Returns:

True or False

Return type:

bool

close()[source]

Hook to close down the resolver after one request

delete_user(uid)[source]

Delete a user from the useridresolver. The user is referenced by the user id. :param uid: The uid of the user object, that should be deleted. :type uid: basestring :return: Returns True in case of success :rtype: bool

property editable

Return true, if the Instance! of this resolver is configured editable. :return:

classmethod getResolverClassDescriptor()[source]

return the descriptor of the resolver, which is - the class name and - the config description

Returns:

resolver description dict

Return type:

dict

static getResolverClassType()[source]

provide the resolver type for registration

static getResolverDescriptor()[source]

return the descriptor of the resolver, which is - the class name and - the config description

Returns:

resolver description dict

Return type:

dict

getResolverId()[source]

get resolver specific information :return: the resolver identifier string - empty string if not exist

static getResolverType()[source]

getResolverType - return the type of the resolver

Returns:

returns the string ‘ldapresolver’

Return type:

string

getUserId(loginName)[source]

The loginname is resolved to a user_id. Depending on the resolver type the user_id can be an ID (like in /etc/passwd) or a string (like the DN in LDAP)

It needs to return an empty string, if the user does not exist.

Parameters:

loginName (sting) – The login name of the user

Returns:

The ID of the user

Return type:

str

getUserInfo(userid)[source]

This function returns all user information for a given user object identified by UserID.

Parameters:

userid (int or string) – ID of the user in the resolver

Returns:

dictionary, if no object is found, the dictionary is empty

Return type:

dict

getUserList(search_dict=None)[source]

This function finds the user objects, that have the term ‘value’ in the user object field ‘key’

Parameters:

search_dict (dict) – dict with key values of user attributes - the key may be something like ‘loginname’ or ‘email’ the value is a regular expression.

Returns:

list of dictionaries (each dictionary contains a user object) or an empty string if no object is found.

Return type:

list of dicts

getUsername(userid)[source]

Returns the username/loginname for a given userid

Parameters:

userid (string) – The userid in this resolver

Returns:

username

Return type:

string

get_config() dict[source]

Returns the configuration of the resolver.

property has_multiple_loginnames

Return if this resolver has multiple loginname attributes :return: bool

loadConfig(config)[source]

Load the configuration from the dict into the Resolver object. If attributes are missing, need to set default values. If required attributes are missing, this should raise an Exception.

Parameters:

config (dict) – The configuration values of the resolver

classmethod testconnection(param)[source]

This function lets you test if the parameters can be used to create a working resolver. The implementation should try to connect to the user store and verify if users can be retrieved. In case of success it should return a text like “Resolver config seems OK. 123 Users found.”

Parameters:

param (dict) – The parameters that should be saved as the resolver

Returns:

returns True in case of success and a descriptive text

Return type:

tuple

update_user(uid, attributes=None)[source]

Update an existing user. This function is also used to update the password. Since the attribute mapping know, which field contains the password, this function can also take care for password changing.

Attributes that are not contained in the dict attributes are not modified.

Parameters:
  • uid (basestring) – The uid of the user object in the resolver.

  • attributes (dict) – Attributes to be updated.

Returns:

True in case of success

16.2.1.17.2. PasswdResolver

class privacyidea.lib.resolvers.PasswdIdResolver.IdResolver[source]

simple constructor

checkPass(uid, password)[source]

This function checks the password for a given uid. returns true in case of success false if password does not match

We do not support shadow passwords. so the seconds column of the passwd file needs to contain the encrypted password

If the password is a unicode object, it is encoded according to ENCODING first.

Parameters:
  • uid (int) – The uid of the user

  • password (sting) – The password in cleartext

Returns:

True or False

Return type:

bool

checkUserId(line, pattern)[source]

Check if a userid matches a pattern. A pattern can be “=1000”, “>=1000”, “<2000” or “between 1000,2000”.

Parameters:
  • line (dict) – the dictionary of a user

  • pattern (string) – match pattern with <, <=…

Returns:

True or False

Return type:

bool

checkUserName(line, pattern)[source]

check for user name

classmethod getResolverClassDescriptor()[source]

return the descriptor of the resolver, which is - the class name and - the config description

Returns:

resolver description dict

Return type:

dict

static getResolverClassType()[source]

provide the resolver type for registration

static getResolverDescriptor()[source]

return the descriptor of the resolver, which is - the class name and - the config description

Returns:

resolver description dict

Return type:

dict

getResolverId()[source]

return the resolver identifier string, which in fact is filename, where it points to.

static getResolverType()[source]

getResolverType - return the type of the resolver

Returns:

returns the string ‘ldapresolver’

Return type:

string

getSearchFields(searchDict=None)[source]

show, which search fields this userIdResolver supports

TODO: implementation is not completed

Parameters:

searchDict (dict) – fields, which can be queried

Returns:

dict of all searchFields

Return type:

dict

getUserId(LoginName)[source]

search the user id from the login name

Parameters:

LoginName – the login of the user (as unicode)

Returns:

the userId

Return type:

str

getUserInfo(userId, no_passwd=False)[source]

get some info about the user as we only have the loginId, we have to traverse the dict for the value

Parameters:
  • userId – the to be searched user

  • no_passwd – return no password

Returns:

dict of user info

getUserList(search_dict=None)[source]

get a list of all users matching the search criteria of the searchdict

Parameters:

search_dict – dict of search expressions

getUsername(userId)[source]

Returns the username/loginname for a given userid :param userid: The userid in this resolver :type userid: string :return: username :rtype: str

loadConfig(configDict)[source]

The UserIdResolver could be configured from the pylons app config - here this could be the passwd file , whether it is /etc/passwd or /etc/shadow

loadFile()[source]

Loads the data of the file initially. if the self.fileName is empty, it loads /etc/passwd. Empty lines are ignored.

static setup(config=None, cache_dir=None)[source]

this setup hook is triggered, when the server starts to serve the first request

Parameters:

config (the privacyidea config dict) – the privacyidea config

16.2.1.17.3. LDAPResolver

class privacyidea.lib.resolvers.LDAPIdResolver.IdResolver[source]
add_user(attributes: dict = None)[source]

Add a new user to the LDAP directory. The user can only be created in the LDAP using a DN. So we have to construct the DN out of the given attributes.

attributes are these “username”, “surname”, “givenname”, “email”, “mobile”, “phone”, “password”

Parameters:

attributes (dict) – Attributes according to the attribute mapping

Returns:

The new UID of the user. The UserIdResolver needs to determine the way how to create the UID.

checkPass(uid, password)[source]

This function checks the password for a given uid. - returns true in case of success - false if password does not match

static create_connection(authtype=None, server=None, user=None, password=None, auto_bind='NONE', client_strategy='SYNC', check_names=True, auto_referrals=False, receive_timeout=5, start_tls=False, keytabfile=None)[source]

Create a connection to the LDAP server.

Parameters:
  • authtype

  • server

  • user

  • password

  • auto_bind

  • client_strategy

  • check_names

  • auto_referrals

  • receive_timeout (float) – At the moment we do not use this, since receive_timeout is not supported by ldap3 < 2

  • start_tls (bool) – Use startTLS for connection to server

  • keytabfile (str or None) – Path to keytab file for service account

Returns:

classmethod create_serverpool(urilist, timeout, get_info=None, tls_context=None, rounds=2, exhaust=30, pool_cls=<class 'ldap3.core.pooling.ServerPool'>, strategy='ROUND_ROBIN')[source]

This creates the serverpool for the ldap3 connection. The URI from the LDAP resolver can contain a comma separated list of LDAP servers. These are split and then added to the pool.

See https://github.com/cannatag/ldap3/blob/master/docs/manual/source/servers.rst#server-pool

Parameters:
  • urilist (basestring) – The list of LDAP URIs, comma separated

  • timeout (float) – The connection timeout

  • get_info – The get_info type passed to the ldap3.Sever constructor. default: ldap3.SCHEMA, should be ldap3.NONE in case of a bind.

  • tls_context – A ldap3.tls object, which defines if certificate verification should be performed

  • rounds – The number of rounds we should cycle through the server pool before giving up

  • exhaust – The seconds, for how long a non-reachable server should be removed from the serverpool

  • pool_clsldap3.ServerPool subclass that should be instantiated

  • strategy (str) – The pooling strategy of the server-pool

Returns:

Server Pool

Return type:

ldap3.ServerPool

delete_user(uid)[source]

Delete a user from the LDAP Directory. The user is referenced by the user id.

Parameters:

uid (str) – The uid of the user object, that should be deleted.

Returns:

Returns True in case of success

Return type:

bool

property editable

Return true, if the instance of the resolver is configured editable :return:

classmethod getResolverClassDescriptor()[source]

return the descriptor of the resolver, which is - the class name and - the config description

Returns:

resolver description dict

Return type:

dict

static getResolverClassType()[source]

provide the resolver type for registration

static getResolverDescriptor()[source]

return the descriptor of the resolver, which is - the class name and - the config description

Returns:

resolver description dict

Return type:

dict

getResolverId()[source]

Returns the resolver Id This should be an Identifier of the resolver, preferable the type and the name of the resolver.

Returns:

the id of the resolver

Return type:

str

static getResolverType()[source]

getResolverType - return the type of the resolver

Returns:

returns the string ‘ldapresolver’

Return type:

string

getUserId(login_name)[source]

resolve the loginname to the userid.

Parameters:

login_name (str) – The login name from the credentials

Returns:

UserId as found for the LoginName

Return type:

str

getUserInfo(user_id)[source]

This function returns all user info for a given userid/object.

Parameters:

user_id (string) – The userid of the object

Returns:

A dictionary with the keys defined in self.userinfo

Return type:

dict

getUserList(search_dict=None)[source]
Parameters:

search_dict (dict) – A dictionary with search parameters

Returns:

list of users, where each user is a dictionary

getUsername(user_id)[source]

Returns the username/loginname for a given user_id

Parameters:

user_id (string) – The user_id in this resolver

Returns:

username

Return type:

string

get_persistent_serverpool(get_info=None)[source]

Return a process-level instance of LockingServerPool for the current LDAP resolver configuration. Retrieve it from the app-local store. If such an instance does not exist yet, create one.

Parameters:

get_info – one of ldap3.SCHEMA, ldap3.NONE, ldap3.ALL

Returns:

a LockingServerPool instance

get_serverpool_instance(get_info=None)[source]

Return a ServerPool instance that should be used. If SERVERPOOL_PERSISTENT is enabled, invoke get_persistent_serverpool to retrieve a per-process server pool instance. If it is not enabled, invoke create_serverpool to retrieve a per-request server pool instance.

Parameters:

get_info – one of ldap3.SCHEMA, ldap3.NONE, ldap3.ALL

Returns:

a ServerPool/LockingServerPool instance

property has_multiple_loginnames

Return if this resolver has multiple loginname attributes :return: bool

loadConfig(config)[source]

Load the config from conf.

Parameters:

config (dict) – The configuration from the Config Table

‘#ldap_uri’: ‘LDAPURI’, ‘#ldap_basedn’: ‘LDAPBASE’, ‘#ldap_binddn’: ‘BINDDN’, ‘#ldap_password’: ‘BINDPW’, ‘#ldap_timeout’: ‘TIMEOUT’, ‘#ldap_sizelimit’: ‘SIZELIMIT’, ‘#ldap_loginattr’: ‘LOGINNAMEATTRIBUTE’, ‘#ldap_searchfilter’: ‘LDAPSEARCHFILTER’, ‘#ldap_mapping’: ‘USERINFO’, ‘#ldap_uidtype’: ‘UIDTYPE’, ‘#ldap_noreferrals’ : ‘NOREFERRALS’, ‘#ldap_editable’ : ‘EDITABLE’, ‘#ldap_certificate’: ‘CACERTIFICATE’, ‘#ldap_keytabfile’: ‘KEYTABFILE’,

static split_uri(uri)[source]

Splits LDAP URIs like: * ldap://server * ldaps://server * ldap[s]://server:1234 * server :param uri: The LDAP URI :return: Returns a tuple of Servername, Port and SSL(bool)

classmethod testconnection(param)[source]

This function lets you test the to be saved LDAP connection.

Parameters are:

BINDDN, BINDPW, LDAPURI, TIMEOUT, LDAPBASE, LOGINNAMEATTRIBUTE, LDAPSEARCHFILTER, USERINFO, SIZELIMIT, NOREFERRALS, CACERTIFICATE, AUTHTYPE, TLS_VERIFY, TLS_VERSION, TLS_CA_FILE, SERVERPOOL_ROUNDS, SERVERPOOL_SKIP, SERVERPOOL_STRATEGY

Parameters:

param (dict) – A dictionary with all necessary parameter to test the connection.

Returns:

Tuple of success and a description

Return type:

(bool, string)

unbind()[source]

Unbind and close open connection

update_user(uid, attributes=None)[source]

Update an existing user. This function is also used to update the password. Since the attribute mapping know, which field contains the password, this function can also take care for password changing.

Attributes that are not contained in the dict attributes are not modified.

Parameters:
  • uid (basestring) – The uid of the user object in the resolver.

  • attributes (dict) – Attributes to be updated.

Returns:

True in case of success

16.2.1.17.4. HTTPResolver

class privacyidea.lib.resolvers.HTTPResolver.HTTPResolver[source]
add_user(attributes: dict | None = None) str[source]

Add a new user in the useridresolver. This is only possible, if the UserIdResolver supports this and if we have write access to the user store.

Parameters:

attributes – Attributes according to the attribute mapping

Returns:

The new UID of the user.

checkPass(uid: str, password: str, username: str | None = None) bool[source]

This function checks the password for a given user. The user can either be identified by the uid or the username.

Parameters:
  • uid – The uid in the resolver

  • password – the password to check. Usually in cleartext

  • username – The username of the user

Returns:

True or False

default_error_handling(response: Response, config: RequestConfig) bool[source]

Checks if an HTTP error occurred and raise it or if the custom error handling fits the response.

Parameters:
  • response – The response object from the HTTP request

  • config – Configuration for the endpoint containing information about special error handling

Returns:

True if the request was successful, False otherwise

delete_user(uid: str) bool[source]

Delete a user from the useridresolver. The user is referenced by the user id.

Parameters:

uid – The uid of the user object, that should be deleted.

Returns:

Returns True in case of success

property editable: bool

Return true, if the Instance! of this resolver is configured editable. :return:

classmethod getResolverClassDescriptor() dict[source]

return the descriptor of the resolver, which is - the class name and - the config description

Returns:

resolver description dict

static getResolverClassType() str[source]

provide the resolver type for registration

static getResolverDescriptor() dict[source]

return the descriptor of the resolver, which is - the class name and - the config description

Returns:

resolver description dict

Return type:

dict

getResolverId() str[source]

get resolver specific information :return: the resolver identifier string - empty string if not exist

static getResolverType() str[source]

getResolverType - return the type of the resolver

Returns:

returns the string ‘ldapresolver’

Return type:

string

getUserId(login_name: str) str[source]

Returns the user ID for the given username. If the user does not exist, an empty string is returned. If the endpoint to get the user by its username is not configured, only the username is echoed.

Parameters:

login_name – The username to resolve

Returns:

The user ID for the given username or an empty string if the user does not exist.

getUserInfo(userid: str) dict[source]

This function returns all user information for a given user object identified by UserID.

Parameters:

userid – ID of the user in the resolver

Returns:

dictionary, if no object is found, the dictionary is empty

getUserList(search_dict: dict | None = None) list[dict][source]

Fetches all users from the user store according to the search dictionary. If the endpoint is not configured to list all users, an empty list is returned.

getUsername(userid: str) str[source]

Returns the username for the given user ID.

get_config() dict[source]

Returns the configuration of the resolver.

static get_error(response: Response) Error[source]

Extracts a potential error from the response.

Parameters:

response – Response object

Returns:

Error dataclass containing the error info

loadConfig(config: dict)[source]

Load the configuration from the dict into the Resolver object. If attributes are missing, need to set default values. If required attributes are missing, this should raise an Exception.

For the basic http resolver the config dict must contain the following entries: * endpoint: str * method: str (e.g. “get” or “post”) * requestMapping: str (JSON) or dict * responseMapping: str (JSON) or dict * hasSpecialErrorHandler: bool or str (e.g. “true” or “false”) * errorResponse: str (JSON) or dict

For the advanced http resolver the config can contain the following entries: * base_url: str * headers: dict or str (JSON) * attribute_mapping: dict (or JSON str) * Editable: bool or str (e.g. “true” or “false”) * config_authorization: dict * config_user_auth: dict * username: str * password: str * verify_tls: bool or str (e.g. “true” or “false”) * tls_certificate_path: str * timeout: int (seconds) or str e.g. “10” * config_get_user_by_id: dict

  • method: str (e.g. “get” or “post”)

  • endpoint: str

  • headers: str (JSON) or dict

  • requestMapping: str (JSON) or dict

  • responseMapping: str (JSON) or dict

  • hasSpecialErrorHandler: bool or str (e.g. “true” or “false”)

  • errorResponse: str (JSON) or dict

  • config_get_user_by_name: dict
    • see config_get_user_by_id

  • config_get_user_list: dict
    • see config_get_user_by_id

  • config_create_user
    • see config_get_user_by_id

  • config_edit_user
    • see config_get_user_by_id

  • config_delete_user
    • see config_get_user_by_id

Parameters:

config (dict) – The configuration values of the resolver

property map: dict

Return the attribute mapping from privacyidea to the user store. This is used to get the relevant attributes from the request parameters.

Returns:

attribute mapping pi to user store

classmethod testconnection(param: dict) tuple[bool, str][source]

This function lets you test if the parameters can be used to create a working resolver. Also, you can use it anytime you see if the API is running as expected. The implementation should try to make a request to the HTTP API and verify if user can be retrieved. In case of success it should return a list of all tested functions.

The following functions are tested (if configured):
  • loading the configuration

  • authorization endpoint: Retrieve an access token to use the users API

  • Resolve a test user by the user ID (“test_username” must be provided in param)

  • Resolve a test user by the username (“test_username” must be provided in param)

  • List all users

  • Evaluate config to check a users password

  • Evaluate config to create a user

  • Evaluate config to edit a user

  • Evaluate config to delete a user

Parameters:

param – The parameters that should be saved as the resolver

Returns:

returns True in case of success and a raw response

update_user(uid: str, attributes: dict | None = None) bool[source]

Update an existing user. This function can also be used to update the password. Attributes that are not contained in the dict attributes are not modified.

Parameters:
  • uid – The uid of the user object in the resolver.

  • attributes – Attributes to be updated.

Returns:

True in case of success

16.2.1.17.5. EntraIDResolver

class privacyidea.lib.resolvers.EntraIDResolver.EntraIDResolver[source]
checkPass(uid: str, password: str, username: str | None = None) bool[source]

This function checks the password for a given user. The user can either be identified by the uid or the username. EntraID provides the OAuth 2.0 ROPC flow to check the password. This flow only supports using client secrets and does not support client certificates. If the resolver is configured to use a client certificate, this function will raise a ResolverError.

Parameters:
  • uid – The uid in the resolver

  • password – the password to check. Usually in cleartext

  • username – The username of the user

Returns:

True or False

classmethod getResolverClassDescriptor() dict[source]

Returns the class descriptor which is a dictionary with the resolver type as key and a dictionary containing the data type for each configuration parameter as value.

static getResolverClassType()[source]

Provide the resolver type for registration.

static getResolverDescriptor() dict[source]

Returns the descriptor of the resolver, which is the class name and the config description.

static getResolverType()[source]

Returns the type of the resolver

get_config() dict[source]

Returns the configuration of the resolver.

static get_error(response: Response) Error[source]

Extracts a potential error from the response. EntraID usually returns errors in the format: {"error": "code": "ErrorCode", "message": "Error message"}

Parameters:

response – Response object

Returns:

Error dataclass containing the error info

loadConfig(config: dict)[source]

loadConfig - load the configuration from the database.

Parameters:

config – the config dictionary

16.2.1.17.6. KeycloakResolver

class privacyidea.lib.resolvers.KeycloakResolver.KeycloakResolver[source]
classmethod getResolverClassDescriptor() dict[source]

Returns the class descriptor which is a dictionary with the resolver type as key and a dictionary containing the data type for each configuration parameter as value.

static getResolverClassType() str[source]

provide the resolver type for registration

static getResolverDescriptor() dict[source]

Returns the descriptor of the resolver, which is the class name and the config description.

static getResolverType() str[source]

Returns the type of the resolver

getUserId(login_name: str) str[source]

Searches for a user by its name. Keycloak does not have an explicit endpoint for this purpose. Hence, we use the endpoint to get all users but filter for the username.

get_config() dict[source]

Returns the configuration of the resolver.

static get_error(response: Response) Error | None[source]

Extracts the error message from the response if available. It tries to get the error message under the key “errorMessage” or “error”.

Parameters:

response – The response object from the HTTP request

Returns:

The error message if available, otherwise None

loadConfig(config: dict)[source]

Load the configuration for the resolver.