Compare commits

...

1 Commits

Author SHA1 Message Date
19c5b28cb2 endpoints: initial data structure
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-05-28 23:22:38 +02:00
13 changed files with 255 additions and 0 deletions

View File

View File

@ -0,0 +1,12 @@
"""authentik endpoints app config"""
from authentik.blueprints.apps import ManagedAppConfig
class AuthentikEndpointsConfig(ManagedAppConfig):
"""authentik endpoints app config"""
name = "authentik.endpoints"
label = "authentik_endpoints"
verbose_name = "authentik Endpoints"
default = True

View File

@ -0,0 +1,47 @@
from enum import Enum
from pydantic import BaseModel
class UNSUPPORTED(BaseModel):
pass
class OSFamily(Enum):
linux = "linux"
unix = "unix"
bsd = "bsd"
windows = "windows"
macOS = "mac_os"
android = "android"
iOS = "i_os"
other = "other"
class CommonDeviceData(BaseModel):
class Disk(BaseModel):
encryption: bool
class OS(BaseModel):
firewall_enabled: bool
family: OSFamily
name: str
version: str
class Network(BaseModel):
hostname: str
dns_servers: list[str]
class Hardware(BaseModel):
model: str
manufacturer: str
class Software(BaseModel):
name: str
version: str
os: OS | UNSUPPORTED
disks: list[Disk] | UNSUPPORTED
network: Network | UNSUPPORTED
hardware: Hardware | UNSUPPORTED
software: list[Software] | UNSUPPORTED

View File

@ -0,0 +1,16 @@
from authentik.blueprints import models
class EnrollmentMethods(models.TextChoices):
AUTOMATIC_USER = "automatic_user" # Automatically enrolled through user action
AUTOMATIC_API = "automatic_api" # Automatically enrolled through connector integration
MANUAL_USER = "manual_user" # Manually enrolled
class BaseConnector:
def __init__(self) -> None:
pass
def supported_enrollment_methods(self) -> list[EnrollmentMethods]:
return []

View File

@ -0,0 +1,7 @@
from authentik.endpoints.connector import BaseConnector, EnrollmentMethods
class GoogleChromeConnector(BaseConnector):
def supported_enrollment_methods(self) -> list[EnrollmentMethods]:
return [EnrollmentMethods.AUTOMATIC_USER]

View File

@ -0,0 +1,7 @@
from django.db import models
from authentik.endpoints.models import Connector
class GoogleChromeConnector(Connector):
credentials = models.JSONField()

View File

@ -0,0 +1,125 @@
# Generated by Django 5.0.9 on 2024-09-24 19:16
import django.db.models.deletion
import uuid
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name="Connector",
fields=[
(
"id",
models.AutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
),
),
("connector_uuid", models.UUIDField(default=uuid.uuid4)),
("name", models.TextField()),
(
"enrollment_method",
models.TextField(
choices=[
("automatic_user", "Automatic User"),
("automatic_api", "Automatic Api"),
("manual_user", "Manual User"),
]
),
),
],
options={
"abstract": False,
},
),
migrations.CreateModel(
name="Device",
fields=[
(
"id",
models.AutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
),
),
("device_uuid", models.UUIDField(default=uuid.uuid4)),
("identifier", models.TextField(unique=True)),
],
options={
"abstract": False,
},
),
migrations.CreateModel(
name="DeviceConnection",
fields=[
(
"id",
models.AutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
),
),
("device_connection_uuid", models.UUIDField(default=uuid.uuid4)),
("data", models.JSONField(default=dict)),
(
"connection",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="authentik_endpoints.connector",
),
),
(
"device",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="authentik_endpoints.device"
),
),
],
),
migrations.AddField(
model_name="device",
name="connections",
field=models.ManyToManyField(
through="authentik_endpoints.DeviceConnection", to="authentik_endpoints.connector"
),
),
migrations.CreateModel(
name="DeviceUser",
fields=[
(
"id",
models.AutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
),
),
("device_user_uuid", models.UUIDField(default=uuid.uuid4)),
("is_primary", models.BooleanField()),
(
"device",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="authentik_endpoints.device"
),
),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
),
),
],
),
migrations.AddField(
model_name="device",
name="users",
field=models.ManyToManyField(
through="authentik_endpoints.DeviceUser", to=settings.AUTH_USER_MODEL
),
),
]

View File

@ -0,0 +1,40 @@
from uuid import uuid4
from django.db import models
from django.utils.functional import cached_property
from authentik.core.models import User
from authentik.endpoints.common_data import CommonDeviceData
from authentik.lib.models import SerializerModel
class Device(SerializerModel):
device_uuid = models.UUIDField(default=uuid4)
identifier = models.TextField(unique=True)
users = models.ManyToManyField(User, through="DeviceUser")
connections = models.ManyToManyField("Connector", through="DeviceConnection")
@cached_property
def data(self) -> CommonDeviceData:
pass
class DeviceUser(models.Model):
device_user_uuid = models.UUIDField(default=uuid4)
device = models.ForeignKey("Device", on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
is_primary = models.BooleanField()
class DeviceConnection(models.Model):
device_connection_uuid = models.UUIDField(default=uuid4)
device = models.ForeignKey("Device", on_delete=models.CASCADE)
connection = models.ForeignKey("Connector", on_delete=models.CASCADE)
data = models.JSONField(default=dict)
class Connector(SerializerModel):
connector_uuid = models.UUIDField(default=uuid4)
name = models.TextField()

View File

@ -73,6 +73,7 @@ TENANT_APPS = [
"authentik.admin",
"authentik.api",
"authentik.crypto",
"authentik.endpoints",
"authentik.flows",
"authentik.outposts",
"authentik.policies.dummy",