Mapping#

The classes describing how SCIM resources are stored in SQLAlchemy models, and the function generating them from the resource types.

class scim2_sqlalchemy.ResourceMapping(model, record, attributes, *, version)[source]#

How the resources of a SCIM model are stored in the records of a SQLAlchemy model.

The paths are checked against the SCIM model when the mapping is created, so a mistake raises at import time rather than at the first request.

Parameters:
Raises:

ValueError – When a path is not valid for the model, or when a value does not fit the attribute of its path.

schemas()[source]#

Return the schemas of the resources, restricted to what the mapping stores.

They hold the mapped attributes only, and an attribute the mapping reads but never writes is readOnly. Publish them, rather than the schemas of model, so that clients know what the server stores: build the provider of the server with ScimProvider.from_discovery, and pass it to the storage.

Returns:

The schema of the resource, then the schemas of its extensions.

Return type:

list[Schema]

class scim2_sqlalchemy.Attribute(expression, *, readable=True, writable=True)[source]#

A column holding a SCIM attribute that the storage only reads, or only writes.

To store a value in another form, map the attribute to a hybrid_property that converts it, in Python and in SQL.

Parameters:
  • expression (Any) – The column, or the hybrid_property, holding the value.

  • readable (bool) – Whether the storage reads the attribute. When False, the attribute is write-only, such as a password: the storage never returns it, nor filters or sorts on it.

  • writable (bool) – Whether the storage writes the attribute. When False, the attribute is read-only.

class scim2_sqlalchemy.Hashed(hash_value, length=None)[source]#

A column type storing the hash of a string, such as a password.

The column stores what the hash function returns for the value written. Map it with readable=False, since the storage cannot read a hash back.

Parameters:
  • hash_value (Callable[[str], str]) – The function hashing a value.

  • length (int | None) – The length of the column.

class scim2_sqlalchemy.Many(relationship, attributes)[source]#

The entries of a multi-valued attribute, stored in a child table.

The entries belong to the resource: writing the resource replaces them. The relationship needs cascade="all, delete-orphan" (delete-orphan). Its order_by gives the order of the entries. Without it, the order is the one the database returns. A sort uses the primary entry, or else the first one.

The entries of a multi-valued simple attribute, such as a list of strings, are the values of one column of the child table. The storage keeps their order and their duplicates.

Parameters:
  • relationship (Any) – The relationship() from the resource record to the entry records.

  • attributes (Mapping[str, Any] | Any) – The columns of the entry records, by sub-attribute name, such as "value" or "type". For a simple attribute, the column holding the values.

A complex attribute linking to other resources.

A multi-valued attribute, such as the members of a group, maps to a relationship holding several records. A single-valued one, such as the manager of an enterprise user, maps to a relationship holding one record.

value is the id of the linked resource. Its display name, the display or displayName sub-attribute, is the displayName of the linked resource when its mapping has one, or else its userName. Writing the resource changes the links, and never creates nor deletes the linked resources.

A Link links to the resources of one resource type. An attribute linking to several resource types, such as the members of a group holding users and groups, maps to a list of Links, one per resource type. The entries are read in the order of the list.

Parameters:
  • relationship (Any) – The relationship() from the resource record to the records of the linked resources.

  • resource_type (str) – The name of the resource type of the linked resources, as the storage knows it.

  • type (str | None) – The type sub-attribute of the entries, such as "User" for the members of a group, or "direct" for the groups of a user. A client may send it, and a write with another value is refused. Without it, the storage does not store type.

scim2_sqlalchemy.generate_mappings(provider, metadata, *, prefix='', store=_store_all, inverses=None)[source]#

Generate the tables and the mappings that store the resources of a provider.

Each resource type gets a table named after its endpoint, such as users. A simple attribute gets a column, a complex attribute holding a single value gets a column for each sub-attribute, and an extension gets columns prefixed by the name of its schema. A multi-valued attribute gets a child table, mapped with Many. A complex attribute whose $ref links to served resource types gets a Link for each of them.

A read-only attribute is not stored, except an inverse: it reads the links of the attribute it reverses, such as groups of a user, which reads the members of the groups. A multi-valued sub-attribute is not stored either, nor a write-only attribute other than a single string. A column holds NOT NULL for a required attribute of the core schema, and UNIQUE for an attribute unique on the server. The table and column names longer than 63 characters are shortened.

store decides how each attribute is kept. It receives the AttributeBinding of the attribute, and returns:

  • True, to store the attribute with the column type matching it;

  • False, not to store it: the published schemas leave it out;

  • a column type, such as Hashed, to store it in a column of this type. Only an attribute with a column of its own takes one: a simple attribute, a sub-attribute, or the values of a multi-valued simple attribute.

A write-only string, such as a password, is never stored in clear text: store gives it a column type that hashes it, or does not store it.

Pass the mappings to the storage, and create the tables with MetaData.create_all or a migration tool.

Parameters:
  • provider (ScimProvider) – The provider of the server, which gives the resource types and their models.

  • metadata (MetaData) – The MetaData the tables are added to.

  • prefix (str) – A prefix of the names of the tables.

  • store (Callable[[AttributeBinding], bool | TypeEngine]) – The function deciding how each attribute is kept. By default, every attribute is stored with the column type matching it.

  • inverses (Mapping[str, str] | None) – The read-only attributes reading the links of another attribute, by URN, in addition to groups of a user reversing members of a group.

Returns:

The mappings, by resource type name.

Raises:

ValueError – When store keeps a write-only string in clear text, when it gives a column type to an attribute without a column of its own, or when two attributes need the same column name.

Return type:

dict[str, ResourceMapping]