16.2.1.5. Container Class

The following container types are known to privacyIDEA. All are inherited from the generic tokenclass which is described below.

16.2.1.5.3. Generic

class privacyidea.lib.containerclass.TokenContainerClass(db_container)[source]
add_options(options)[source]

Add the given options to the container.

Parameters:

options – The options to add as dictionary

add_states(state_list: list[str]) dict[str, bool][source]

Add states to the container. Previous states are only removed if a new state excludes them. Raises a ParameterError if the state list contains exclusive states.

Parameters:

state_list – List of states as strings

Returns:

Dictionary in the format {state: success}

add_token(token: TokenClass) bool[source]

Add a token to the container. Raises a ParameterError if the token type is not supported by the container.

Parameters:

token – TokenClass object

Returns:

True if the token was successfully added, False if the token is already in the container

add_user(user: User) bool[source]

Assign a user to the container. Raises a UserError if the user does not exist. Raises a TokenAdminError if the container already has an owner.

Parameters:

user – User object

Returns:

True if the user was assigned

check_challenge_response(params: dict)[source]

Checks if the response to a challenge is valid.

create_challenge(scope, validity_time=2)[source]

Create a challenge for the container.

property db_id: int
delete() int[source]

Deletes the container and all associated objects from the database. Returns the id of the deleted container.

delete_container_info(key=None, keep_internal: bool = True) dict[str, bool][source]

Delete the tokencontainerinfo from the DB

Parameters:
  • key – key to delete, if None all keys are deleted

  • keep_internal – If True, entries of type PI_INTERNAL are not deleted

Returns:

dictionary of deleted keys in the format {key: deleted}

property description: str
encrypt_dict(container_dict: dict, params: dict)[source]

Encrypts a dictionary with the public key of the container. It is not supported by all container classes. Classes not supporting the encryption raise a privacyIDEA error.

finalize_registration(params)[source]

Finalize the registration of a container.

get_as_dict(include_tokens: bool = True, public_info: bool = True, additional_hide_info: list = None) dict[str, any][source]

Returns a dictionary containing all properties, contained tokens, and owners

Parameters:
  • include_tokens – If True, the tokens are included in the dictionary

  • public_info – If True, only public information is included and sensitive information is omitted

  • additional_hide_info – List of keys that shall be omitted from the dictionary

Returns:

Dictionary with the container details

Example response:

{
    "type": "smartphone",
    "serial": "SMPH00038DD3",
    "description": "My smartphone",
    "last_authentication": "2024-09-11T08:56:37.200336+00:00",
    "last_synchronization": "2024-09-11T08:56:37.200336+00:00",
    "states": ["active"],
    "info": {
                "hash_algorithm": "SHA256",
                "key_algorithm": "secp384r1"
            },
    "internal_info_keys": ["hash_algorithm"],
    "realms": ["deflocal"],
    "users": [{"user_name": "testuser",
               "user_realm": "deflocal",
               "user_resolver": "internal",
               "user_id": 1}],
    "tokens": ["TOTP000152D1", "HOTP00012345"]
}
classmethod get_class_description() str[source]

Returns a description of the container class.

classmethod get_class_options(only_selectable=False) dict[str, list[str]][source]

Returns the options for the container class.

Parameters:

only_selectable – If True, only options with more than one value are returned.

Returns:

Dictionary in the format {key: [values]}

classmethod get_class_prefix() str[source]

Returns the container class specific prefix for the serial.

classmethod get_class_type() str[source]

Returns the type of the container class.

get_container_info() list[TokenContainerInfo][source]

Return the tokencontainerinfo from the DB

Returns:

list of tokencontainerinfo objects

get_container_info_dict() dict[str, str][source]

Return the tokencontainerinfo from the DB as dictionary

Returns:

dictionary of tokencontainerinfo objects

get_internal_info_keys() list[str][source]

Returns the keys of the internal container info.

classmethod get_state_types() dict[str, list[str]][source]

Returns the state types that are supported by this container class and the states that are exclusive to each of these states.

Returns:

Dictionary in the format: {state: [excluded_states]}

get_states() list[str][source]

Returns the states of the container as a list of strings.

classmethod get_supported_token_types() list[str][source]

Returns the token types that are supported by the container class.

get_tokens() list[TokenClass][source]

Returns the tokens of the container as a list of TokenClass objects.

get_tokens_for_synchronization() list[TokenClass][source]

Returns the tokens of the container that can be synchronized with a client as a list of TokenClass objects.

get_users() list[User][source]

Returns a list of users that are assigned to the container.

init_registration(server_url: str, scope: str, registration_ttl: int, ssl_verify: bool, params: dict = None)[source]

Initializes the registration: Generates a QR code containing all relevant data.

Parameters:
  • server_url – URL of the server reachable for the client.

  • scope – The URL the client contacts to finalize the registration e.g. “https://pi.net/container/register/finalize”.

  • registration_ttl – Time to live of the registration link in minutes.

  • ssl_verify – Whether the client shall use ssl.

  • params – Container specific parameters

classmethod is_multi_challenge_enrollable() bool[source]

Returns True if the container type can be enrolled during the authentication process “via multi challenge”

property last_authentication: datetime | None

