magpie.api.management.register.register_utils

Attributes

CONTENT_TYPE_JSON

LOGGER

Classes

Group

Mixin for Group model

TemporaryToken

Model that defines a token for temporary URL completion of a given pending operation.

TokenOperation

Supported operations by the temporary tokens.

UserPending

Temporary definition of a User pending for approval by an administrator.

UserSearchService

Extends the ziggurat_foundations UserService with additional features provided by Magpie.

UserStatuses

Values applicable to User statues.

BaseViews

Base methods for Magpie UI pages.

Functions

get_email_template(→ mako.template.Template)

Retrieves the template file with email content matching the custom application setting or the corresponding default.

send_email(→ bool)

Send email notification using provided template and parameters.

generate_callback_url(→ magpie.typedefs.Str)

Generates a callback URL using Magpie temporary tokens for use by the webhook implementation.

webhook_update_error_status(→ None)

Updates the user's status to indicate an error occurred with the webhook requests.

get_constant(→ magpie.typedefs.SettingValue)

Search in order for matched value of constant_name:

get_logger(→ logging.Logger)

Immediately sets the logger level to avoid duplicate log outputs from the root logger and this logger when

get_magpie_url(→ magpie.typedefs.Str)

Obtains the configured Magpie URL entrypoint based on the various combinations of supported configuration settings.

handle_temporary_token(...)

Handles the operation according to the provided temporary token.

get_discoverable_groups(→ List[magpie.models.Group])

Get all existing group that are marked as publicly discoverable from the database.

get_discoverable_group_by_name(→ magpie.models.Group)

Obtains the requested discoverable group by name.

register_pending_user(...)

Registers a temporary user pending approval.

handle_user_registration_confirmation(...)

Applies the appropriate step of the user registration workflow following reception of the confirmation URL visit.

request_admin_approval(→ None)

Sends the email to the administrator to approve or refuse the Pending User registration.

handle_user_registration_admin_decision(...)

Applies the appropriate operation according to the decision the administrator took for the pending registration.

complete_user_registration(→ None)

Completes the successful user registration following any required validation steps.

Module Contents

magpie.api.management.register.register_utils.get_email_template(template_constant: magpie.typedefs.Str, container: magpie.typedefs.AnySettingsContainer | None = None) mako.template.Template[source]

Retrieves the template file with email content matching the custom application setting or the corresponding default.

Allowed values of template_constant are:

Raises:

IOError – if an explicit override value of the requested template cannot be located.

Returns:

template formatter from the requested template file.

magpie.api.management.register.register_utils.send_email(recipient: magpie.typedefs.Str, container: magpie.typedefs.AnySettingsContainer, template: mako.template.Template, parameters: TemplateParameters | None = None) bool[source]

Send email notification using provided template and parameters.

The preparation steps of the email (retrieve SMTP configuration, setup the SMTP connection, define email content parameters and attempt template generation) will directly raise if invalid as they correspond to incorrect application code or configuration settings.

Following step to send the email with the established SMTP connection is caught and logged if raising an exception. This is to allow the calling operation to ignore failing email notification and act accordingly using the resulting email status.

Parameters:
  • recipient – Email address of the intended recipient to which the email must be sent.

  • template – Mako template used for the email contents.

  • container – Any container to retrieve application settings.

  • parameters – Parameters to provide for templating email contents. They are applied on top of various defaults values provided to all emails.

Raises:

any SMTP server configuration, template generator or parameter parsing error for email setup.

Returns:

success status of the notification email (sent without error, no guarantee of reception).

magpie.api.management.register.register_utils.generate_callback_url(operation: magpie.models.TokenOperation, db_session: sqlalchemy.orm.session.Session, user: magpie.models.AnyUser | None = None, group: magpie.models.Group | None = None) magpie.typedefs.Str[source]

Generates a callback URL using Magpie temporary tokens for use by the webhook implementation.

Parameters:
  • operation – targeted operation that employs the callback URL for reference.

  • db_session – database session to store the generated temporary token.

  • user – user reference associated to the operation as applicable.

  • group – group reference associated to the operation as applicable.

Returns:

generated callback URL.

magpie.api.management.register.register_utils.webhook_update_error_status(user_name: magpie.typedefs.Str) None[source]

Updates the user’s status to indicate an error occurred with the webhook requests.

magpie.api.management.register.register_utils.get_constant(constant_name: magpie.typedefs.Str, settings_container: magpie.typedefs.AnySettingsContainer | None = None, settings_name: magpie.typedefs.Str | None = None, default_value: magpie.typedefs.SettingValue | None = None, raise_not_set: bool = True, raise_missing: bool = True, print_missing: bool = False, empty_missing: bool = False) magpie.typedefs.SettingValue[source]
Search in order for matched value of constant_name:
  1. search in MAGPIE_CONSTANTS

  2. search in settings if specified

  3. search alternative setting names (see below)

  4. search in magpie.constants definitions

  5. search in environment variables

