Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EXAMPLE IDPF-147 DO NOT MERGE. #23

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions config/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from ninja import NinjaAPI

from core.api import router as core_router


api = NinjaAPI()

api.add_router("", core_router)
3 changes: 3 additions & 0 deletions config/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@
from django.contrib import admin
from django.urls import include, path

from .api import api


urlpatterns = [
path("api/", api.urls),
path("", include("core.urls")),
path("pingdom/", include("pingdom.urls")),
path("admin/", admin.site.urls),
Expand Down
59 changes: 59 additions & 0 deletions core/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from typing import List

from ninja import Router

from identity.core.models import PeopleFinderProfile, Proifle, StaffSSOProfile

from .schemas.scim_schema import SCIMUser, user
from .services.user import UserService


router = Router()


@router.get("scim/v2/Users", response=List[SCIMUser])
def get_users(request):
users = user.objects.all()
return users


responsecodes = frozenset({200, 201})


@router.get("/user/emails?profile=peoplefinder")
def get_emails(request):
emails = CoreService.get_user_emails(request)
return emails


@router.post("scim/v2/Users", response={responsecodes: SCIMUser})
def create_user(request, scim_request: SCIMUser):
user, created = CoreService.createUser(scim_request)
# user, created = UserService.createUser(scim_request)

if created:
return 201, user
else:
return 200, user


class CoreService:
def create_user(scim_request):
user = UserService.createUser(scim_request)

sso_profile_request = {"user": user, "sso_id": scim_request.external_id}

profile = ProfileService.createProfile(sso_profile_request, StaffSSOProfile)

pf_profile_request = {"user": user, "first_name": scim_request.name.givenName}

profile = ProfileService.create_profile(pf_profile_request, PeopleFinderProfile)

def create_profile(request):
request = {}
ProfileService.createProfile(request)


class ProfileService:
def create_profile(self, request, type):
profile, created = type.objects.get_or_create(request)
28 changes: 27 additions & 1 deletion core/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,30 @@
from django.contrib.postgres.fields import ArrayField
from django.db import models


# Create your models here.
class User(models.Model):
external_id: str


class Email(models.Model):
address = models.EmailField()


class Proifle(models.Model):
user: User


class StaffSSOProfile(Proifle):
user: User
sso_id: int
given_name: str
family_name: str
prefered_email = models.EmailField()
emails = ArrayField(Email)


class PeopleFinderProfile(Proifle):
first_name: str
last_name: str
prefered_email = models.EmailField()
emails = ArrayField(Email)
Empty file added core/schemas/__init__.py
Empty file.
64 changes: 64 additions & 0 deletions core/schemas/scim_schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
from dataclasses import dataclass
from typing import Dict, List

from django.contrib.auth import get_user_model
from ninja import Field, Schema


user = get_user_model()


@dataclass
class Name:
givenName: str
familyName: str
formatted: str | None = None
middleName: str | None = None
honorificPrefix: str | None = None
honorificSuffix: str | None = None


@dataclass
class Email:
value: str | None = None
type: str | None = None
primary: bool = False


class SCIMUser(Schema):
class Config:
populate_by_name = True

schemas: List = ["urn:ietf:params:scim:schemas:core:2.0:User"]
userName: str = Field(alias="username")
name: Name
displayName: str | None = None
nickName: str | None = None
profileUrl: str | None = None
title: str | None = None
userType: str | None = None
preferredLanguage: str = None
locale: str | None = None
timezone: str | None = None
active: bool = Field(alias="is_active")
emails: list[Email] | None = None
ims: str | None = None
photos: str | None = None

@staticmethod
def resolve_emails(obj: Dict[any, any] | get_user_model):
if type(obj) is get_user_model():
if obj.email:
return [Email(obj.email, "work", True)]
else:
if "emails" in obj:
return obj["emails"]
else:
return None

@staticmethod
def resolve_name(obj: Dict[any, any] | get_user_model):
if type(obj) is get_user_model():
return Name(obj.first_name, obj.last_name)
else:
return obj["name"]
Empty file added core/services/__init__.py
Empty file.
45 changes: 45 additions & 0 deletions core/services/scim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from django.contrib.auth import get_user_model

from core.schemas.scim_schema import SCIMUser


class SCIMService:
def __init__():
super()

def transform_user(scim_request: SCIMUser) -> get_user_model:
user_model = get_user_model()
user = {
"username": scim_request.userName,
"email": scim_request.emails,
"first_name": scim_request.name.givenName,
"last_name": scim_request.name.familyName,
"is_active": scim_request.active,
"is_superuser": False,
"is_staff": False,
}

user, _ = user_model.objects.get_or_create(
username=scim_request.userName,
email=scim_request.emails,
first_name=scim_request.name.givenName,
last_name=scim_request.name.familyName,
is_active=scim_request.active,
is_superuser=False,
is_staff=False,
)

return user

def to_scim(user: get_user_model) -> SCIMUser:
# print(user)
return {
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": user.username,
"name": {
"givenName": user.first_name,
"familyName": user.last_name,
},
"emails": user.email,
"active": user.is_active,
}
23 changes: 23 additions & 0 deletions core/services/user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from django.contrib.auth import get_user_model

from core.schemas.scim_schema import SCIMUser


class UserService:
@staticmethod
def get_primary_email(scim_user: SCIMUser) -> str:
emails = scim_user.emails
primary_email = [email for email in emails if email.primary][0]
return primary_email.value

def createUser(scim_user: SCIMUser) -> tuple[get_user_model, bool]:
user_model = get_user_model()

user, created = user_model.objects.get_or_create(
username=scim_user.externalId,
is_active=scim_user.active,
is_staff=False,
is_superuser=False,
)

return user, created
Loading
Loading