authentik.sources.scim.models
SCIM Source
1"""SCIM Source""" 2 3from typing import Any 4from uuid import uuid4 5 6from django.db import models 7from django.templatetags.static import static 8from django.utils.translation import gettext_lazy as _ 9from rest_framework.serializers import BaseSerializer, Serializer 10 11from authentik.core.models import Group, PropertyMapping, Source, Token, User 12from authentik.lib.models import InternallyManagedMixin, SerializerModel 13 14 15class SCIMSource(Source): 16 """System for Cross-domain Identity Management Source, allows for 17 cross-system user provisioning""" 18 19 token = models.ForeignKey(Token, on_delete=models.CASCADE, null=True, default=None) 20 21 @property 22 def service_account_identifier(self) -> str: 23 return f"ak-source-scim-{self.pk}" 24 25 @property 26 def component(self) -> str: 27 """Return component used to edit this object""" 28 return "ak-source-scim-form" 29 30 @property 31 def icon_url(self) -> str: 32 return static("authentik/sources/scim.png") 33 34 @property 35 def serializer(self) -> BaseSerializer: 36 from authentik.sources.scim.api.sources import SCIMSourceSerializer 37 38 return SCIMSourceSerializer 39 40 @property 41 def property_mapping_type(self) -> type[PropertyMapping]: 42 return SCIMSourcePropertyMapping 43 44 def get_base_user_properties(self, data: dict[str, Any]) -> dict[str, Any | dict[str, Any]]: 45 properties = {} 46 47 def get_email(data: list[dict]) -> str: 48 """Wrapper to get primary email or first email""" 49 for email in data: 50 if email.get("primary", False): 51 return email.get("value") 52 if len(data) < 1: 53 return "" 54 return data[0].get("value") 55 56 if "userName" in data: 57 properties["username"] = data.get("userName") 58 if "name" in data: 59 properties["name"] = data.get("name", {}).get("formatted", data.get("displayName")) 60 if "emails" in data: 61 properties["email"] = get_email(data.get("emails")) 62 if "active" in data: 63 properties["is_active"] = data.get("active") 64 65 return properties 66 67 def get_base_group_properties(self, data: dict[str, Any]) -> dict[str, Any | dict[str, Any]]: 68 properties = {} 69 70 if "displayName" in data: 71 properties["name"] = data.get("displayName") 72 73 return properties 74 75 def __str__(self) -> str: 76 return f"SCIM Source {self.name}" 77 78 class Meta: 79 80 verbose_name = _("SCIM Source") 81 verbose_name_plural = _("SCIM Sources") 82 83 84class SCIMSourcePropertyMapping(PropertyMapping): 85 """Map SCIM properties to User or Group object attributes""" 86 87 @property 88 def component(self) -> str: 89 return "ak-property-mapping-source-scim-form" 90 91 @property 92 def serializer(self) -> type[Serializer]: 93 from authentik.sources.scim.api.property_mappings import ( 94 SCIMSourcePropertyMappingSerializer, 95 ) 96 97 return SCIMSourcePropertyMappingSerializer 98 99 class Meta: 100 verbose_name = _("SCIM Source Property Mapping") 101 verbose_name_plural = _("SCIM Source Property Mappings") 102 103 104class SCIMSourceUser(InternallyManagedMixin, SerializerModel): 105 """Mapping of a user and source to a SCIM user ID""" 106 107 id = models.TextField(primary_key=True, default=uuid4) 108 external_id = models.TextField() 109 user = models.ForeignKey(User, on_delete=models.CASCADE) 110 source = models.ForeignKey(SCIMSource, on_delete=models.CASCADE) 111 attributes = models.JSONField(default=dict) 112 last_update = models.DateTimeField(auto_now=True) 113 114 @property 115 def serializer(self) -> BaseSerializer: 116 from authentik.sources.scim.api.users import SCIMSourceUserSerializer 117 118 return SCIMSourceUserSerializer 119 120 class Meta: 121 unique_together = (("external_id", "source"),) 122 indexes = [ 123 models.Index(fields=["external_id"]), 124 ] 125 126 def __str__(self) -> str: 127 return f"SCIM User {self.user_id} to {self.source_id}" 128 129 130class SCIMSourceGroup(InternallyManagedMixin, SerializerModel): 131 """Mapping of a group and source to a SCIM user ID""" 132 133 id = models.TextField(primary_key=True, default=uuid4) 134 external_id = models.TextField() 135 group = models.ForeignKey(Group, on_delete=models.CASCADE) 136 source = models.ForeignKey(SCIMSource, on_delete=models.CASCADE) 137 attributes = models.JSONField(default=dict) 138 last_update = models.DateTimeField(auto_now=True) 139 140 @property 141 def serializer(self) -> BaseSerializer: 142 from authentik.sources.scim.api.groups import SCIMSourceGroupSerializer 143 144 return SCIMSourceGroupSerializer 145 146 class Meta: 147 unique_together = (("external_id", "source"),) 148 indexes = [ 149 models.Index(fields=["external_id"]), 150 ] 151 152 def __str__(self) -> str: 153 return f"SCIM Group {self.group_id} to {self.source_id}"
16class SCIMSource(Source): 17 """System for Cross-domain Identity Management Source, allows for 18 cross-system user provisioning""" 19 20 token = models.ForeignKey(Token, on_delete=models.CASCADE, null=True, default=None) 21 22 @property 23 def service_account_identifier(self) -> str: 24 return f"ak-source-scim-{self.pk}" 25 26 @property 27 def component(self) -> str: 28 """Return component used to edit this object""" 29 return "ak-source-scim-form" 30 31 @property 32 def icon_url(self) -> str: 33 return static("authentik/sources/scim.png") 34 35 @property 36 def serializer(self) -> BaseSerializer: 37 from authentik.sources.scim.api.sources import SCIMSourceSerializer 38 39 return SCIMSourceSerializer 40 41 @property 42 def property_mapping_type(self) -> type[PropertyMapping]: 43 return SCIMSourcePropertyMapping 44 45 def get_base_user_properties(self, data: dict[str, Any]) -> dict[str, Any | dict[str, Any]]: 46 properties = {} 47 48 def get_email(data: list[dict]) -> str: 49 """Wrapper to get primary email or first email""" 50 for email in data: 51 if email.get("primary", False): 52 return email.get("value") 53 if len(data) < 1: 54 return "" 55 return data[0].get("value") 56 57 if "userName" in data: 58 properties["username"] = data.get("userName") 59 if "name" in data: 60 properties["name"] = data.get("name", {}).get("formatted", data.get("displayName")) 61 if "emails" in data: 62 properties["email"] = get_email(data.get("emails")) 63 if "active" in data: 64 properties["is_active"] = data.get("active") 65 66 return properties 67 68 def get_base_group_properties(self, data: dict[str, Any]) -> dict[str, Any | dict[str, Any]]: 69 properties = {} 70 71 if "displayName" in data: 72 properties["name"] = data.get("displayName") 73 74 return properties 75 76 def __str__(self) -> str: 77 return f"SCIM Source {self.name}" 78 79 class Meta: 80 81 verbose_name = _("SCIM Source") 82 verbose_name_plural = _("SCIM Sources")
System for Cross-domain Identity Management Source, allows for cross-system user provisioning
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example::
class Child(Model):
parent = ForeignKey(Parent, related_name='children')
Child.parent is a ForwardManyToOneDescriptor instance.
26 @property 27 def component(self) -> str: 28 """Return component used to edit this object""" 29 return "ak-source-scim-form"
Return component used to edit this object
35 @property 36 def serializer(self) -> BaseSerializer: 37 from authentik.sources.scim.api.sources import SCIMSourceSerializer 38 39 return SCIMSourceSerializer
Get serializer for this model
41 @property 42 def property_mapping_type(self) -> type[PropertyMapping]: 43 return SCIMSourcePropertyMapping
Return property mapping type used by this object
45 def get_base_user_properties(self, data: dict[str, Any]) -> dict[str, Any | dict[str, Any]]: 46 properties = {} 47 48 def get_email(data: list[dict]) -> str: 49 """Wrapper to get primary email or first email""" 50 for email in data: 51 if email.get("primary", False): 52 return email.get("value") 53 if len(data) < 1: 54 return "" 55 return data[0].get("value") 56 57 if "userName" in data: 58 properties["username"] = data.get("userName") 59 if "name" in data: 60 properties["name"] = data.get("name", {}).get("formatted", data.get("displayName")) 61 if "emails" in data: 62 properties["email"] = get_email(data.get("emails")) 63 if "active" in data: 64 properties["is_active"] = data.get("active") 65 66 return properties
Get base properties for a user to build final properties upon.
68 def get_base_group_properties(self, data: dict[str, Any]) -> dict[str, Any | dict[str, Any]]: 69 properties = {} 70 71 if "displayName" in data: 72 properties["name"] = data.get("displayName") 73 74 return properties
Get base properties for a group to build final properties upon.
Accessor to the related object on the forward side of a one-to-one relation.
In the example::
class Restaurant(Model):
place = OneToOneField(Place, related_name='restaurant')
Restaurant.place is a ForwardOneToOneDescriptor instance.
Accessor to the related objects manager on the reverse side of a many-to-one relation.
In the example::
class Child(Model):
parent = ForeignKey(Parent, related_name='children')
Parent.children is a ReverseManyToOneDescriptor instance.
Most of the implementation is delegated to a dynamically defined manager
class built by create_forward_many_to_many_manager() defined below.
Accessor to the related objects manager on the reverse side of a many-to-one relation.
In the example::
class Child(Model):
parent = ForeignKey(Parent, related_name='children')
Parent.children is a ReverseManyToOneDescriptor instance.
Most of the implementation is delegated to a dynamically defined manager
class built by create_forward_many_to_many_manager() defined below.
Inherited Members
- authentik.core.models.Source
- MANAGED_INBUILT
- name
- slug
- user_path_template
- enabled
- promoted
- user_property_mappings
- group_property_mappings
- icon
- authentication_flow
- enrollment_flow
- user_matching_mode
- group_matching_mode
- objects
- icon_themed_urls
- get_user_path
- ui_user_settings
- managed
- authentication_flow_id
- enrollment_flow_id
- get_user_matching_mode_display
- get_group_matching_mode_display
- policybindingmodel_ptr_id
- policybindingmodel_ptr
- user_set
- usersourceconnection_set
- groupsourceconnection_set
- oauthsource
- samlsource
- kerberossource
- ldapsource
- identificationstage_set
- plexsource
- scimsource
- telegramsource
- sourcestage_set
The requested object does not exist
The query returned multiple objects when only one was expected.
85class SCIMSourcePropertyMapping(PropertyMapping): 86 """Map SCIM properties to User or Group object attributes""" 87 88 @property 89 def component(self) -> str: 90 return "ak-property-mapping-source-scim-form" 91 92 @property 93 def serializer(self) -> type[Serializer]: 94 from authentik.sources.scim.api.property_mappings import ( 95 SCIMSourcePropertyMappingSerializer, 96 ) 97 98 return SCIMSourcePropertyMappingSerializer 99 100 class Meta: 101 verbose_name = _("SCIM Source Property Mapping") 102 verbose_name_plural = _("SCIM Source Property Mappings")
Map SCIM properties to User or Group object attributes
92 @property 93 def serializer(self) -> type[Serializer]: 94 from authentik.sources.scim.api.property_mappings import ( 95 SCIMSourcePropertyMappingSerializer, 96 ) 97 98 return SCIMSourcePropertyMappingSerializer
Get serializer for this model
Accessor to the related object on the forward side of a one-to-one relation.
In the example::
class Restaurant(Model):
place = OneToOneField(Place, related_name='restaurant')
Restaurant.place is a ForwardOneToOneDescriptor instance.
Inherited Members
- authentik.core.models.PropertyMapping
- pm_uuid
- name
- expression
- objects
- evaluate
- managed
- provider_set
- source_userpropertymappings_set
- source_grouppropertymappings_set
- notificationwebhookmapping
- oauthsourcepropertymapping
- scopemapping
- endpoint_set
- racpropertymapping
- radiusproviderpropertymapping
- samlsourcepropertymapping
- samlpropertymapping
- scimprovider_set
- scimmapping
- kerberossourcepropertymapping
- ldapsourcepropertymapping
- plexsourcepropertymapping
- scimsourcepropertymapping
- telegramsourcepropertymapping
- googleworkspaceprovider_set
- googleworkspaceprovidermapping
- microsoftentraprovider_set
- microsoftentraprovidermapping
The requested object does not exist
The query returned multiple objects when only one was expected.
105class SCIMSourceUser(InternallyManagedMixin, SerializerModel): 106 """Mapping of a user and source to a SCIM user ID""" 107 108 id = models.TextField(primary_key=True, default=uuid4) 109 external_id = models.TextField() 110 user = models.ForeignKey(User, on_delete=models.CASCADE) 111 source = models.ForeignKey(SCIMSource, on_delete=models.CASCADE) 112 attributes = models.JSONField(default=dict) 113 last_update = models.DateTimeField(auto_now=True) 114 115 @property 116 def serializer(self) -> BaseSerializer: 117 from authentik.sources.scim.api.users import SCIMSourceUserSerializer 118 119 return SCIMSourceUserSerializer 120 121 class Meta: 122 unique_together = (("external_id", "source"),) 123 indexes = [ 124 models.Index(fields=["external_id"]), 125 ] 126 127 def __str__(self) -> str: 128 return f"SCIM User {self.user_id} to {self.source_id}"
Mapping of a user and source to a SCIM user ID
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example::
class Child(Model):
parent = ForeignKey(Parent, related_name='children')
Child.parent is a ForwardManyToOneDescriptor instance.
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example::
class Child(Model):
parent = ForeignKey(Parent, related_name='children')
Child.parent is a ForwardManyToOneDescriptor instance.
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
115 @property 116 def serializer(self) -> BaseSerializer: 117 from authentik.sources.scim.api.users import SCIMSourceUserSerializer 118 119 return SCIMSourceUserSerializer
Get serializer for this model
Method descriptor with partial application of the given arguments and keywords.
Supports wrapping existing descriptors and handles non-descriptor callables as instance methods.
Method descriptor with partial application of the given arguments and keywords.
Supports wrapping existing descriptors and handles non-descriptor callables as instance methods.
Inherited Members
The requested object does not exist
The query returned multiple objects when only one was expected.
131class SCIMSourceGroup(InternallyManagedMixin, SerializerModel): 132 """Mapping of a group and source to a SCIM user ID""" 133 134 id = models.TextField(primary_key=True, default=uuid4) 135 external_id = models.TextField() 136 group = models.ForeignKey(Group, on_delete=models.CASCADE) 137 source = models.ForeignKey(SCIMSource, on_delete=models.CASCADE) 138 attributes = models.JSONField(default=dict) 139 last_update = models.DateTimeField(auto_now=True) 140 141 @property 142 def serializer(self) -> BaseSerializer: 143 from authentik.sources.scim.api.groups import SCIMSourceGroupSerializer 144 145 return SCIMSourceGroupSerializer 146 147 class Meta: 148 unique_together = (("external_id", "source"),) 149 indexes = [ 150 models.Index(fields=["external_id"]), 151 ] 152 153 def __str__(self) -> str: 154 return f"SCIM Group {self.group_id} to {self.source_id}"
Mapping of a group and source to a SCIM user ID
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example::
class Child(Model):
parent = ForeignKey(Parent, related_name='children')
Child.parent is a ForwardManyToOneDescriptor instance.
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example::
class Child(Model):
parent = ForeignKey(Parent, related_name='children')
Child.parent is a ForwardManyToOneDescriptor instance.
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
141 @property 142 def serializer(self) -> BaseSerializer: 143 from authentik.sources.scim.api.groups import SCIMSourceGroupSerializer 144 145 return SCIMSourceGroupSerializer
Get serializer for this model
Method descriptor with partial application of the given arguments and keywords.
Supports wrapping existing descriptors and handles non-descriptor callables as instance methods.
Method descriptor with partial application of the given arguments and keywords.
Supports wrapping existing descriptors and handles non-descriptor callables as instance methods.
Inherited Members
The requested object does not exist
The query returned multiple objects when only one was expected.