Parameter constant_name is expected to have the format MAGPIE_[VARIABLE_NAME] although any value can be passed to retrieve generic settings from all above-mentioned search locations.

If settings_name is provided as alternative name, it is used as is to search for results if constant_name was not found. Otherwise, magpie.[variable_name] is used for additional search when the format MAGPIE_[VARIABLE_NAME] was used for constant_name (i.e.: MAGPIE_ADMIN_USER will also search for magpie.admin_user and so on for corresponding constants).

Parameters:
  • constant_name – key to search for a value

  • settings_container – WSGI application settings container (if not provided, uses found one in current thread)

  • settings_name – alternative name for settings if specified

  • default_value – default value to be returned if not found anywhere, and exception raises are disabled.

  • raise_not_set – raise an exception if the found key is None, search until last case if others are None

  • raise_missing – raise exception if key is not found anywhere

  • print_missing – print message if key is not found anywhere, return None

  • empty_missing – consider an empty value for an existing key as if it was missing (i.e.: as if not set).

Returns:

found value or default_value

Raises:
  • ValueError – if resulting value is invalid based on options (by default raise missing/empty/None value)

  • LookupError – if no appropriate value could be found from all search locations (according to options)

class magpie.api.management.register.register_utils.Group[source]

Bases: ziggurat_foundations.models.group.GroupMixin, Base

Mixin for Group model

_priority = None
get_member_count(db_session: sqlalchemy.orm.session.Session | None = None) int[source]
property discoverable
Indicates if the group is discoverable for users to self-register to it.
property terms
Text containing the terms and conditions.
property priority: magpie.typedefs.GroupPriority

Sorting priority weight of the group for resolving conflicting permissions.

class magpie.api.management.register.register_utils.TemporaryToken(*_, **__)[source]

Bases: ziggurat_foundations.models.base.BaseModel, Base

Model that defines a token for temporary URL completion of a given pending operation.

__tablename__ = 'tmp_tokens'
token
operation
created
user_id
_user
user_pending_id
_pending_user
group_id
group
user() AnyUser[source]
url(settings: magpie.typedefs.AnySettingsContainer = None) magpie.typedefs.Str[source]
expired() bool[source]
static by_token(token: magpie.typedefs.Str | sqlalchemy.dialects.postgresql.UUID, db_session: sqlalchemy.orm.session.Session | None = None) TemporaryToken | None[source]
static by_user(user: AnyUser, db_session: sqlalchemy.orm.session.Session | None = None) sqlalchemy.orm.query.Query | None[source]
json() magpie.typedefs.JSON[source]
class magpie.api.management.register.register_utils.TokenOperation[source]

Bases: magpie.utils.ExtendedEnum

Supported operations by the temporary tokens.

GROUP_ACCEPT_TERMS = 'group-accept-terms'

Temporary token associated to an URL endpoint called by a user that accepts the terms and conditions (T&C) to join a particular group.

USER_PASSWORD_RESET = 'user-password-reset'

Temporary token associated to an URL endpoint to request a user password reset.

USER_REGISTRATION_CONFIRM_EMAIL = 'user-registration-confirm-email'

Temporary token associated to a pending user registration that requires email validation by visiting the link.

USER_REGISTRATION_ADMIN_APPROVE = 'user-registration-admin-approve'

Temporary token associated to a pending user registration that will be approved by an administrator when visited.

USER_REGISTRATION_ADMIN_DECLINE = 'user-registration-admin-decline'

Temporary token associated to a pending user registration that will be declined by an administrator when visited.

WEBHOOK_USER_STATUS_ERROR = 'webhook-user-status-error'

Temporary token employed to provide a callback URL that a registered webhook can call following the triggered event to indicate that the corresponding operation resulted into an invalid user status.

class magpie.api.management.register.register_utils.UserPending[source]

Bases: Base

Temporary definition of a User pending for approval by an administrator.

property __tablename__
property id
Unique identifier of user.
property user_name
Unique user name.
property user_password
Password hash of the user.
property email
Email of the user.
property registered_date
Date of user's registration.
property status
Pending user status is enforced.

Avoid error in case the corresponding attribute of User was accessed.

property groups
Pending user is not a member of any group.

Avoid error in case this field gets accessed when simultaneously handling User and :class`UserPending`.

get_groups_by_status(status: UserGroupStatus, db_session: sqlalchemy.orm.session.Session = None) List[magpie.typedefs.Str][source]

Pending user is not a member of any group.

Avoid error in case this method gets accessed when simultaneously handling User and :class`UserPending`.

upgrade(db_session: sqlalchemy.orm.session.Session | None = None) User[source]

Upgrades this :class`UserPending` instance to a complete and corresponding User definition.

