magpie.api.management.user.user_utils

Attributes

LOGGER

USERNAME_REGEX

Functions

create_user(→ pyramid.httpexceptions.HTTPException)

Creates a User if it is permitted and not conflicting with existing ones.

update_user(→ None)

Applies updates of user details with specified values after validation.

create_user_resource_permission_response(...)

Creates a permission on a user/resource combination if it is permitted, and optionally not conflicting.

assign_user_group(→ None)

Creates a user-group relationship (user membership to a group).

send_group_terms_email(...)

Sends an email for terms and conditions confirmation.

create_pending_or_assign_user_group(...)

Associates the pending user or existing user to the group.

handle_user_group_terms_confirmation(...)

Handles the confirmation of a user to accept the terms and conditions of a group.

delete_user_group(→ None)

Deletes a user-group relationship (user membership to a group).

delete_user_resource_permission_response(...)

Get validated response on deleted user resource permission.

get_similar_user_resource_permission(...)

Obtains the user service/resource permission that corresponds to the provided one.

get_user_resource_permissions(...)

Retrieves user resource permissions applied directly, with inherited group permissions, or resolve between them.

get_user_resource_permissions_response(...)

Retrieves user resource permissions with or without inherited group permissions.

get_user_services(→ magpie.typedefs.UserServicesType)

Returns services by type with corresponding services by name containing sub-dict information.

get_user_service_permissions(...)

Retrieve the permissions the user has directly on a service or inherited permissions by its group memberships.

filter_user_permission(...)

Retrieves only user Direct Permissions amongst a list of user/group resource/service permissions.

resolve_user_group_permissions(...)

Reduces overlapping user Inherited Permission for corresponding resources/services amongst the given list.

regroup_permissions_by_resource(...)

Regroups multiple uncategorized permissions into a dictionary of corresponding resource IDs.

get_user_resources_permissions_dict(...)

Creates a dictionary of resources ID with corresponding permissions of the user.

get_user_service_resources_permissions_dict(...)

Retrieves all permissions the user has for every Resource nested under the Service.

check_user_info(→ None)

Validates provided user information to ensure they are adequate for user creation.

check_user_editable(→ None)

Verify if the specified user is allowed to receive modifications (to it directly or any resource referring to it).

get_user_groups_checked(→ List[magpie.typedefs.Str])

Obtains the validated list of group names from a pre-validated user.

Module Contents

magpie.api.management.user.user_utils.LOGGER[source]
magpie.api.management.user.user_utils.USERNAME_REGEX[source]
magpie.api.management.user.user_utils.create_user(user_name: magpie.typedefs.Str, password: magpie.typedefs.Str | None, email: magpie.typedefs.Str, group_name: magpie.typedefs.Str | None, db_session: sqlalchemy.orm.session.Session, **extra_fields) pyramid.httpexceptions.HTTPException[source]

Creates a User if it is permitted and not conflicting with existing ones.

Password must be set to None if using an external identity or skip its encrypted value generation.

Created User will immediately be assigned membership to the group matching group_name (can be MAGPIE_ANONYMOUS_GROUP for minimal access). If no group is provided, this anonymous group will be applied by default, creating a user effectively without any permissions other than ones set directly for him and inherited from Public Access.

Furthermore, the User always gets associated with MAGPIE_ANONYMOUS_GROUP (if not already explicitly or implicitly requested with group_name) to allow access to resources with public permission. This means that when group_name is provided with another name than MAGPIE_ANONYMOUS_GROUP, the User will have two memberships initially.

Argument group_name MUST be an existing group if provided.

Note

In order to properly handle subscribed Webhook that could request to change the user status to an error following a failing external operation, the created user is immediately committed. This way, following requests will have access to the instance from the database. Because of this requirement, any operation that desire an handle to the created User instance should retrieve it again from the database session.

Parameters:
  • user_name – Unique name of the user to validate and employ for creation.

  • password – Raw password of the user to validate and employ for creation. If Skipped if None. Otherwise, apply hash encryption on the value.

  • email – User email to be validated and employed for creation.

  • group_name – Group name to associate the user with at creation time.

  • db_session – database connection.

  • extra_fields – Additional fields that should be set for the user. Must be known properties of the instance.

Returns:

valid HTTP response on successful operation, or the User when requested.

magpie.api.management.user.user_utils.update_user(user: magpie.models.User, request: pyramid.request.Request, new_user_name: magpie.typedefs.Str | None = None, new_password: magpie.typedefs.Str | None = None, new_email: magpie.typedefs.Str | None = None, new_status: magpie.models.UserStatuses | None = None) None[source]

