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

enterprise/providers: SSF #12327

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
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
13 changes: 8 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ UID = $(shell id -u)
GID = $(shell id -g)
NPM_VERSION = $(shell python -m scripts.npm_version)
PY_SOURCES = authentik tests scripts lifecycle .github website/docs/install-config/install/aws
GO_SOURCES = cmd internal
WEB_SOURCES = web/src web/packages
DOCKER_IMAGE ?= "authentik:test"

GEN_API_TS = "gen-ts-api"
Expand All @@ -19,11 +21,12 @@ pg_name := $(shell python -m authentik.lib.config postgresql.name 2>/dev/null)
CODESPELL_ARGS = -D - -D .github/codespell-dictionary.txt \
-I .github/codespell-words.txt \
-S 'web/src/locales/**' \
-S 'website/docs/developer-docs/api/reference/**' \
authentik \
internal \
cmd \
web/src \
-S 'website/developer-docs/api/reference/**' \
-S '**/node_modules/**' \
-S '**/dist/**' \
$(PY_SOURCES) \
$(GO_SOURCES) \
$(WEB_SOURCES) \
website/src \
website/blog \
website/docs \
Expand Down
2 changes: 2 additions & 0 deletions authentik/blueprints/v1/importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
MicrosoftEntraProviderUser,
)
from authentik.enterprise.providers.rac.models import ConnectionToken
from authentik.enterprise.providers.ssf.models import StreamEvent
from authentik.enterprise.stages.authenticator_endpoint_gdtc.models import (
EndpointDevice,
EndpointDeviceConnection,
Expand Down Expand Up @@ -131,6 +132,7 @@ def excluded_models() -> list[type[Model]]:
EndpointDevice,
EndpointDeviceConnection,
DeviceToken,
StreamEvent,
)


Expand Down
Empty file.
Empty file.
62 changes: 62 additions & 0 deletions authentik/enterprise/providers/ssf/api/providers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"""SSF Provider API Views"""

from django.urls import reverse
from rest_framework.fields import SerializerMethodField
from rest_framework.request import Request
from rest_framework.viewsets import ModelViewSet

from authentik.core.api.providers import ProviderSerializer
from authentik.core.api.tokens import TokenSerializer
from authentik.core.api.used_by import UsedByMixin
from authentik.enterprise.api import EnterpriseRequiredMixin
from authentik.enterprise.providers.ssf.models import SSFProvider


class SSFProviderSerializer(EnterpriseRequiredMixin, ProviderSerializer):
"""SSFProvider Serializer"""

ssf_url = SerializerMethodField()
token_obj = TokenSerializer(source="token", required=False, read_only=True)

def get_ssf_url(self, instance: SSFProvider) -> str | None:
request: Request = self._context["request"]
if not instance.application:
return None
return request.build_absolute_uri(

Check warning on line 25 in authentik/enterprise/providers/ssf/api/providers.py

View check run for this annotation

Codecov / codecov/patch

authentik/enterprise/providers/ssf/api/providers.py#L22-L25

Added lines #L22 - L25 were not covered by tests
reverse(
"authentik_providers_ssf:configuration",
kwargs={
"application_slug": instance.application.slug,
"provider": instance.pk,
},
)
)

class Meta:
model = SSFProvider
fields = [
"pk",
"name",
"component",
"verbose_name",
"verbose_name_plural",
"meta_model_name",
"signing_key",
"token_obj",
"oidc_auth_providers",
"ssf_url",
]
extra_kwargs = {}


class SSFProviderViewSet(UsedByMixin, ModelViewSet):
"""SSFProvider Viewset"""

queryset = SSFProvider.objects.all()
serializer_class = SSFProviderSerializer
filterset_fields = {
"application": ["isnull"],
"name": ["iexact"],
}
search_fields = ["name"]
ordering = ["name"]
13 changes: 13 additions & 0 deletions authentik/enterprise/providers/ssf/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"""SSF app config"""

from authentik.enterprise.apps import EnterpriseConfig