Automatically handles instance updates in the database. All relevant User metadata is transferred from available UserPending details.

All operations that should take place during normal User creation will take effect, including minimal Group membership creation and Webhook triggers.

This current UserPending instance is finally removed and should not be accessed following upgrade.

Parameters:

db_session – Database connection to use, otherwise retrieved from the user pending object.

Returns:

created user instance

property passwordmanager
Employ the same password manager attached to :class:`User` instances from :class:`UserService`.

This allows all functionalities of password generation, encryption and comparison to be directly transferable between this pending user until it eventually gets upgraded to a full User once validated.

class magpie.api.management.register.register_utils.UserSearchService[source]

Bases: ziggurat_foundations.models.services.user.UserService

Extends the ziggurat_foundations UserService with additional features provided by Magpie.

Note

For any search result where parameter status is equal to or contains UserStatuses.Pending combined with any other UserStatuses members, or through the all representation, the returned iterable could be a mix of both User models or only UserPending. Therefore, only fields supported by both of those models should be accessed from the result.

classmethod by_status(status: UserStatuses | None = None, db_session: sqlalchemy.orm.session.Session | None = None) Iterable[AnyUser][source]

Search for appropriate User and/or UserPending according to specified UserStatuses.

When the status is None, normal retrieval of all non-pending User is executed, as if directly using the UserService implementation. Otherwise, a combination of appropriate search criterion is executed based on the status flags.

classmethod by_user_name(user_name: magpie.typedefs.Str, status: UserStatuses | None = None, db_session: sqlalchemy.orm.session.Session | None = None) AnyUser | None[source]

Retrieves the user matching the given name.

Search is always accomplished against User table unless UserStatuses.Pending is provided in the status. If more that one status is provided such that both UserPending and User could yield results, the User is returned first, as there should not be any conflict between those two models.

classmethod by_name_or_email(user_name: magpie.typedefs.Str, email: magpie.typedefs.Str, status: UserStatuses | None = None, db_session: sqlalchemy.orm.session.Session | None = None) AnyUser | None[source]

Retrieves the first matched user by either name or email, whichever comes first.

If the status is provided, search is executed against relevant User and/or :class`UserPending` definitions. The user_name is looked for first across both tables (as needed) and then by email if not previously matched.

See also

by_user_name() by_email() by_email_and_username()

class magpie.api.management.register.register_utils.UserStatuses[source]

Bases: enum.IntFlag, magpie.utils.FlexibleNameEnum

Values applicable to User statues.

Provides allowed values for the status search query of User and UserPending entries. Also, defines the possible values of User.status field, omitting UserStatuses.Pending reserved for objects defined by UserPending.

Initialize self. See help(type(self)) for accurate signature.

OK = 1
WebhookError = 2
Pending = 4
classmethod _get_one(status: AnyUserStatus) UserStatuses | None[source]
classmethod get(status: None | int | magpie.typedefs.Str | UserStatuses | Iterable[None, int, magpie.typedefs.Str, UserStatuses], default: UserStatuses | None = None) UserStatuses | None[source]

Obtains the combined flag UserStatuses

classmethod allowed() List[None | int | magpie.typedefs.Str][source]

Returns all supported representation values that can be mapped to a valid status for UserSearchService.

classmethod all() UserStatuses[source]

Representation of all flags combined.

__or__(other: UserStatuses | int) UserStatuses[source]

Return self|value.

__and__(other: UserStatuses | int) UserStatuses[source]

Return self&value.

__xor__(other: UserStatuses | int) UserStatuses[source]

Return self^value.

__iter__() Iterable[UserStatuses][source]
__len__()[source]
class magpie.api.management.register.register_utils.BaseViews(request)[source]

Bases: object

Base methods for Magpie UI pages.

MAGPIE_FIXED_GROUP_MEMBERSHIPS = []

Special Group memberships that cannot be edited.

MAGPIE_FIXED_GROUP_EDITS = []

Special Group details that cannot be edited.

MAGPIE_FIXED_USERS = []

Special User details that cannot be edited.

MAGPIE_FIXED_USERS_REFS = []

Special User that cannot have any relationship edited.

This includes both Group memberships and Permission references.

MAGPIE_USER_PWD_LOCKED = []

Special User that could self-edit themselves, but is disabled since conflicting with other policies.

MAGPIE_USER_PWD_DISABLED = []

Special User where password cannot be edited (managed by Magpie configuration settings).

MAGPIE_ANONYMOUS_GROUP = None

Reference to magpie.constants.MAGPIE_ANONYMOUS_GROUP for convenience in UI pages.

add_template_data(data: Dict[magpie.typedefs.Str, Any] | None = None) Dict[magpie.typedefs.Str, Any][source]

Adds required template data for the ‘heading’ mako template applied to every UI page.