Applies updates of user details with specified values after validation.

Parameters:
  • user – targeted user to update .

  • request – request that produced this update operation.

  • new_user_name – new name to apply (if provided).

  • new_password – new password to apply (if provided).

  • new_email – new email to apply (if provided).

  • new_status – new status to apply (if provided).

Returns:

None if update was successful.

magpie.api.management.user.user_utils.create_user_resource_permission_response(user: magpie.models.User, resource: magpie.typedefs.ServiceOrResourceType, permission: magpie.permissions.PermissionSet, db_session: sqlalchemy.orm.session.Session, overwrite: bool = False) pyramid.httpexceptions.HTTPException[source]

Creates a permission on a user/resource combination if it is permitted, and optionally not conflicting.

Parameters:
  • user – user for which to create/update the permission.

  • resource – service or resource for which to create the permission.

  • permission – permission with modifiers to be applied.

  • db_session – database connection.

  • overwrite – If the corresponding (user, resource, permission[name]) exists, there is a conflict. Conflict is considered only by permission-name regardless of other modifiers. If permissions match exactly (including modifiers), conflict is raised regardless of overwrite value. If overwrite is False, the conflict will be raised and not be applied. If overwrite is True, the permission modifiers will be replaced by the new ones, or created if missing.

Returns:

valid HTTP response on successful operation.

magpie.api.management.user.user_utils.assign_user_group(user: magpie.models.User, group: magpie.models.Group, db_session: sqlalchemy.orm.session.Session) None[source]

Creates a user-group relationship (user membership to a group).

Returns:

nothing - user-group is created.

Raises:

HTTPError – corresponding error matching problem encountered.

magpie.api.management.user.user_utils.send_group_terms_email(user: magpie.models.User, group: magpie.models.Group, db_session: sqlalchemy.orm.session.Session) pyramid.httpexceptions.HTTPSuccessful[source]

Sends an email for terms and conditions confirmation.

Terms and conditions email are sent in the case of a request for the creation of a user-group relationship where the group requires a terms and conditions confirmation.

Returns:

valid HTTP response on successful operations.

Raises:

HTTPError – corresponding error matching problem encountered.

magpie.api.management.user.user_utils.create_pending_or_assign_user_group(user: magpie.models.User, group: magpie.models.Group, db_session: sqlalchemy.orm.session.Session) pyramid.httpexceptions.HTTPSuccessful[source]

Associates the pending user or existing user to the group.

Creates either a new user-group relationship (user membership to a group) or a pending terms and conditions confirmation. If the group requires a T&C confirmation, sends an email for T&C confirmation, else, the user is assigned directly to the group.

Returns:

valid HTTP response on successful operations.

Raises:

HTTPError – corresponding error matching problem encountered.

magpie.api.management.user.user_utils.handle_user_group_terms_confirmation(tmp_token: magpie.models.TemporaryToken, request: pyramid.request.Request) pyramid.response.Response[source]

Handles the confirmation of a user to accept the terms and conditions of a group.

Generates the appropriate response that will be displayed to the user.

magpie.api.management.user.user_utils.delete_user_group(user: magpie.models.User, group: magpie.models.Group, db_session: sqlalchemy.orm.session.Session) None[source]

Deletes a user-group relationship (user membership to a group).

Returns:

nothing - user-group is deleted.

Raises:

HTTPNotFound – if the combination cannot be found.

magpie.api.management.user.user_utils.delete_user_resource_permission_response(user: magpie.models.User, resource: magpie.typedefs.ServiceOrResourceType, permission: magpie.permissions.PermissionSet, db_session: sqlalchemy.orm.session.Session, similar: bool = True) pyramid.httpexceptions.HTTPException[source]

Get validated response on deleted user resource permission.

Parameters:
  • user – user for which to delete the permission.

  • resource – service or resource for which to delete the permission.

  • permission – permission with modifiers to be deleted.

  • db_session – database connection.

  • similar – Allow matching provided permission against any similar database permission. Otherwise, must match exactly.

Returns:

valid HTTP response on successful operations.

Raises:

HTTPException – error HTTP response of corresponding situation.

magpie.api.management.user.user_utils.get_similar_user_resource_permission(user: magpie.models.User, resource: magpie.typedefs.ServiceOrResourceType, permission: magpie.permissions.PermissionSet, db_session: sqlalchemy.orm.session.Session) magpie.permissions.PermissionSet | None[source]

Obtains the user service/resource permission that corresponds to the provided one.

Lookup considers only similar applied permission such that other permission modifiers don’t affect comparison.

