enterprise/providers/SSF: fix a couple of bugs after real world testing (#12987)
* providers/ssf: fix txn being inside the event not the SET itself Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix incorrect ssf format Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix web form Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
@ -70,18 +70,19 @@ def ssf_user_logged_out_session_revoked(sender, request: HttpRequest, user: User
|
|||||||
send_ssf_event(
|
send_ssf_event(
|
||||||
EventTypes.CAEP_SESSION_REVOKED,
|
EventTypes.CAEP_SESSION_REVOKED,
|
||||||
{
|
{
|
||||||
"subject": {
|
|
||||||
"session": {
|
|
||||||
"format": "opaque",
|
|
||||||
"id": sha256(request.session.session_key.encode("ascii")).hexdigest(),
|
|
||||||
},
|
|
||||||
"user": {
|
|
||||||
"format": "email",
|
|
||||||
"email": user.email,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"initiating_entity": "user",
|
"initiating_entity": "user",
|
||||||
},
|
},
|
||||||
|
sub_id={
|
||||||
|
"format": "complex",
|
||||||
|
"session": {
|
||||||
|
"format": "opaque",
|
||||||
|
"id": sha256(request.session.session_key.encode("ascii")).hexdigest(),
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"format": "email",
|
||||||
|
"email": user.email,
|
||||||
|
},
|
||||||
|
},
|
||||||
request=request,
|
request=request,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -95,18 +96,19 @@ def ssf_user_session_delete_session_revoked(sender, instance: AuthenticatedSessi
|
|||||||
send_ssf_event(
|
send_ssf_event(
|
||||||
EventTypes.CAEP_SESSION_REVOKED,
|
EventTypes.CAEP_SESSION_REVOKED,
|
||||||
{
|
{
|
||||||
"subject": {
|
|
||||||
"session": {
|
|
||||||
"format": "opaque",
|
|
||||||
"id": sha256(instance.session_key.encode("ascii")).hexdigest(),
|
|
||||||
},
|
|
||||||
"user": {
|
|
||||||
"format": "email",
|
|
||||||
"email": instance.user.email,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"initiating_entity": "user",
|
"initiating_entity": "user",
|
||||||
},
|
},
|
||||||
|
sub_id={
|
||||||
|
"format": "complex",
|
||||||
|
"session": {
|
||||||
|
"format": "opaque",
|
||||||
|
"id": sha256(instance.session_key.encode("ascii")).hexdigest(),
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"format": "email",
|
||||||
|
"email": instance.user.email,
|
||||||
|
},
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -116,15 +118,16 @@ def ssf_password_changed_cred_change(sender, user: User, password: str | None, *
|
|||||||
send_ssf_event(
|
send_ssf_event(
|
||||||
EventTypes.CAEP_CREDENTIAL_CHANGE,
|
EventTypes.CAEP_CREDENTIAL_CHANGE,
|
||||||
{
|
{
|
||||||
"subject": {
|
|
||||||
"user": {
|
|
||||||
"format": "email",
|
|
||||||
"email": user.email,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"credential_type": "password",
|
"credential_type": "password",
|
||||||
"change_type": "revoke" if password is None else "update",
|
"change_type": "revoke" if password is None else "update",
|
||||||
},
|
},
|
||||||
|
sub_id={
|
||||||
|
"format": "complex",
|
||||||
|
"user": {
|
||||||
|
"format": "email",
|
||||||
|
"email": user.email,
|
||||||
|
},
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -144,19 +147,23 @@ def ssf_device_post_save(sender: type[Model], instance: Device, created: bool, *
|
|||||||
return
|
return
|
||||||
device_type = device_type_map.get(instance.__class__)
|
device_type = device_type_map.get(instance.__class__)
|
||||||
data = {
|
data = {
|
||||||
"subject": {
|
|
||||||
"user": {
|
|
||||||
"format": "email",
|
|
||||||
"email": instance.user.email,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"credential_type": device_type,
|
"credential_type": device_type,
|
||||||
"change_type": "create" if created else "update",
|
"change_type": "create" if created else "update",
|
||||||
"friendly_name": instance.name,
|
"friendly_name": instance.name,
|
||||||
}
|
}
|
||||||
if isinstance(instance, WebAuthnDevice) and instance.aaguid != UNKNOWN_DEVICE_TYPE_AAGUID:
|
if isinstance(instance, WebAuthnDevice) and instance.aaguid != UNKNOWN_DEVICE_TYPE_AAGUID:
|
||||||
data["fido2_aaguid"] = instance.aaguid
|
data["fido2_aaguid"] = instance.aaguid
|
||||||
send_ssf_event(EventTypes.CAEP_CREDENTIAL_CHANGE, data)
|
send_ssf_event(
|
||||||
|
EventTypes.CAEP_CREDENTIAL_CHANGE,
|
||||||
|
data,
|
||||||
|
sub_id={
|
||||||
|
"format": "complex",
|
||||||
|
"user": {
|
||||||
|
"format": "email",
|
||||||
|
"email": instance.user.email,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_delete)
|
@receiver(post_delete)
|
||||||
@ -167,16 +174,20 @@ def ssf_device_post_delete(sender: type[Model], instance: Device, **_):
|
|||||||
return
|
return
|
||||||
device_type = device_type_map.get(instance.__class__)
|
device_type = device_type_map.get(instance.__class__)
|
||||||
data = {
|
data = {
|
||||||
"subject": {
|
|
||||||
"user": {
|
|
||||||
"format": "email",
|
|
||||||
"email": instance.user.email,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"credential_type": device_type,
|
"credential_type": device_type,
|
||||||
"change_type": "delete",
|
"change_type": "delete",
|
||||||
"friendly_name": instance.name,
|
"friendly_name": instance.name,
|
||||||
}
|
}
|
||||||
if isinstance(instance, WebAuthnDevice) and instance.aaguid != UNKNOWN_DEVICE_TYPE_AAGUID:
|
if isinstance(instance, WebAuthnDevice) and instance.aaguid != UNKNOWN_DEVICE_TYPE_AAGUID:
|
||||||
data["fido2_aaguid"] = instance.aaguid
|
data["fido2_aaguid"] = instance.aaguid
|
||||||
send_ssf_event(EventTypes.CAEP_CREDENTIAL_CHANGE, data)
|
send_ssf_event(
|
||||||
|
EventTypes.CAEP_CREDENTIAL_CHANGE,
|
||||||
|
data,
|
||||||
|
sub_id={
|
||||||
|
"format": "complex",
|
||||||
|
"user": {
|
||||||
|
"format": "email",
|
||||||
|
"email": instance.user.email,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
@ -36,7 +36,7 @@ def send_ssf_event(
|
|||||||
stream_filter = {}
|
stream_filter = {}
|
||||||
stream_filter["events_requested__contains"] = [event_type]
|
stream_filter["events_requested__contains"] = [event_type]
|
||||||
if request and hasattr(request, "request_id"):
|
if request and hasattr(request, "request_id"):
|
||||||
data.setdefault("txn", request.request_id)
|
extra_data.setdefault("txn", request.request_id)
|
||||||
for stream in Stream.objects.filter(**stream_filter):
|
for stream in Stream.objects.filter(**stream_filter):
|
||||||
event_data = stream.prepare_event_payload(event_type, data, **extra_data)
|
event_data = stream.prepare_event_payload(event_type, data, **extra_data)
|
||||||
payload.append((str(stream.uuid), event_data))
|
payload.append((str(stream.uuid), event_data))
|
||||||
|
@ -65,9 +65,10 @@ class TestSignals(APITestCase):
|
|||||||
"https://schemas.openid.net/secevent/caep/event-type/session-revoked"
|
"https://schemas.openid.net/secevent/caep/event-type/session-revoked"
|
||||||
]
|
]
|
||||||
self.assertEqual(event_payload["initiating_entity"], "user")
|
self.assertEqual(event_payload["initiating_entity"], "user")
|
||||||
self.assertEqual(event_payload["subject"]["session"]["format"], "opaque")
|
self.assertEqual(event.payload["sub_id"]["format"], "complex")
|
||||||
self.assertEqual(event_payload["subject"]["user"]["format"], "email")
|
self.assertEqual(event.payload["sub_id"]["session"]["format"], "opaque")
|
||||||
self.assertEqual(event_payload["subject"]["user"]["email"], user.email)
|
self.assertEqual(event.payload["sub_id"]["user"]["format"], "email")
|
||||||
|
self.assertEqual(event.payload["sub_id"]["user"]["email"], user.email)
|
||||||
|
|
||||||
def test_signal_password_change(self):
|
def test_signal_password_change(self):
|
||||||
"""Test user password change"""
|
"""Test user password change"""
|
||||||
@ -86,8 +87,9 @@ class TestSignals(APITestCase):
|
|||||||
]
|
]
|
||||||
self.assertEqual(event_payload["change_type"], "update")
|
self.assertEqual(event_payload["change_type"], "update")
|
||||||
self.assertEqual(event_payload["credential_type"], "password")
|
self.assertEqual(event_payload["credential_type"], "password")
|
||||||
self.assertEqual(event_payload["subject"]["user"]["format"], "email")
|
self.assertEqual(event.payload["sub_id"]["format"], "complex")
|
||||||
self.assertEqual(event_payload["subject"]["user"]["email"], user.email)
|
self.assertEqual(event.payload["sub_id"]["user"]["format"], "email")
|
||||||
|
self.assertEqual(event.payload["sub_id"]["user"]["email"], user.email)
|
||||||
|
|
||||||
def test_signal_authenticator_added(self):
|
def test_signal_authenticator_added(self):
|
||||||
"""Test authenticator creation signal"""
|
"""Test authenticator creation signal"""
|
||||||
@ -113,8 +115,9 @@ class TestSignals(APITestCase):
|
|||||||
self.assertEqual(event_payload["fido2_aaguid"], dev.aaguid)
|
self.assertEqual(event_payload["fido2_aaguid"], dev.aaguid)
|
||||||
self.assertEqual(event_payload["friendly_name"], dev.name)
|
self.assertEqual(event_payload["friendly_name"], dev.name)
|
||||||
self.assertEqual(event_payload["credential_type"], "fido-u2f")
|
self.assertEqual(event_payload["credential_type"], "fido-u2f")
|
||||||
self.assertEqual(event_payload["subject"]["user"]["format"], "email")
|
self.assertEqual(event.payload["sub_id"]["format"], "complex")
|
||||||
self.assertEqual(event_payload["subject"]["user"]["email"], user.email)
|
self.assertEqual(event.payload["sub_id"]["user"]["format"], "email")
|
||||||
|
self.assertEqual(event.payload["sub_id"]["user"]["email"], user.email)
|
||||||
|
|
||||||
def test_signal_authenticator_deleted(self):
|
def test_signal_authenticator_deleted(self):
|
||||||
"""Test authenticator deletion signal"""
|
"""Test authenticator deletion signal"""
|
||||||
@ -141,5 +144,6 @@ class TestSignals(APITestCase):
|
|||||||
self.assertEqual(event_payload["fido2_aaguid"], dev.aaguid)
|
self.assertEqual(event_payload["fido2_aaguid"], dev.aaguid)
|
||||||
self.assertEqual(event_payload["friendly_name"], dev.name)
|
self.assertEqual(event_payload["friendly_name"], dev.name)
|
||||||
self.assertEqual(event_payload["credential_type"], "fido-u2f")
|
self.assertEqual(event_payload["credential_type"], "fido-u2f")
|
||||||
self.assertEqual(event_payload["subject"]["user"]["format"], "email")
|
self.assertEqual(event.payload["sub_id"]["format"], "complex")
|
||||||
self.assertEqual(event_payload["subject"]["user"]["email"], user.email)
|
self.assertEqual(event.payload["sub_id"]["user"]["format"], "email")
|
||||||
|
self.assertEqual(event.payload["sub_id"]["user"]["email"], user.email)
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import "@goauthentik/admin/common/ak-crypto-certificate-search";
|
import "@goauthentik/admin/common/ak-crypto-certificate-search";
|
||||||
import "@goauthentik/admin/common/ak-flow-search/ak-flow-search";
|
|
||||||
import { BaseProviderForm } from "@goauthentik/admin/providers/BaseProviderForm";
|
import { BaseProviderForm } from "@goauthentik/admin/providers/BaseProviderForm";
|
||||||
import {
|
import {
|
||||||
oauth2ProvidersProvider,
|
oauth2ProvidersProvider,
|
||||||
@ -7,14 +6,11 @@ import {
|
|||||||
} from "@goauthentik/admin/providers/oauth2/OAuth2ProvidersProvider";
|
} from "@goauthentik/admin/providers/oauth2/OAuth2ProvidersProvider";
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { first } from "@goauthentik/common/utils";
|
import { first } from "@goauthentik/common/utils";
|
||||||
import "@goauthentik/components/ak-radio-input";
|
|
||||||
import "@goauthentik/components/ak-text-input";
|
import "@goauthentik/components/ak-text-input";
|
||||||
import "@goauthentik/components/ak-textarea-input";
|
|
||||||
import "@goauthentik/elements/ak-dual-select/ak-dual-select-dynamic-selected-provider.js";
|
import "@goauthentik/elements/ak-dual-select/ak-dual-select-dynamic-selected-provider.js";
|
||||||
import "@goauthentik/elements/ak-dual-select/ak-dual-select-provider.js";
|
import "@goauthentik/elements/ak-dual-select/ak-dual-select-provider.js";
|
||||||
import "@goauthentik/elements/forms/FormGroup";
|
import "@goauthentik/elements/forms/FormGroup";
|
||||||
import "@goauthentik/elements/forms/HorizontalFormElement";
|
import "@goauthentik/elements/forms/HorizontalFormElement";
|
||||||
import "@goauthentik/elements/forms/Radio";
|
|
||||||
import "@goauthentik/elements/forms/SearchSelect";
|
import "@goauthentik/elements/forms/SearchSelect";
|
||||||
import "@goauthentik/elements/utils/TimeDeltaHelp";
|
import "@goauthentik/elements/utils/TimeDeltaHelp";
|
||||||
|
|
||||||
@ -75,9 +71,9 @@ export class SSFProviderFormPage extends BaseProviderForm<SSFProvider> {
|
|||||||
<p class="pf-c-form__helper-text">${msg("Key used to sign the events.")}</p>
|
<p class="pf-c-form__helper-text">${msg("Key used to sign the events.")}</p>
|
||||||
</ak-form-element-horizontal>
|
</ak-form-element-horizontal>
|
||||||
<ak-form-element-horizontal
|
<ak-form-element-horizontal
|
||||||
label=${msg("Session duration")}
|
label=${msg("Event Retention")}
|
||||||
?required=${true}
|
required
|
||||||
name="sessionDuration"
|
name="eventRetention"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
Reference in New Issue
Block a user