Module Contents



Define every property required to set a permission in Magpie.


A sync point contains services sharing resources via multiple APIs.


Keep service-shared resources in sync when permissions are updated for one of them.









cowbird.permissions_synchronizer.SEGMENT_NAME_REGEX = '[\\w:-]+'[source]
cowbird.permissions_synchronizer.RES_NAMETYPE_SEPARATOR = '::'[source]
cowbird.permissions_synchronizer.PERMISSION_DEFAULT_ACCESS = 'allow'[source]
cowbird.permissions_synchronizer.PERMISSION_DEFAULT_SCOPE = 'recursive'[source]
class cowbird.permissions_synchronizer.Permission(service_name: str, service_type: str, resource_id: int, resource_full_name: str, name: str, access: str, scope: str, user: str = None, group: str = None, resource_display_name: str = None)[source]

Define every property required to set a permission in Magpie.

__eq__(other: Permission) bool[source]

Return self==value.

get_full_permission_value() str[source]

Returns the full permission value, consisting of the name-access-scope values.

class cowbird.permissions_synchronizer.SyncPoint(services: cowbird.typedefs.SyncPointServicesType, permissions_mapping_list: cowbird.typedefs.SyncPointMappingType)[source]

A sync point contains services sharing resources via multiple APIs.

It defines how the same resource is defined in each service and what are the mapping between permission accesses.

Init the sync point, holding services with their respective resources root and how access are mapped between them.

  • services – Dict containing the resource keys by service type and all the names/types of each segment of those resource keys

  • permissions_mapping_list – List of strings representing a permission mapping between two resource keys

static _get_explicit_permission(permission: str) str[source]

Converts a permission that could use an implicit format (‘<name>’ or ‘<name>-match’) and converts it to use an explicit format (‘<name>-<access>-<scope>’).

_add_mapping(src_key: str, src_permissions: str, target_key: str, target_permissions: str) None[source]

Adds a source/target permission mapping to the object’s permissions mapping.

static _generate_regex_from_segments(res_segments: List[cowbird.typedefs.ConfigSegment]) Tuple[str, int][source]

Generates a regex for a resource_nametype_path (ex.: /name1::type1/name2::type2) from a list of segments.

Returns the regex along with the count of segments in the regex that are named. This count excludes tokenized segments.

static _generate_nametype_path_from_segments(res_segments: List[cowbird.typedefs.ConfigSegment], src_resource_tree: cowbird.typedefs.ResourceTree) str[source]

Generate nametype path (ex.: /name1::type1/name2::type2 where name can be a field found in ResourceSegment).

  • res_segments – list of segments

  • src_resource_tree – Resource tree associated with the permission to synchronize

static _remove_type_from_nametype_path(nametype_path: str) str[source]

Removes the type from a nametype path (ex.: /name1::type1/name2::type2 becomes /name1/name2).

_find_matching_res(permission: Permission, src_resource_tree: cowbird.typedefs.ResourceTree) Tuple[str, Collection[str] | Dict[str, str]][source]

Finds a resource key that matches the input resource path, in the sync_permissions config. Note that it returns the longest match and only the named segments of the path are included in the length value. Any tokenized segment is ignored in the length.

  • permission – Permission of the service associated with the input resource.

  • ResourceTree – Resource tree associated with the permission to synchronize

static _create_res_data(target_segments: List[cowbird.typedefs.ConfigSegment], input_matched_groups: Collection[str] | Dict[str, str]) List[cowbird.typedefs.ResourceSegment][source]

Creates resource data, by replacing any tokens found in the segment names to their actual corresponding values. This data includes the name and type of each segments of a full resource path. In the case where a regex is found in the target segment, the data will be formed using the same resource_type for every match in the current segment.

  • target_segments – List containing the name and type info of each segment of the target resource path.

  • input_matched_groups

_get_resource_full_name_and_type(res_key: str, matched_groups: Collection[str] | Dict[str, str]) Tuple[str, List[cowbird.typedefs.ResourceSegment]][source]

Finds the resource data from the config by using the resource key.

Returns the formatted resource data along with the related service name.

_get_src_permissions() Iterator[Tuple[str, str]][source]

Yields all source resource/permissions found in the mappings.

static _is_in_permissions(target_permission: str, svc_name: str, src_res_data: List[cowbird.typedefs.ResourceSegment], permissions: cowbird.typedefs.JSON) bool[source]

Checks if a target permission is found in a permissions dict.

The check is done by looking for the target permission’s resource path in the permissions dict.

_filter_used_targets(target_res_and_permissions: TargetResourcePermissions, input_src_res_key: str, src_matched_groups: Collection[str] | Dict[str, str], input_permission: Permission) Tuple[Dict[str, List[str]], Dict[str, List[str]]][source]

Filters a dictionary of target resource/permissions, keeping only the permissions which should actually be removed.

This is used for the deleted webhook event, where all target permissions should not necessarily be synced. Any target permission that is also a target permission in another mapping and where the source permission of that other mapping still exists, should not be synced yet, since it would destroy that other mapping. Ex.:

A -> C
B -> C


[A,B] -> C

If the A -> C mapping was triggered for a deleted webhook event, the C target permission should only be synced if both A and B permissions don’t exist.

_get_permission_data(user_targets: Dict[str, List[str]], group_targets: Dict[str, List[str]], src_matched_groups: Collection[str] | Dict[str, str], input_permission: Permission) cowbird.typedefs.PermissionData[source]

Formats permissions data to send to Magpie. Output contains, for each target resource key, the resource path (with the name of each segment and its corresponding type), and all the permissions to sync, defining for each permission, if it is on a user, a group, or both.

Output dict format :

{ <target_key>: {
    "res_path": [<list of segment names/types>],
    "permissions": { <permission_key>: [user, grp], ...}},
_prepare_permissions_to_remove(target_res_and_permissions: TargetResourcePermissions, input_permission: Permission, input_src_res_key: str, src_matched_groups: Collection[str] | Dict[str, str]) cowbird.typedefs.PermissionData[source]

Removes every source resource found in the mappings that has an existing permission that is synced to one of the input target permissions.

Used in the case of a deleted webhook event.

_find_permissions_to_sync(src_res_key: str, src_matched_groups: Collection[str] | Dict[str, str], input_permission: Permission, perm_operation: Callable[[List[cowbird.typedefs.PermissionConfigItemType]], None]) cowbird.typedefs.PermissionData[source]

Finds all permissions that should be synchronised with the source resource.

sync(perm_operation: Callable[[List[cowbird.typedefs.PermissionConfigItemType]], None], permission: Permission, src_resource_tree: cowbird.typedefs.ResourceTree) None[source]

Create or delete target permissions, that are mapped to the source resource that triggered the event.

  • perm_operation – Magpie create_permission or delete_permission function

  • permission – Permission to synchronize with others services

  • src_resource_tree – Resource tree associated with the permission to synchronize

class cowbird.permissions_synchronizer.PermissionSynchronizer(magpie_inst: cowbird.handlers.impl.magpie.Magpie)[source]

Bases: object

Keep service-shared resources in sync when permissions are updated for one of them.


At some point we will need a consistency function that goes through all permissions of all services and make sure that linked services have the same permissions.

create_permission(permission: Permission) None[source]

Create the same permission on each service sharing the same resource.

delete_permission(permission: Permission) None[source]

Delete the same permission on each service sharing the same resource.