magpie.api.management.user.user_utils.get_user_resource_permissions(user: magpie.models.User, resource: magpie.models.Resource, db_session: sqlalchemy.orm.session.Session, inherit: bool = False, resolve: bool = False) Tuple[List[magpie.permissions.PermissionSet], magpie.permissions.PermissionType, bool][source]

Retrieves user resource permissions applied directly, with inherited group permissions, or resolve between them.

Parameters:
  • user – user for which to retrieve permissions for the resource, and optionally its groups as well.

  • resource – resource for which permissions to retrieve are applied on.

  • db_session – database session

  • inherit – obtain permissions with user’s group inheritance (duplicate permissions possible across user/groups)

  • resolve – resolve permissions across user/groups to obtain a single highest priority permission on resource.

magpie.api.management.user.user_utils.get_user_resource_permissions_response(user: magpie.models.User, resource: magpie.typedefs.ServiceOrResourceType, request: pyramid.request.Request, inherit_groups_permissions: bool = True, resolve_groups_permissions: bool = False, effective_permissions: bool = False) pyramid.httpexceptions.HTTPException[source]

Retrieves user resource permissions with or without inherited group permissions.

Alternatively retrieves the effective user resource permissions, where group permissions are implied as True.

Warning

Does not consider direct Resource ownership.

See also

Returns:

valid HTTP response on successful operations.

Raises:

HTTPException – error HTTP response of corresponding situation.

magpie.api.management.user.user_utils.get_user_services(user: magpie.models.User, request: pyramid.request.Request, cascade_resources: bool = False, format_as_list: bool = False, inherit_groups_permissions: bool = False, resolve_groups_permissions: bool = False, service_types: List[magpie.typedefs.Str] | None = None) magpie.typedefs.UserServicesType[source]

Returns services by type with corresponding services by name containing sub-dict information.

Parameters:
  • user – user for which to find services

  • request – request with database session connection

  • cascade_resources – If False, return only services which the User has Immediate Permissions on specialized top-level resources corresponding to a Service. Otherwise, return every service that has at least one sub-resource with permissions (children at any-level). In both cases, the permissions looked for consider either only Direct Permissions or any Inherited Permission according to the value of inherit_groups_permissions.

  • inherit_groups_permissions – If False, return only user-specific service/sub-resources Direct Permissions. Otherwise, resolve Inherited Permissions using all groups the user is member of.

  • resolve_groups_permissions – Whether to combine Direct Permissions and Inherited Permissions for respective resources or not.

  • format_as_list – Returns as list of service dict information (not grouped by type and by name)

  • service_types – Filter list of service types for which to return details. All service types are used if omitted.

Returns:

Only services which the user as Direct Permissions or considering all tree hierarchy, and for each case, either considering only user permissions or every Inherited Permission, according to provided options.

Return type:

Mapping of services by type to corresponding services by name containing each sub-mapping of their information, unless format_as_list is True, in which case a flat list of service information is returned.

magpie.api.management.user.user_utils.get_user_service_permissions(user: magpie.models.User, service: magpie.models.Service, request: pyramid.request.Request, inherit_groups_permissions: bool = True, resolve_groups_permissions: bool = False) List[magpie.permissions.PermissionSet][source]

Retrieve the permissions the user has directly on a service or inherited permissions by its group memberships.

Warning

magpie.api.management.user.user_utils.filter_user_permission(resource_permission_list: List[ziggurat_foundations.permissions.PermissionTuple], user: magpie.models.User) Iterable[ziggurat_foundations.permissions.PermissionTuple][source]

Retrieves only user Direct Permissions amongst a list of user/group resource/service permissions.

magpie.api.management.user.user_utils.resolve_user_group_permissions(resource_permission_list: List[magpie.typedefs.ResolvablePermissionType]) Iterable[magpie.permissions.PermissionSet][source]

Reduces overlapping user Inherited Permission for corresponding resources/services amongst the given list.

User Direct Permissions have the top-most priority and are therefore selected first if permissions are found for corresponding resource. In such case, only one entry is possible (it is invalid to have more than one combination of (User, Resource, Permission), including modifiers, as per validation during their creation).

Otherwise, for corresponding Inherited Permissions, resolve the prioritized Permission across every group. Similarly to users, magpie.groups.group_utils.get_similar_group_resource_permission() validate that only one combination of (Group, Resource, Permission) can exist including permission modifiers. Only, cross-group memberships for a given resource must then be computed.

