authnzerver.actions.admin module

This contains functions to drive admin related actions (listing users, editing users, change user roles).

authnzerver.actions.admin.edit_user(payload: dict, raiseonfail: bool = False, override_permissions_json: str = None, override_authdb_path: str = None, config=None) → dict[source]

This edits users.

FIXME: add permissions checks to this instead of relying on a frontend to filter out users who aren’t allowed to perform this action.

Parameters:
  • payload (dict) –

    This is the input payload dict. Required items:

    • user_id: int, user ID of an admin user or == target_userid
    • user_role: str, == ‘superuser’ or == target_userid user_role
    • session_token: str, session token of admin or target_userid token
    • target_userid: int, the user to edit
    • update_dict: dict, the update dict

    In addition to these items received from an authnzerver client, the payload must also include the following keys (usually added in by a wrapping function):

    • reqid: int or str
    • pii_salt: str

    Only these items can be edited:

    {'full_name', 'email',     <- by user and superuser
     'is_active','user_role', 'email_verified'}  <- by superuser only
    

    User IDs 2 and 3 are reserved for the system-wide anonymous and locked users respectively, and can’t be edited.

  • raiseonfail (bool) – If True, will raise an Exception if something goes wrong.
  • override_permissions_json (str or None) –

    If given as a str, is the alternative path to the permissions JSON to load and use for this request. Normally, the path to the permissions JSON has already been specified as a process-local variable by the main authnzerver start up routines. If you want to use some other permissions model JSON (e.g. for testing), provide that here.

    Note that we load the permissions JSON from disk every time we need to take a decision. This might be a bit slower, but allows for much faster policy changes by just changing the permissions JSON file and not having to restart the authnzerver.

  • override_authdb_path (str or None) – If given as a str, is the alternative path to the auth DB.
  • config (SimpleNamespace object or None) – An object containing systemwide config variables as attributes. This is useful when the wrapping function needs to pass in some settings directly from environment variables.
Returns:

The dict returned is of the form:

{'success': True or False,
 'user_info': dict, with new user info,
 'messages': list of str messages if any}

Return type:

dict

authnzerver.actions.admin.get_user_by_email(payload: dict, raiseonfail: bool = False, override_authdb_path: str = None, config: types.SimpleNamespace = None) → dict[source]

This gets a user’s information using their email address.

FIXME: add permissions checks to this instead of relying on a frontend to filter out users who aren’t allowed to perform this action.

Parameters:
  • payload (dict) –

    This is the input payload dict. Required items:

    • email: str

    In addition to these items received from an authnzerver client, the payload must also include the following keys (usually added in by a wrapping function):

    • reqid: int or str
    • pii_salt: str
  • raiseonfail (bool) – If True, will raise an Exception if something goes wrong.
  • override_authdb_path (str or None) – If given as a str, is the alternative path to the auth DB.
  • config (SimpleNamespace object or None) – An object containing systemwide config variables as attributes. This is useful when the wrapping function needs to pass in some settings directly from environment variables.
Returns:

The dict returned is of the form:

{'success': True or False,
 'user_info': a user info dict,
 'messages': list of str messages if any}

The user info dict will contain the following items:

{'user_id','system_id', 'full_name', 'email',
 'is_active','created_on','user_role',
 'last_login_try','last_login_success'}

Return type:

dict

authnzerver.actions.admin.internal_edit_user(payload: dict, raiseonfail: bool = False, override_authdb_path: str = None, config: types.SimpleNamespace = None) → dict[source]

Handles editing users. Meant for use internally in a frontend server.

Parameters:
  • payload (dict) –

    The input payload dict. Required items:

    • target_userid: int, the user to edit
    • update_dict: dict, the changes to make, with each key being a column value to change in the users table.

    update_dict cannot contain the following fields: user_id, system_id, password, emailverify_sent_datetime, emailforgotpass_sent_datetime, emailchangepass_sent_datetime, last_login_success, last_login_try, failed_login_tries, created_on, and last_updated. These are tracked in other action functions and should not be changed directly.

    If update_dict contains the extra_info field, this JSON field in the database will be updated with the info in extra_info. To delete an item from extra_info, pass in the special value of “__delete__” in extra_info for that item.

    In addition to these items received from an authnzerver client, the payload must also include the following keys (usually added in by a wrapping function):

    • reqid: int or str
    • pii_salt: str
  • raiseonfail (bool) – If True, and something goes wrong, this will raise an Exception instead of returning normally with a failure condition.
  • override_authdb_path (str or None) – The SQLAlchemy database URL to use if not using the default auth DB.
  • config (SimpleNamespace object or None) – An object containing systemwide config variables as attributes. This is useful when the wrapping function needs to pass in some settings directly from environment variables.
Returns:

Returns a dict containing the new user information.

Return type:

dict

authnzerver.actions.admin.internal_toggle_user_lock(payload: dict, raiseonfail: bool = False, override_authdb_path: str = None, config: types.SimpleNamespace = None) → dict[source]

Locks/unlocks user accounts.

This version of the function should only be run internally (i.e. not called by a client). The use-case is automatically locking user accounts if there are too many incorrect password attempts. The lock can be permanent or temporary.