render(template: magpie.typedefs.Str, data: Dict[magpie.typedefs.Str, Any] | None = None) pyramid.response.Response[source]

Render the response with an explicit Mako template reference.

Views that are decorated by pyramid.view.view_config() or registered by pyramid.config.Configurator.add_view() with a renderer parameter do not require to call this function as it is auto-resolved with the submitted data.

magpie.api.management.register.register_utils.CONTENT_TYPE_JSON = 'application/json'[source]
magpie.api.management.register.register_utils.get_logger(name: magpie.typedefs.Str, level: int | None = None, force_stdout: bool = None, message_format: magpie.typedefs.Str | None = None, datetime_format: magpie.typedefs.Str | None = None) logging.Logger[source]

Immediately sets the logger level to avoid duplicate log outputs from the root logger and this logger when level is logging.NOTSET.

magpie.api.management.register.register_utils.get_magpie_url(container: magpie.typedefs.AnySettingsContainer | None = None) magpie.typedefs.Str[source]

Obtains the configured Magpie URL entrypoint based on the various combinations of supported configuration settings.

See also

Documentation section Application Settings for available setting combinations.

Parameters:

container – container that provides access to application settings.

Returns:

resolved Magpie URL

magpie.api.management.register.register_utils.LOGGER[source]
magpie.api.management.register.register_utils.handle_temporary_token(tmp_token: magpie.models.TemporaryToken, request: pyramid.request.Request) pyramid.httpexceptions.HTTPException | pyramid.response.Response[source]

Handles the operation according to the provided temporary token.

Returns:

Basic JSON response with successful indicate of correct handling of the token by default. If overridden, can be any HTML rendered response.

magpie.api.management.register.register_utils.get_discoverable_groups(db_session: sqlalchemy.orm.session.Session) List[magpie.models.Group][source]

Get all existing group that are marked as publicly discoverable from the database.

magpie.api.management.register.register_utils.get_discoverable_group_by_name(group_name: magpie.typedefs.Str, db_session: sqlalchemy.orm.session.Session) magpie.models.Group[source]

Obtains the requested discoverable group by name.

Note

For security reason, an existing group that is NOT discoverable will return NotFound instead of Forbidden. Otherwise we give an indication to a potentially non-admin user that some group of that name exists.

Returns:

found group matched by name

Raises:

HTTPNotFound – if the group cannot be found or if matched group name is not discoverable.

magpie.api.management.register.register_utils.register_pending_user(user_name: magpie.typedefs.Str, email: magpie.typedefs.Str, password: magpie.typedefs.Str, request: pyramid.request.Request) pyramid.httpexceptions.HTTPException[source]

Registers a temporary user pending approval.

Procedure and validation workflow is similar to normal user creation by an administrator, but employs reduced fields and different target table. Some operations are also simplified as they are not required for pending user. There is also no user creation Webhook triggers as User doesn’t exist yet.

See also

See magpie.api.management.user.user_utils.create_user() for similarities and distinctions of operations between a normal User and a Pending User.

Implements steps (1) and (2) of the user registration procedure.

See also

Returns:

HTTP created with relevant details if successful.

Raises:

HTTPException – HTTP error with relevant details upon any failing condition.

magpie.api.management.register.register_utils.handle_user_registration_confirmation(tmp_token: magpie.models.TemporaryToken, request: pyramid.request.Request) pyramid.response.Response[source]

Applies the appropriate step of the user registration workflow following reception of the confirmation URL visit.

Implements steps (3A) and (3B) redirection of the user registration procedure. Generates the appropriate response that will be displayed to the Pending User that confirmed its email.

See also

  • See proc_user_registration for the procedure step details.

  • See request_admin_approval for step 3B.

  • See complete_user_registration for step 5 (from 3A).

magpie.api.management.register.register_utils.request_admin_approval(tmp_token: magpie.models.TemporaryToken, request: pyramid.request.Request) None[source]

Sends the email to the administrator to approve or refuse the Pending User registration.

Implements step (3B) of the user registration procedure.

See also

  • See proc_user_registration for the procedure step details.

magpie.api.management.register.register_utils.handle_user_registration_admin_decision(tmp_token: magpie.models.TemporaryToken, request: pyramid.request.Request) pyramid.response.Response[source]

Applies the appropriate operation according to the decision the administrator took for the pending registration.

  • approved: Moves to step (5)

  • declined: Removes the pending user request.

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

Implements step (4) of the user registration procedure.

See also

magpie.api.management.register.register_utils.complete_user_registration(tmp_token: magpie.models.TemporaryToken, approval_required: bool, request: pyramid.request.Request) None[source]

Completes the successful user registration following any required validation steps.

Generates the User from the Pending User. Then, sends configured notification emails about successful User creation.

Implements steps (5) and (6) of the user registration procedure.

See also