class AuthentikEnterpriseProviderSSF(EnterpriseConfig):
"""authentik enterprise ssf app config"""

name = "authentik.enterprise.providers.ssf"
label = "authentik_providers_ssf"
verbose_name = "authentik Enterprise.Providers.SSF"
default = True
mountpoint = ""
140 changes: 140 additions & 0 deletions authentik/enterprise/providers/ssf/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# Generated by Django 5.0.9 on 2024-09-30 17:22

import django.contrib.postgres.fields
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 = [
("authentik_core", "0039_source_group_matching_mode_alter_group_name_and_more"),
("authentik_crypto", "0004_alter_certificatekeypair_name"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.CreateModel(
name="SSFProvider",
fields=[
(
"provider_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="authentik_core.provider",
),
),
(
"signing_key",
models.ForeignKey(
help_text="Key used to sign the tokens. Only required when JWT Algorithm is set to RS256.",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to="authentik_crypto.certificatekeypair",
verbose_name="Signing Key",
),
),
(
"token",
models.ForeignKey(
default=None,
null=True,
on_delete=django.db.models.deletion.CASCADE,
to="authentik_core.token",
),
),
],
options={
"verbose_name": "SSF Provider",
"verbose_name_plural": "SSF Providers",
},
bases=("authentik_core.provider",),
),
migrations.CreateModel(
name="Stream",
fields=[
(
"uuid",
models.UUIDField(
default=uuid.uuid4, editable=False, primary_key=True, serialize=False
),
),
(
"delivery_method",
models.TextField(
choices=[
(
"https://schemas.openid.net/secevent/risc/delivery-method/push",
"Risc Push",
),
(
"https://schemas.openid.net/secevent/risc/delivery-method/poll",
"Risc Poll",
),
]
),
),
("endpoint_url", models.TextField(null=True)),
(
"events_requested",
django.contrib.postgres.fields.ArrayField(
base_field=models.TextField(
choices=[
(
"https://schemas.openid.net/secevent/caep/event-type/session-revoked",
"Caep Session Revoked",
)
]
),
default=list,
size=None,
),
),
(
"provider",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="authentik_providers_ssf.ssfprovider",
),
),
(
"user_subjects",
models.ManyToManyField(
related_name="UserStreamSubject", to=settings.AUTH_USER_MODEL
),
),
],
),
migrations.CreateModel(
name="UserStreamSubject",
fields=[
(
"id",
models.AutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
),
),
(
"stream",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="authentik_providers_ssf.stream",
),
),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
),
),
],
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Generated by Django 5.0.9 on 2024-11-07 13:31

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("authentik_providers_oauth2", "0023_alter_accesstoken_refreshtoken_use_hash_index"),
("authentik_providers_ssf", "0001_initial"),
]

operations = [
migrations.AddField(
model_name="ssfprovider",
name="oidc_auth_providers",
field=models.ManyToManyField(
blank=True, default=None, to="authentik_providers_oauth2.oauth2provider"
),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 5.0.9 on 2024-11-07 14:22

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("authentik_providers_ssf", "0002_ssfprovider_oidc_auth_providers"),
]

operations = [
migrations.AddField(
model_name="stream",
name="format",
field=models.TextField(default=""),
preserve_default=False,
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Generated by Django 5.0.9 on 2024-11-07 15:10

import django.contrib.postgres.fields
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("authentik_providers_ssf", "0003_stream_format"),
]

operations = [
migrations.AddField(
model_name="stream",
name="aud",
field=django.contrib.postgres.fields.ArrayField(
base_field=models.TextField(), default=list, size=None
),
),
migrations.AlterField(
model_name="stream",
name="events_requested",
field=django.contrib.postgres.fields.ArrayField(
base_field=models.TextField(
choices=[
(
"https://schemas.openid.net/secevent/caep/event-type/session-revoked",
"Caep Session Revoked",
),
(
"https://schemas.openid.net/secevent/caep/event-type/credential-change",
"Caep Credential Change",
),
]
),
default=list,
size=None,
),
),
]
Loading
Loading