Parameters:
  • payload (dict) –

    This is the input payload dict. Required items:

    • target_userid: int, the user to lock/unlock
    • action: str {‘unlock’,’lock’}

    In addition to these items received from an authnzerver client, the payload must also include the following keys (usually added in by a wrapping function):

    • reqid: int or str
    • pii_salt: str
  • raiseonfail (bool) – If True, will raise an Exception if something goes wrong.
  • override_authdb_path (str or None) – If given as a str, is the alternative path to the auth DB.
  • config (SimpleNamespace object or None) – An object containing systemwide config variables as attributes. This is useful when the wrapping function needs to pass in some settings directly from environment variables.
Returns:

The dict returned is of the form:

{'success': True or False,
 'user_info': dict, with new user info,
 'messages': list of str messages if any}

Return type:

dict

authnzerver.actions.admin.list_users(payload: dict, raiseonfail: bool = False, override_authdb_path: str = None, override_permissions_json: str = None, config: types.SimpleNamespace = None) → dict[source]

This lists users.

FIXME: add permissions checks to this instead of relying on a frontend to filter out users who aren’t allowed to perform this action.

Parameters:
  • payload (dict) –

    This is the input payload dict. Required items:

    • user_id: int or None. If None, all users will be returned

    In addition to these items received from an authnzerver client, the payload must also include the following keys (usually added in by a wrapping function):

    • reqid: int or str
    • pii_salt: str
  • raiseonfail (bool) – If True, will raise an Exception if something goes wrong.
  • override_authdb_path (str or None) – If given as a str, is the alternative path to the auth DB.
  • override_permissions_json (str or None) – If given as a str, is the alternative path to the permissions JSON to use.
  • config (SimpleNamespace object or None) – An object containing systemwide config variables as attributes. This is useful when the wrapping function needs to pass in some settings directly from environment variables.
Returns:

The dict returned is of the form:

{'success': True or False,
 'user_info': list of dicts, one per user,
 'messages': list of str messages if any}

The dicts per user will contain the following items:

{'user_id','full_name', 'email',
 'is_active','created_on','user_role',
 'last_login_try','last_login_success'}

Return type:

dict

authnzerver.actions.admin.lookup_users(payload: dict, raiseonfail: bool = False, override_authdb_path: str = None, config: types.SimpleNamespace = None) → dict[source]

This looks up users by a given property.

FIXME: add permissions checks to this instead of relying on a frontend to filter out users who aren’t allowed to perform this action.

Valid properties are all the columns in the users table, except for the password column.

Parameters:
  • payload (dict) –

    This is the input payload dict. Required items:

    • by (str): the property column to use to look up the user by
    • match (object): the required value of the property. Note that in most cases, this will be coerced to a string to compare it to the database value.

    If by == ‘extra_info’, then match must be a dict of the form:

    {‘extra_info_key’: extra_info_value}

    to match one or more keys inside the extra_info JSON column to the specified value.

    In addition to these items received from an authnzerver client, the payload must also include the following keys (usually added in by a wrapping function):

    • reqid: int or str
    • pii_salt: str
  • raiseonfail (bool) – If True, will raise an Exception if something goes wrong.
  • override_authdb_path (str or None) – If given as a str, is the alternative path to the auth DB.
  • config (SimpleNamespace object or None) – An object containing systemwide config variables as attributes. This is useful when the wrapping function needs to pass in some settings directly from environment variables.
Returns:

The dict returned is of the form:

{'success': True or False,
 'user_info': a user info dict,
 'messages': list of str messages if any}

The user info dict will contain the following items:

{'user_id','system_id', 'full_name', 'email',
 'is_active','created_on','user_role',
 'last_login_try','last_login_success'}

Return type:

dict

authnzerver.actions.admin.toggle_user_lock(payload: dict, raiseonfail: bool = False, override_authdb_path: str = None, config: types.SimpleNamespace = None) → dict[source]

Locks/unlocks user accounts.

Can only be run by superusers and is suitable for use when called from a frontend.

Parameters:
  • payload (dict) –

    This is the input payload dict. Required items:

    • user_id: int, user ID of a superuser
    • user_role: str, == ‘superuser’
    • session_token: str, session token of superuser
    • target_userid: int, the user to lock/unlock
    • action: str {‘unlock’,’lock’}

    In addition to these items received from an authnzerver client, the payload must also include the following keys (usually added in by a wrapping function):

    • reqid: int or str
    • pii_salt: str
  • raiseonfail (bool) – If True, will raise an Exception if something goes wrong.
  • override_authdb_path (str or None) – If given as a str, is the alternative path to the auth DB.
  • config (SimpleNamespace object or None) – An object containing systemwide config variables as attributes. This is useful when the wrapping function needs to pass in some settings directly from environment variables.
Returns:

The dict returned is of the form:

{'success': True or False,
 'user_info': dict, with new user info,
 'messages': list of str messages if any}

Return type:

dict

authnzerver.actions.admin.user_info_columns(table: sqlalchemy.sql.expression.table) → Tuple[source]

Returns the column expression for all required info retrieved by a user lookup.

table is the users SQLAlchemy table object. Required to preserve type information for the columns.