Priority of combined group-only permissions follows 3 conditions:
  1. Permissions inherited from special group MAGPIE_ANONYMOUS_GROUP have lower priority than any other more explicit group membership, regardless of permission modifiers applied on it.

  2. Permissions of same group priority with Access.DENY are prioritized over Access.ALLOW.

  3. Permissions of same group priority with Scope.RECURSIVE are prioritized over Access.MATCH as they affect a larger range of resources when Effective Permissions are eventually requested.

Note

Resource tree inherited resolution is not considered here (no recursive Effective Permission computed). Only same-level scope of every given resource is processed independently. The intended behaviour here is therefore to help illustrate in responses how deep is a given permission going to have an impact onto lower-level resources, making Scope.RECURSIVE more important than specific instance Scope.MATCH.

See also

  • Sorting methods of magpie.permissions.PermissionSet that orders the permissions with desired result.

  • magpie.groups.group_utils.get_similar_group_resource_permission()

  • magpie.users.user_utils.get_similar_user_resource_permission()

magpie.api.management.user.user_utils.regroup_permissions_by_resource(resource_permissions: Iterable[magpie.typedefs.ResolvablePermissionType], resolve: bool = False) magpie.typedefs.ResourcePermissionMap[source]

Regroups multiple uncategorized permissions into a dictionary of corresponding resource IDs.

While regrouping the various permissions (both Direct Permissions and any amount of groups Inherited Permissions) under their respective resource by ID, optionally resolve overlapping or conflicting permissions by name such that only one permission persists for that resource and name.

Parameters:
  • resource_permissions – List of resource permissions to process. Can include both user Direct Permissions and its groups Inherited Permissions.

  • resolve – When False, only mapping by resource ID is accomplished. Full listing of permissions is returned. Otherwise, resolves the corresponding resource permissions (by same ID) considering various priority rules to obtain unique permission names per resource.

Returns:

resolved permission

magpie.api.management.user.user_utils.get_user_resources_permissions_dict(user: magpie.models.User, request: pyramid.request.Request, resource_types: List[magpie.typedefs.Str] | None = None, resource_ids: List[int] | None = None, inherit_groups_permissions: bool = True, resolve_groups_permissions: bool = False) magpie.typedefs.ResourcePermissionMap[source]

Creates a dictionary of resources ID with corresponding permissions of the user.

Parameters:
  • user – user for which to find resources permissions

  • request – request with database session connection

  • resource_types – filter the search query with only the specified resource types

  • resource_ids – filter the search query to only the specified resource IDs

  • inherit_groups_permissions – Whether to include group inherited permissions from user memberships or not. If False, return only user-specific resource permissions. Otherwise, resolve inherited permissions using all groups the user is member of.

  • resolve_groups_permissions – whether to combine corresponding user/group permissions into one or not.

Returns:

Only resources which the user has permissions on, or including all Inherited Permissions, according to inherit_groups_permissions argument.

magpie.api.management.user.user_utils.get_user_service_resources_permissions_dict(user: magpie.models.User, service: magpie.models.Service, request: pyramid.request.Request, inherit_groups_permissions: bool = True, resolve_groups_permissions: bool = False) magpie.typedefs.ResourcePermissionMap[source]

Retrieves all permissions the user has for every Resource nested under the Service.

The retrieved permissions can either include only Direct Permissions or a combination of user and group Inherited Permissions accordingly to provided options.

Returns:

dictionary of resource IDs with corresponding permissions.

magpie.api.management.user.user_utils.check_user_info(user_name: magpie.typedefs.Str = None, email: magpie.typedefs.Str = None, password: magpie.typedefs.Str = None, group_name: magpie.typedefs.Str = None, check_name: bool = True, check_email: bool = True, check_password: bool = True, check_group: bool = True) None[source]

Validates provided user information to ensure they are adequate for user creation.

Using check_ prefixed arguments, individual field checks can be disabled (check all by default).

Raises:

HTTPException – appropriate error for the invalid field value or format that was checked as applicable.

Returns:

nothing if all enabled checks are successful.

magpie.api.management.user.user_utils.check_user_editable(user: magpie.models.User, container: magpie.typedefs.AnySettingsContainer) None[source]

Verify if the specified user is allowed to receive modifications (to it directly or any resource referring to it).

Parameters:
  • user – User to validate.

  • container – Any container to retrieve application settings.

Raises:

HTTPForbidden – When user is not allowed to be edited.

Returns:

Nothing if allowed edition.

magpie.api.management.user.user_utils.get_user_groups_checked(user: magpie.models.User, db_session: sqlalchemy.orm.session.Session) List[magpie.typedefs.Str][source]

Obtains the validated list of group names from a pre-validated user.