Returns the timestamp of the last seen field in the database. It is the time when a token of the container was last used successfully for authentication. From this layer on it is hence called ‘last_authentication’. If the container was never used for authentication, the value is None.

property last_synchronization: datetime | None

Returns the timestamp of the last updated field in the database. It is the time when the container was last synchronized with the privacyIDEA server. From this layer on it is hence called ‘last_synchronization’.

options = {}
property realms: list[Realm]
property registration_state: RegistrationState

Returns the registration state of the container. The registration state is stored in the container info with key ‘registration_state’. If the key does not exist, it returns the registration state NOT_REGISTERED with the value None.

remove_token(serial: str) bool[source]

Remove a token from the container. Raises a ResourceNotFoundError if the token does not exist.

Parameters:

serial – Serial of the token

Returns:

True if the token was successfully removed, False if the token was not found in the container

remove_user(user: User) bool[source]

Remove a user from the container. Also, non-existing users can be removed without an error. However, if no matching user is found to remove, we raise an error if the user does not exist.

Parameters:

user – User object to be removed

Returns:

True if the user was removed, False if the user was not found in the container

reset_last_authentication()[source]

Resets the timestamp of the last seen field in the database.

reset_last_synchronization()[source]

Resets the timestamp of the last updated field in the database.

property serial: str
set_container_info(info)[source]

Set the containerinfo field in the DB. Old values will be deleted.

Parameters:

info – dictionary in the format: {key: value}

set_default_option(key) str[source]

Checks if a value is set in the container info for the requested key. If not, the default value is set, otherwise the already set value is kept.

Parameters:

key – The key to be checked.

Returns:

The used value for the key or None if the key does not exist in the class options.

set_realms(realms, add=False) dict[str, bool][source]

Set the realms of the container. If add is True, the realms will be added to the existing realms, otherwise the existing realms will be removed.

Parameters:
  • realms – List of realm names

  • add – False if the existing realms shall be removed, True otherwise

Returns:

Dictionary in the format {realm: success}, the entry ‘deleted’ indicates whether existing realms were deleted.

set_states(state_list: list[str]) dict[str, bool][source]

Set the states of the container. Previous states will be removed. Raises a ParameterError if the state list contains exclusive states.

Parameters:

state_list – List of states as strings

Returns:

Dictionary in the format {state: success}

synchronize_container_details(container_client: dict, initial_transfer_allowed: bool = False) dict[str, dict[str, any]][source]

Compares the container from the client with the server and returns the differences. The container dictionary from the client contains information about the container itself and the tokens. For each token the type and serial shall be provided. If no serial is available, two otp values can be provided. The server than tries to find the serial for the otp values. If multiple serials are found, it will not be included in the returned dictionary, since the token can not be uniquely identified. The returned dictionary contains information about the container itself and the tokens that needs to be added or updated. For the tokens to be added the enrollUrl is provided. For the tokens to be updated at least the serial and the tokentype are provided.

An example container dictionary from the client:

{
    "serial": "SMPH001",
    "type": "smartphone",
    "tokens": [{"serial": "TOTP001", "tokentype": "TOTP"},
                {"otp": ["1234", "9876"], "tokentype": "HOTP", "counter": "2"}]
}

An example of a returned container dictionary:

{
    "container": {"type": "smartphone", "serial": "SMPH001"},
    "tokens": {"add": ["enroll_url1", "enroll_url2"],
               "update": [{"serial": "TOTP001", "tokentype": "totp"},
                          {"serial": "HOTP001", "otp": ["1234", "9876"],
                           "tokentype": "hotp", "counter": 2}]}
}
Parameters:
  • initial_transfer_allowed – If True, all tokens from the client are added to the container

  • container_client – The container from the client as dictionary.

Returns:

container dictionary

property template: TokenContainerTemplate

Returns the template the container is based on.

terminate_registration()[source]

Terminate the synchronisation of the container with privacyIDEA.

property type: str
update_container_info(info: list[TokenContainerInfoData])[source]

Updates the container info for the passed list of container info. Non-existing keys are added and the values for existing keys are updated.

Parameters:

info – list of TokenContainerInfoData objects

update_last_authentication()[source]

Updates the timestamp of the last seen field in the database.

update_last_synchronization()[source]

Updates the timestamp of the last updated field in the database.

validate_challenge(signature: bytes, public_key: EllipticCurvePublicKey, scope: str, transaction_id: str = None, key: str = None, container: str = None, device_brand: str = None, device_model: str = None, passphrase: str = None) bool[source]
Verifies the response of a challenge:
  • Checks if challenge is valid (not expired)

  • Checks if the challenge is for the right scope

  • Verifies the signature

Implicitly verifies the passphrase by adding it to the signature message. The passphrase needs to be defined in the challenge data. Otherwise, no passphrase is used.

Parameters:
  • signature – Signature of the message

  • public_key – Public key to verify the signature

  • scope – endpoint to reach if the challenge is valid

  • transaction_id – Transaction ID of the challenge, optional

  • key – Key to be included in the signature, optional

  • container – Container to be included in the signature, optional

  • device_brand – Device brand to be included in the signature, optional

  • device_model – Device model to be included in the signature, optional

  • passphrase – Passphrase to be included in the signature and validated against the user store, optional

Returns:

True if the challenge response is valid, False otherwise