magpie.api.requests

Attributes

CONTENT_TYPE_JSON

LOGGER

Classes

PermissionSet

Explicit definition of a Permission with applicable Access and Scope to resolve it.

Functions

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

check_value(→ None)

Validates the value against specified type and pattern.

get_request_method_content(→ Dict[magpie.typedefs.Str, ...)

Obtain request content from property according to submitted method.

get_multiformat_body(→ Any)

Obtains the value of key element from the request body according to specified Content-Type header.

get_permission_multiformat_body_checked(...)

Retrieves the permission from the body and validates that it is allowed for the specified service or resource.

get_value_multiformat_body_checked(→ magpie.typedefs.Str)

Obtains and validates the matched value under key element from the request body.

get_principals(...)

Obtains the list of effective principals according to detected request session user.

has_admin_access(→ bool)

Verifies if the authenticated user doing the request has administrative access.

get_logged_user(→ Optional[magpie.models.User])

get_user(→ magpie.models.AnyUser)

Obtains the user corresponding to the provided user-name, token or via lookup of the logged user request session.

get_user_matchdict_checked_or_logged(...)

Obtains either the explicit or logged user specified in the request path variable.

get_user_matchdict_checked(→ magpie.models.AnyUser)

Obtains the user matched against the specified request path variable.

get_group_matchdict_checked(→ magpie.models.Group)

Obtains the group matched against the specified request path variable.

get_resource_matchdict_checked(→ magpie.models.Resource)

Obtains the resource matched against the specified request path variable.

get_service_matchdict_checked(→ magpie.models.Service)

Obtains the service matched against the specified request path variable.

get_permission_matchdict_checked(...)

Obtains the permission specified in the request path variable and validates that service_or_resource

get_value_matchdict_checked(→ magpie.typedefs.Str)

Obtains the matched value located at the expected position of the specified path variable.

get_query_param(→ Any)

Retrieves a query string value by name (case insensitive), or returns the default if not present.

Module Contents

magpie.api.requests.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.requests.PermissionSet(permission: magpie.typedefs.AnyPermissionType, access: Access | magpie.typedefs.Str | None = None, scope: Scope | magpie.typedefs.Str | None = None, typ: PermissionType | None = None, reason: magpie.typedefs.Str | None = None)[source]

Bases: object

Explicit definition of a Permission with applicable Access and Scope to resolve it.

The Permission is the name of the applicable permission on the magpie.models.Resource. The Scope defines how the Permission should impact the resolution of the perceived Effective Permissions over a magpie.models.Resource tree hierarchy. The Access defines how the Permission access should be interpreted (granted or denied).

Optionally, a PermissionType can be provided to specifically indicate which kind of permission this set represents. This type is only for informative purposes, and is not saved to database nor displayed by the explicit string representation. It is returned within JSON representation and can be employed by Effective Permissions resolution to be more verbose about returned results.

On missing Access or Scope specifications, they default to Access.ALLOW and Scope.RECURSIVE to handle backward compatible naming convention of plain permission_name.

Initializes the permission definition, possibly using required conversion from other implementations.

Parameters:
  • permission – Name of the permission, or any other implementation from which the name can be inferred.

  • access – Effective behaviour of the permissions. Generally, grant or deny the specified permission.

  • scope – Scope for which the permission affects hierarchical resources. Important for effective resolution.

  • typ – Type of permission being represented. Informative only, does not impact behavior if omitted.

  • reason – Slightly more indicative information on why the current permission-type has this value. Value should be either explicitly provided or will be inferred if converted from input PermissionTuple.

__slots__ = ['_name', '_access', '_scope', '_tuple', '_type', '_reason']
__eq__(other: Any) bool[source]

Return self==value.

__ne__(other: Any) bool[source]

Return self!=value.

__lt__(other: Any) bool[source]

Ascending sort of permission according to their name, access and scope modifiers.

First sort by permission name alphabetically, followed by increasing restrictive access and increasing range of scoped resources.

Using this sorting methodology, similar permissions by name are grouped together first, and permissions of same name with modifiers are then ordered, the first having less priority when selecting a single item to display with conflicting possibilities. Respecting Access.DENY is more important than Access.ALLOW (to protect the Resource), and Scope.MATCH is closer to the actual Resource than Scope.RECURSIVE permission received from a farther parent in the hierarchy.

Sorted explicit string representation becomes:

[name1]-[allow]-[match]
[name1]-[allow]-[recursive]
[name1]-[deny]-[match]
[name1]-[deny]-[recursive]
[name2]-[allow]-[match]
[name2]-[allow]-[recursive]
[name2]-[deny]-[match]
[name2]-[deny]-[recursive]
...
We then obtain two crucial ordering results:
  1. We can easily pick the last sorted item with highest resolution priority to find the final result of corresponding permissions. (note: final result for same user or group, their direct/inherited resolution is not considered here).

  2. Picking the first element with lowest priority also displays the permission that impacts the widest range of resources. For instance in Magpie UI, indicating that a permission as Scope.RECURSIVE is more verbose as it tell other resources under it are also receive the specified Access modifier rather than only the punctual resource.

Warning

Alphabetically sorting permissions by string representation (implicit/explicit) is not equivalent to sorting them according to Permission priority according to how modifiers are resolved. To obtain the prioritized sorting as strings, a list of PermissionSet (with the strings as input) should be used to convert and correctly interpreted the raw strings, and then be converted back after sorting.

# valid priority-sorted strings
[str(perm) for perm in sorted(PermissionSet(p) for p in permission_strings)]

# not equivalent to raw sorting
list(sorted(permission_strings))
__hash__() int[source]

Return hash(self).

__str__() magpie.typedefs.Str[source]

Obtains the compound literal representation of the PermissionSet.

Employed for database storage supporting ziggurat format.

__repr__() magpie.typedefs.Str[source]

Obtains the visual representation of the PermissionSet.

like(other: Any) bool[source]

Evaluates if one permission is similar to another permission definition regardless of modifiers.

This is different than == operator which will evaluate exactly equal permission definitions.

json() magpie.typedefs.PermissionDict[source]

Obtains the JSON representation of this PermissionSet.

webhook_params() magpie.typedefs.JSON[source]

Obtain JSON representation employed for Webhook reference.

ace(user_or_group: magpie.models.User | magpie.models.Group | None) magpie.typedefs.AccessControlEntryType[source]

Converts the PermissionSet into an ACE that pyramid can understand.

property reason: magpie.typedefs.Str | None

Indicative reason of the returned value defined by type() or inferred by the PermissionTuple.

See also

combine()

Returns:

Single string that describes the reason (source) of the permission, or multiple strings if updated by combination of multiple permissions.

classmethod resolve(permission1: magpie.typedefs.ResolvablePermissionType, permission2: magpie.typedefs.ResolvablePermissionType, context: PermissionType = PermissionType.INHERITED, multiple_choice: magpie.typedefs.Str | None = None) magpie.typedefs.ResolvablePermissionType[source]

Resolves provided permissions into a single one considering various modifiers and groups for a resource.

Permissions MUST have the same Permission name. The associated Resource on which the two compared permissions are applied on should also be the same This method SHOULD NOT be used by itself to obtain for Effective Permission since it does not handle multi-level Resource resolution. Resolution is accomplished in this case only for a given level in the tree hierarchy.

The comparison considers both the Access and Scope of every Inherited Permission of the User, as well as its Group memberships sorted by their priority.

See also

Parameters:
  • permission1 – Permission to compare.

  • permission2 – Permission to compare.

  • context – Control the resolution context (local/effective) of the permissions (safeguard against invalid definitions).

  • multiple_choice – Alternate explanation to default PERMISSION_REASON_MULTIPLE applied if multiple Permission refer to distinct Group of equal priority and equivalent access definitions, meaning they are interchangeable without impacting resolution to access the same target Resource.

Returns:

Permission with highest priority to resolve access a resource without considering scope.

property group_priority: magpie.typedefs.GroupPriority | None

Priority accessor in case of group inherited permission resolved by PermissionTuple.

property perm_tuple: ziggurat_foundations.permissions.PermissionTuple | None

Get the original PermissionTuple if available (PermissionSet must have been created by one).

property implicit_permission: magpie.typedefs.Str | None

Obtain the implicit string representation of the PermissionSet as plain Permission name.

This representation is backward compatible with prior versions of Magpie where explicit representation of permission names in the database did not exist.

If the contained modifiers of the PermissionSet (notably the Access.DENY) result in a string representation that is not possible according to non existing permissions for older Magpie instances, the returned value will be None.

See also

property explicit_permission: magpie.typedefs.Str

Obtain the explicit string representation of the PermissionSet.

This format is always guaranteed to be completely defined contrary to implicit_permission().

See also

property name: Permission
permission
property access: Access
property scope: Scope
property type: PermissionType | None
classmethod _convert(permission: magpie.typedefs.AnyPermissionType) PermissionSet | None[source]

Converts any permission representation to the PermissionSet with applicable enum members.

Supports older Permission representation such that implicit conversion of permission name without access and scope values are padded with defaults. Also, pre-defined partial or full definition from literal string representation are parsed to generate the PermissionSet instance.

Parameters:

permission – implicit or explicit permission name string, or any other known permission implementation

Raises:

ValueError – when the permission name cannot be identified or parsed

magpie.api.requests.CONTENT_TYPE_JSON = 'application/json'[source]
magpie.api.requests.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.requests.LOGGER[source]
magpie.api.requests.check_value(value: Any, param_name: magpie.typedefs.Str, check_type: Any = six.string_types, pattern: magpie.typedefs.Str | bool | None = ax.PARAM_REGEX) None[source]

Validates the value against specified type and pattern.

Parameters:
  • value – value to validate.

  • check_type – verify that parameter value is of specified type. Set to None to disable check.

  • pattern – regex pattern to validate the input with. If value evaluates to False, skip this kind of validation (default: ax.PARAM_REGEX).

  • param_name – path variable key.

Returns:

None.

Raises:

HTTPUnprocessableEntity – if the key is not an applicable path variable for this request.

magpie.api.requests.get_request_method_content(request: pyramid.request.Request) Dict[magpie.typedefs.Str, Any][source]

Obtain request content from property according to submitted method.

Requests with HTTP GET store content into GET property, while other methods are in POST property.

magpie.api.requests.get_multiformat_body(request: pyramid.request.Request, key: magpie.typedefs.Str, default: Any | None = None) Any[source]

Obtains the value of key element from the request body according to specified Content-Type header.

magpie.api.requests.get_permission_multiformat_body_checked(request: pyramid.request.Request, service_or_resource: magpie.typedefs.ServiceOrResourceType) magpie.permissions.PermissionSet[source]

Retrieves the permission from the body and validates that it is allowed for the specified service or resource.

Validation combines basic field checks followed by contextual values applicable for the service or resource. The permission can be provided either by literal string name (explicit or implicit format) or JSON object.

magpie.api.requests.get_value_multiformat_body_checked(request: pyramid.request.Request, key: magpie.typedefs.Str, default: Any = None, check_type: Any = six.string_types, pattern: magpie.typedefs.Str | bool | None = ax.PARAM_REGEX) magpie.typedefs.Str[source]

Obtains and validates the matched value under key element from the request body.

Parsing of the body is accomplished according to Content-Type header.

Parameters:
  • request – request from which to retrieve the key.

  • key – body key variable.

  • default – value to return instead if not found. If this default is None, it will raise.

  • check_type – verify that parameter value is of specified type. Set to None to disable check.

  • pattern – regex pattern to validate the input with. If value evaluates to False, skip this kind of validation (default: magpie.api.exception.PARAM_REGEX).

Returns:

matched path variable value.

Raises:
  • HTTPBadRequest – if the key could not be retrieved from the request body and has no provided default value.

  • HTTPUnprocessableEntity – if the retrieved value from the key is invalid for this request.

magpie.api.requests.get_principals(request: pyramid.request.Request) List[magpie.typedefs.AnyAccessPrincipalType][source]

Obtains the list of effective principals according to detected request session user.

magpie.api.requests.has_admin_access(request: pyramid.request.Request) bool[source]

Verifies if the authenticated user doing the request has administrative access.

Note

Any request view that does not explicitly override permission by another value than the default MAGPIE_ADMIN_PERMISSION will already automatically guarantee that the request user is an administrator since HTTP [403] Forbidden would have been otherwise replied. This method is indented for operations that are more permissive and require conditional validation of administrator access.

See also

Definitions in magpie.models.RootFactory and magpie.models.UserFactory define conditional principals and ACL based on the request.

magpie.api.requests.get_logged_user(request: pyramid.request.Request) magpie.models.User | None[source]
magpie.api.requests.get_user(request: pyramid.request.Request, user_name_or_token: magpie.typedefs.Str | None = None, user_status: magpie.models.UserStatuses | None = None) magpie.models.AnyUser[source]

Obtains the user corresponding to the provided user-name, token or via lookup of the logged user request session.

Parameters:
  • request – request from which to obtain application settings and session user as applicable.

  • user_name_or_token – reference value to employ for lookup of the user.

  • user_status – filter search based on a user status. Ignored if no user name or token is provided.

Returns:

found user.

Raises:
  • HTTPForbidden – if the requesting user does not have sufficient permission to execute this request.

  • HTTPNotFound – if the specified user name or token does not correspond to any existing user.

magpie.api.requests.get_user_matchdict_checked_or_logged(request: pyramid.request.Request, user_name_key: magpie.typedefs.Str = 'user_name', user_status: magpie.models.UserStatuses | None = None) magpie.models.AnyUser[source]

Obtains either the explicit or logged user specified in the request path variable.

:returns found user. :raises HTTPForbidden: if the requesting user does not have sufficient permission to execute this request. :raises HTTPNotFound: if the specified user name or logged user keyword does not correspond to any existing user.

magpie.api.requests.get_user_matchdict_checked(request: pyramid.request.Request, user_name_key: magpie.typedefs.Str = 'user_name', user_status: magpie.models.UserStatuses | None = None) magpie.models.AnyUser[source]

Obtains the user matched against the specified request path variable.

Returns:

found user.

Raises:
  • HTTPForbidden – if the requesting user does not have sufficient permission to execute this request.

  • HTTPNotFound – if the specified user name does not correspond to any existing user.

magpie.api.requests.get_group_matchdict_checked(request: pyramid.request.Request, group_name_key: magpie.typedefs.Str = 'group_name') magpie.models.Group[source]

Obtains the group matched against the specified request path variable.

Returns:

found group.

Raises:
  • HTTPForbidden – if the requesting user does not have sufficient permission to execute this request.

  • HTTPNotFound – if the specified group name does not correspond to any existing group.

magpie.api.requests.get_resource_matchdict_checked(request: pyramid.request.Request, resource_name_key: magpie.typedefs.Str = 'resource_id') magpie.models.Resource[source]

Obtains the resource matched against the specified request path variable.

Returns:

found resource.

Raises:
  • HTTPForbidden – if the requesting user does not have sufficient permission to execute this request.

  • HTTPNotFound – if the specified resource ID does not correspond to any existing resource.

magpie.api.requests.get_service_matchdict_checked(request: pyramid.request.Request, service_name_key: magpie.typedefs.Str = 'service_name') magpie.models.Service[source]

Obtains the service matched against the specified request path variable.

Returns:

found service.

Raises:
  • HTTPForbidden – if the requesting user does not have sufficient permission to execute this request.

  • HTTPNotFound – if the specified service name does not correspond to any existing service.

magpie.api.requests.get_permission_matchdict_checked(request: pyramid.request.Request, service_or_resource: magpie.models.Resource) magpie.permissions.PermissionSet[source]

Obtains the permission specified in the request path variable and validates that service_or_resource allows it.

The service_or_resource can be top-level service or a children resource.

Allowed permissions correspond to the direct service permissions or restrained permissions of the resource under its root service. The permission name can be provided either by implicit or explicit string representation.

Returns:

found permission name if valid for the service/resource

magpie.api.requests.get_value_matchdict_checked(request: pyramid.request.Request, key: magpie.typedefs.Str, check_type: Any = six.string_types, pattern: magpie.typedefs.Str | bool | None = ax.PARAM_REGEX) magpie.typedefs.Str[source]

Obtains the matched value located at the expected position of the specified path variable.

Parameters:
  • request – request from which to retrieve the key.

  • key – path variable key.

  • check_type – verify that parameter value is of specified type. Set to None to disable check.

  • pattern – regex pattern to validate the input with. If value evaluates to False, skip this kind of validation (default: ax.PARAM_REGEX).

Returns:

matched path variable value.

Raises:

HTTPUnprocessableEntity – if the key is not an applicable path variable for this request.

magpie.api.requests.get_query_param(request: pyramid.request.Request, case_insensitive_key: magpie.typedefs.Str | Iterable[magpie.typedefs.Str], default: Any | None = None) Any[source]

Retrieves a query string value by name (case insensitive), or returns the default if not present.