core: add API Endpoint to get all MFA devices, add web ui to delete MFA devices of any user

closes #3237

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2022-07-28 23:50:25 +02:00
parent b82a142745
commit 83eba36f8d
21 changed files with 758 additions and 26 deletions

View File

@ -14,7 +14,7 @@ from authentik.api.v3.config import ConfigView
from authentik.api.views import APIBrowserView
from authentik.core.api.applications import ApplicationViewSet
from authentik.core.api.authenticated_sessions import AuthenticatedSessionViewSet
from authentik.core.api.devices import DeviceViewSet
from authentik.core.api.devices import AdminDeviceViewSet, DeviceViewSet
from authentik.core.api.groups import GroupViewSet
from authentik.core.api.propertymappings import PropertyMappingViewSet
from authentik.core.api.providers import ProviderViewSet
@ -171,6 +171,11 @@ router.register("authenticators/sms", SMSDeviceViewSet)
router.register("authenticators/static", StaticDeviceViewSet)
router.register("authenticators/totp", TOTPDeviceViewSet)
router.register("authenticators/webauthn", WebAuthnDeviceViewSet)
router.register(
"authenticators/admin/all",
AdminDeviceViewSet,
basename="admin-device",
)
router.register(
"authenticators/admin/duo",
DuoAdminDeviceViewSet,

View File

@ -98,7 +98,6 @@ class ApplicationViewSet(UsedByMixin, ModelViewSet):
"group",
]
lookup_field = "slug"
filterset_fields = ["name", "slug"]
ordering = ["name"]
def _filter_queryset_for_list(self, queryset: QuerySet) -> QuerySet:

View File

@ -1,9 +1,10 @@
"""Authenticator Devices API Views"""
from django_otp import devices_for_user
from django_otp import device_classes, devices_for_user
from django_otp.models import Device
from drf_spectacular.utils import extend_schema
from rest_framework.fields import CharField, IntegerField, SerializerMethodField
from rest_framework.permissions import IsAuthenticated
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, extend_schema
from rest_framework.fields import BooleanField, CharField, IntegerField, SerializerMethodField
from rest_framework.permissions import IsAdminUser, IsAuthenticated
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.viewsets import ViewSet
@ -17,6 +18,7 @@ class DeviceSerializer(MetaNameSerializer):
pk = IntegerField()
name = CharField()
type = SerializerMethodField()
confirmed = BooleanField()
def get_type(self, instance: Device) -> str:
"""Get type of device"""
@ -34,3 +36,33 @@ class DeviceViewSet(ViewSet):
"""Get all devices for current user"""
devices = devices_for_user(request.user)
return Response(DeviceSerializer(devices, many=True).data)
class AdminDeviceViewSet(ViewSet):
"""Viewset for authenticator devices"""
serializer_class = DeviceSerializer
permission_classes = [IsAdminUser]
def get_devices(self, **kwargs):
"""Get all devices in all child classes"""
for model in device_classes():
device_set = model.objects.filter(**kwargs)
yield from device_set
@extend_schema(
parameters=[
OpenApiParameter(
name="user",
location=OpenApiParameter.QUERY,
type=OpenApiTypes.INT,
)
],
responses={200: DeviceSerializer(many=True)},
)
def list(self, request: Request) -> Response:
"""Get all devices for current user"""
kwargs = {}
if "user" in request.query_params:
kwargs = {"user": request.query_params["user"]}
return Response(DeviceSerializer(self.get_devices(**kwargs), many=True).data)

View File

@ -4,7 +4,7 @@ from rest_framework import mixins
from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.permissions import IsAdminUser
from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
from rest_framework.viewsets import GenericViewSet, ModelViewSet
from authentik.api.authorization import OwnerFilter, OwnerPermissions
from authentik.core.api.used_by import UsedByMixin
@ -72,7 +72,7 @@ class SMSDeviceViewSet(
ordering = ["name"]
class SMSAdminDeviceViewSet(ReadOnlyModelViewSet):
class SMSAdminDeviceViewSet(ModelViewSet):
"""Viewset for sms authenticator devices (for admins)"""
permission_classes = [IsAdminUser]

View File

@ -5,7 +5,7 @@ from rest_framework import mixins
from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.permissions import IsAdminUser
from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
from rest_framework.viewsets import GenericViewSet, ModelViewSet
from authentik.api.authorization import OwnerFilter, OwnerPermissions
from authentik.core.api.used_by import UsedByMixin
@ -71,7 +71,7 @@ class StaticDeviceViewSet(
ordering = ["name"]
class StaticAdminDeviceViewSet(ReadOnlyModelViewSet):
class StaticAdminDeviceViewSet(ModelViewSet):
"""Viewset for static authenticator devices (for admins)"""
permission_classes = [IsAdminUser]

View File

@ -5,7 +5,7 @@ from rest_framework import mixins
from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.permissions import IsAdminUser
from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
from rest_framework.viewsets import GenericViewSet, ModelViewSet
from authentik.api.authorization import OwnerFilter, OwnerPermissions
from authentik.core.api.used_by import UsedByMixin
@ -64,7 +64,7 @@ class TOTPDeviceViewSet(
ordering = ["name"]
class TOTPAdminDeviceViewSet(ReadOnlyModelViewSet):
class TOTPAdminDeviceViewSet(ModelViewSet):
"""Viewset for totp authenticator devices (for admins)"""
permission_classes = [IsAdminUser]

View File

@ -4,7 +4,7 @@ from rest_framework import mixins
from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.permissions import IsAdminUser
from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
from rest_framework.viewsets import GenericViewSet, ModelViewSet
from authentik.api.authorization import OwnerFilter, OwnerPermissions
from authentik.core.api.used_by import UsedByMixin
@ -65,7 +65,7 @@ class WebAuthnDeviceViewSet(
filter_backends = [OwnerFilter, DjangoFilterBackend, OrderingFilter, SearchFilter]
class WebAuthnAdminDeviceViewSet(ReadOnlyModelViewSet):
class WebAuthnAdminDeviceViewSet(ModelViewSet):
"""Viewset for WebAuthn authenticator devices (for admins)"""
permission_classes = [IsAdminUser]

View File

@ -179,6 +179,32 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
/authenticators/admin/all/:
get:
operationId: authenticators_admin_all_list
description: Get all devices for current user
parameters:
- in: query
name: user
schema:
type: integer
tags:
- authenticators
security:
- authentik: []
responses:
'200':
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Device'
description: ''
'400':
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
/authenticators/admin/duo/:
get:
operationId: authenticators_admin_duo_list
@ -407,6 +433,30 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
post:
operationId: authenticators_admin_sms_create
description: Viewset for sms authenticator devices (for admins)
tags:
- authenticators
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SMSDeviceRequest'
required: true
security:
- authentik: []
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/SMSDevice'
description: ''
'400':
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
/authenticators/admin/sms/{id}/:
get:
operationId: authenticators_admin_sms_retrieve
@ -433,6 +483,88 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
put:
operationId: authenticators_admin_sms_update
description: Viewset for sms authenticator devices (for admins)
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this SMS Device.
required: true
tags:
- authenticators
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SMSDeviceRequest'
required: true
security:
- authentik: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/SMSDevice'
description: ''
'400':
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
patch:
operationId: authenticators_admin_sms_partial_update
description: Viewset for sms authenticator devices (for admins)
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this SMS Device.
required: true
tags:
- authenticators
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedSMSDeviceRequest'
security:
- authentik: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/SMSDevice'
description: ''
'400':
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
delete:
operationId: authenticators_admin_sms_destroy
description: Viewset for sms authenticator devices (for admins)
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this SMS Device.
required: true
tags:
- authenticators
security:
- authentik: []
responses:
'204':
description: No response body
'400':
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
/authenticators/admin/static/:
get:
operationId: authenticators_admin_static_list
@ -481,6 +613,30 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
post:
operationId: authenticators_admin_static_create
description: Viewset for static authenticator devices (for admins)
tags:
- authenticators
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/StaticDeviceRequest'
required: true
security:
- authentik: []
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/StaticDevice'
description: ''
'400':
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
/authenticators/admin/static/{id}/:
get:
operationId: authenticators_admin_static_retrieve
@ -507,6 +663,88 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
put:
operationId: authenticators_admin_static_update
description: Viewset for static authenticator devices (for admins)
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this static device.
required: true
tags:
- authenticators
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/StaticDeviceRequest'
required: true
security:
- authentik: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/StaticDevice'
description: ''
'400':
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
patch:
operationId: authenticators_admin_static_partial_update
description: Viewset for static authenticator devices (for admins)
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this static device.
required: true
tags:
- authenticators
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedStaticDeviceRequest'
security:
- authentik: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/StaticDevice'
description: ''
'400':
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
delete:
operationId: authenticators_admin_static_destroy
description: Viewset for static authenticator devices (for admins)
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this static device.
required: true
tags:
- authenticators
security:
- authentik: []
responses:
'204':
description: No response body
'400':
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
/authenticators/admin/totp/:
get:
operationId: authenticators_admin_totp_list
@ -555,6 +793,30 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
post:
operationId: authenticators_admin_totp_create
description: Viewset for totp authenticator devices (for admins)
tags:
- authenticators
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/TOTPDeviceRequest'
required: true
security:
- authentik: []
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/TOTPDevice'
description: ''
'400':
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
/authenticators/admin/totp/{id}/:
get:
operationId: authenticators_admin_totp_retrieve
@ -581,6 +843,88 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
put:
operationId: authenticators_admin_totp_update
description: Viewset for totp authenticator devices (for admins)
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this TOTP device.
required: true
tags:
- authenticators
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/TOTPDeviceRequest'
required: true
security:
- authentik: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/TOTPDevice'
description: ''
'400':
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
patch:
operationId: authenticators_admin_totp_partial_update
description: Viewset for totp authenticator devices (for admins)
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this TOTP device.
required: true
tags:
- authenticators
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedTOTPDeviceRequest'
security:
- authentik: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/TOTPDevice'
description: ''
'400':
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
delete:
operationId: authenticators_admin_totp_destroy
description: Viewset for totp authenticator devices (for admins)
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this TOTP device.
required: true
tags:
- authenticators
security:
- authentik: []
responses:
'204':
description: No response body
'400':
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
/authenticators/admin/webauthn/:
get:
operationId: authenticators_admin_webauthn_list
@ -629,6 +973,30 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
post:
operationId: authenticators_admin_webauthn_create
description: Viewset for WebAuthn authenticator devices (for admins)
tags:
- authenticators
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/WebAuthnDeviceRequest'
required: true
security:
- authentik: []
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/WebAuthnDevice'
description: ''
'400':
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
/authenticators/admin/webauthn/{id}/:
get:
operationId: authenticators_admin_webauthn_retrieve
@ -655,6 +1023,88 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
put:
operationId: authenticators_admin_webauthn_update
description: Viewset for WebAuthn authenticator devices (for admins)
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this WebAuthn Device.
required: true
tags:
- authenticators
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/WebAuthnDeviceRequest'
required: true
security:
- authentik: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/WebAuthnDevice'
description: ''
'400':
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
patch:
operationId: authenticators_admin_webauthn_partial_update
description: Viewset for WebAuthn authenticator devices (for admins)
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this WebAuthn Device.
required: true
tags:
- authenticators
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedWebAuthnDeviceRequest'
security:
- authentik: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/WebAuthnDevice'
description: ''
'400':
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
delete:
operationId: authenticators_admin_webauthn_destroy
description: Viewset for WebAuthn authenticator devices (for admins)
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this WebAuthn Device.
required: true
tags:
- authenticators
security:
- authentik: []
responses:
'204':
description: No response body
'400':
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
/authenticators/all/:
get:
operationId: authenticators_all_list
@ -1601,6 +2051,22 @@ paths:
operationId: core_applications_list
description: Custom list method that checks Policy based access instead of guardian
parameters:
- in: query
name: group
schema:
type: string
- in: query
name: meta_description
schema:
type: string
- in: query
name: meta_launch_url
schema:
type: string
- in: query
name: meta_publisher
schema:
type: string
- in: query
name: name
schema:
@ -20742,7 +21208,10 @@ components:
type:
type: string
readOnly: true
confirmed:
type: boolean
required:
- confirmed
- meta_model_name
- name
- pk

View File

@ -0,0 +1,95 @@
import { AKResponse } from "@goauthentik/web/api/Client";
import { DEFAULT_CONFIG } from "@goauthentik/web/api/Config";
import "@goauthentik/web/elements/forms/DeleteBulkForm";
import { TableColumn } from "@goauthentik/web/elements/table/Table";
import {
MFADevicesPage,
deviceTypeName,
} from "@goauthentik/web/user/user-settings/mfa/MFADevicesPage";
import { t } from "@lingui/macro";
import { TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { AuthenticatorsApi, Device } from "@goauthentik/api";
@customElement("ak-user-device-list")
export class UserDeviceList extends MFADevicesPage {
@property({ type: Number })
userId?: number;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async apiEndpoint(page: number): Promise<AKResponse<Device>> {
return new AuthenticatorsApi(DEFAULT_CONFIG)
.authenticatorsAdminAllList({
user: this.userId,
})
.then((res) => {
return {
pagination: {
count: res.length,
current: 1,
totalPages: 1,
startIndex: 1,
endIndex: res.length,
},
results: res,
};
});
}
async deleteWrapper(device: Device) {
switch (device.type) {
case "authentik_stages_authenticator_duo.DuoDevice":
return new AuthenticatorsApi(DEFAULT_CONFIG).authenticatorsAdminDuoDestroy({
id: device.pk,
});
case "authentik_stages_authenticator_sms.SMSDevice":
return new AuthenticatorsApi(DEFAULT_CONFIG).authenticatorsAdminSmsDestroy({
id: device.pk,
});
case "otp_totp.TOTPDevice":
return new AuthenticatorsApi(DEFAULT_CONFIG).authenticatorsAdminTotpDestroy({
id: device.pk,
});
case "otp_static.StaticDevice":
return new AuthenticatorsApi(DEFAULT_CONFIG).authenticatorsAdminStaticDestroy({
id: device.pk,
});
case "authentik_stages_authenticator_webauthn.WebAuthnDevice":
return new AuthenticatorsApi(DEFAULT_CONFIG).authenticatorsAdminWebauthnDestroy({
id: device.pk,
});
default:
break;
}
}
columns(): TableColumn[] {
return [
new TableColumn(t`Name`, ""),
new TableColumn(t`Type`, ""),
new TableColumn(t`Confirmed`, ""),
];
}
renderToolbar(): TemplateResult {
return html` <ak-spinner-button
.callAction=${() => {
return this.fetch();
}}
class="pf-m-secondary"
>
${t`Refresh`}</ak-spinner-button
>`;
}
row(item: Device): TemplateResult[] {
return [
html`${item.name}`,
html`${deviceTypeName(item)}`,
html`${item.confirmed ? t`Yes` : t`No`}`,
];
}
}

View File

@ -1151,6 +1151,10 @@ msgstr "Konfiguriere visuelle Einstellungen und Standards für verschiedene Doma
msgid "Configure what data should be used as unique User Identifier. For most cases, the default should be fine."
msgstr "onfigurieren Sie, welche Daten als eindeutige Benutzerkennung verwendet werden sollen. In den meisten Fällen sollte die Standardeinstellung in Ordnung sein."
#: src/elements/user/UserDevicesList.ts
msgid "Confirmed"
msgstr ""
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
#: src/user/user-settings/sources/SourceSettingsPlex.ts
msgid "Connect"
@ -3198,6 +3202,10 @@ msgstr ""
msgid "MESSAGE_CONTINUE will follow the ?next parameter if set, otherwise show a message."
msgstr ""
#: src/pages/users/UserViewPage.ts
msgid "MFA Authenticators"
msgstr ""
#: src/user/user-settings/UserSettingsPage.ts
msgid "MFA Devices"
msgstr "Multifaktor-Authentifzierungs Geräte"
@ -3342,6 +3350,7 @@ msgid "My applications"
msgstr "Meine Anwendungen"
#: src/elements/forms/DeleteBulkForm.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationForm.ts
#: src/pages/applications/ApplicationListPage.ts
#: src/pages/applications/wizard/InitialApplicationWizardPage.ts
@ -3515,6 +3524,7 @@ msgid "Nginx (standalone)"
msgstr "Nginx (eigenständig)"
#: src/elements/oauth/UserRefreshList.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationCheckAccessForm.ts
#: src/pages/crypto/CertificateKeyPairListPage.ts
#: src/pages/groups/GroupListPage.ts
@ -5988,6 +5998,7 @@ msgstr "Twilio Konto SID"
msgid "Twilio Auth Token"
msgstr "Twilio Authentifizierungs Token"
#: src/elements/user/UserDevicesList.ts
#: src/pages/flows/BoundStagesList.ts
#: src/pages/outposts/OutpostForm.ts
#: src/pages/outposts/OutpostListPage.ts
@ -6795,6 +6806,7 @@ msgid "XML-based SSO standard. Use this if your application only supports SAML."
msgstr ""
#: src/elements/oauth/UserRefreshList.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationCheckAccessForm.ts
#: src/pages/groups/GroupListPage.ts
#: src/pages/groups/MemberSelectModal.ts

View File

@ -1158,6 +1158,10 @@ msgstr "Configure visual settings and defaults for different domains."
msgid "Configure what data should be used as unique User Identifier. For most cases, the default should be fine."
msgstr "Configure what data should be used as unique User Identifier. For most cases, the default should be fine."
#: src/elements/user/UserDevicesList.ts
msgid "Confirmed"
msgstr "Confirmed"
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
#: src/user/user-settings/sources/SourceSettingsPlex.ts
msgid "Connect"
@ -3250,6 +3254,10 @@ msgstr "MESSAGE will notify the user the flow isn't applicable."
msgid "MESSAGE_CONTINUE will follow the ?next parameter if set, otherwise show a message."
msgstr "MESSAGE_CONTINUE will follow the ?next parameter if set, otherwise show a message."
#: src/pages/users/UserViewPage.ts
msgid "MFA Authenticators"
msgstr "MFA Authenticators"
#: src/user/user-settings/UserSettingsPage.ts
msgid "MFA Devices"
msgstr "MFA Devices"
@ -3395,6 +3403,7 @@ msgid "My applications"
msgstr "My applications"
#: src/elements/forms/DeleteBulkForm.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationForm.ts
#: src/pages/applications/ApplicationListPage.ts
#: src/pages/applications/wizard/InitialApplicationWizardPage.ts
@ -3568,6 +3577,7 @@ msgid "Nginx (standalone)"
msgstr "Nginx (standalone)"
#: src/elements/oauth/UserRefreshList.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationCheckAccessForm.ts
#: src/pages/crypto/CertificateKeyPairListPage.ts
#: src/pages/groups/GroupListPage.ts
@ -6108,6 +6118,7 @@ msgstr "Twilio Account SID"
msgid "Twilio Auth Token"
msgstr "Twilio Auth Token"
#: src/elements/user/UserDevicesList.ts
#: src/pages/flows/BoundStagesList.ts
#: src/pages/outposts/OutpostForm.ts
#: src/pages/outposts/OutpostListPage.ts
@ -6925,6 +6936,7 @@ msgid "XML-based SSO standard. Use this if your application only supports SAML."
msgstr "XML-based SSO standard. Use this if your application only supports SAML."
#: src/elements/oauth/UserRefreshList.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationCheckAccessForm.ts
#: src/pages/groups/GroupListPage.ts
#: src/pages/groups/MemberSelectModal.ts

View File

@ -1142,6 +1142,10 @@ msgstr "Configure los ajustes visuales y los valores predeterminados para los di
msgid "Configure what data should be used as unique User Identifier. For most cases, the default should be fine."
msgstr "Configure qué datos deben usarse como identificador de usuario único. En la mayoría de los casos, el valor predeterminado debería estar bien."
#: src/elements/user/UserDevicesList.ts
msgid "Confirmed"
msgstr ""
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
#: src/user/user-settings/sources/SourceSettingsPlex.ts
msgid "Connect"
@ -3191,6 +3195,10 @@ msgstr ""
msgid "MESSAGE_CONTINUE will follow the ?next parameter if set, otherwise show a message."
msgstr ""
#: src/pages/users/UserViewPage.ts
msgid "MFA Authenticators"
msgstr ""
#: src/user/user-settings/UserSettingsPage.ts
msgid "MFA Devices"
msgstr "Dispositivos de MFA"
@ -3335,6 +3343,7 @@ msgid "My applications"
msgstr "Mis solicitudes"
#: src/elements/forms/DeleteBulkForm.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationForm.ts
#: src/pages/applications/ApplicationListPage.ts
#: src/pages/applications/wizard/InitialApplicationWizardPage.ts
@ -3508,6 +3517,7 @@ msgid "Nginx (standalone)"
msgstr "Nginx (independiente)"
#: src/elements/oauth/UserRefreshList.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationCheckAccessForm.ts
#: src/pages/crypto/CertificateKeyPairListPage.ts
#: src/pages/groups/GroupListPage.ts
@ -5982,6 +5992,7 @@ msgstr "SID de cuenta Twilio"
msgid "Twilio Auth Token"
msgstr "Token de autenticación de Twilio"
#: src/elements/user/UserDevicesList.ts
#: src/pages/flows/BoundStagesList.ts
#: src/pages/outposts/OutpostForm.ts
#: src/pages/outposts/OutpostListPage.ts
@ -6789,6 +6800,7 @@ msgid "XML-based SSO standard. Use this if your application only supports SAML."
msgstr ""
#: src/elements/oauth/UserRefreshList.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationCheckAccessForm.ts
#: src/pages/groups/GroupListPage.ts
#: src/pages/groups/MemberSelectModal.ts

View File

@ -1151,6 +1151,10 @@ msgstr "Configure le paramètres visuels et par défaut des différents domaines
msgid "Configure what data should be used as unique User Identifier. For most cases, the default should be fine."
msgstr "Configure quelle donnée utiliser pour l'identifiant unique utilisateur. La valeur par défaut devrait être correcte dans la plupart des cas."
#: src/elements/user/UserDevicesList.ts
msgid "Confirmed"
msgstr ""
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
#: src/user/user-settings/sources/SourceSettingsPlex.ts
msgid "Connect"
@ -3222,6 +3226,10 @@ msgstr ""
msgid "MESSAGE_CONTINUE will follow the ?next parameter if set, otherwise show a message."
msgstr ""
#: src/pages/users/UserViewPage.ts
msgid "MFA Authenticators"
msgstr ""
#: src/user/user-settings/UserSettingsPage.ts
msgid "MFA Devices"
msgstr ""
@ -3366,6 +3374,7 @@ msgid "My applications"
msgstr "Mes applications"
#: src/elements/forms/DeleteBulkForm.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationForm.ts
#: src/pages/applications/ApplicationListPage.ts
#: src/pages/applications/wizard/InitialApplicationWizardPage.ts
@ -3539,6 +3548,7 @@ msgid "Nginx (standalone)"
msgstr ""
#: src/elements/oauth/UserRefreshList.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationCheckAccessForm.ts
#: src/pages/crypto/CertificateKeyPairListPage.ts
#: src/pages/groups/GroupListPage.ts
@ -6040,6 +6050,7 @@ msgstr ""
msgid "Twilio Auth Token"
msgstr ""
#: src/elements/user/UserDevicesList.ts
#: src/pages/flows/BoundStagesList.ts
#: src/pages/outposts/OutpostForm.ts
#: src/pages/outposts/OutpostListPage.ts
@ -6850,6 +6861,7 @@ msgid "XML-based SSO standard. Use this if your application only supports SAML."
msgstr ""
#: src/elements/oauth/UserRefreshList.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationCheckAccessForm.ts
#: src/pages/groups/GroupListPage.ts
#: src/pages/groups/MemberSelectModal.ts

View File

@ -1139,6 +1139,10 @@ msgstr "Skonfiguruj ustawienia wizualne i domyślne dla różnych domen."
msgid "Configure what data should be used as unique User Identifier. For most cases, the default should be fine."
msgstr "Skonfiguruj, jakie dane mają być używane jako unikalny identyfikator użytkownika. W większości przypadków wartość domyślna powinna być w porządku."
#: src/elements/user/UserDevicesList.ts
msgid "Confirmed"
msgstr ""
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
#: src/user/user-settings/sources/SourceSettingsPlex.ts
msgid "Connect"
@ -3188,6 +3192,10 @@ msgstr ""
msgid "MESSAGE_CONTINUE will follow the ?next parameter if set, otherwise show a message."
msgstr ""
#: src/pages/users/UserViewPage.ts
msgid "MFA Authenticators"
msgstr ""
#: src/user/user-settings/UserSettingsPage.ts
msgid "MFA Devices"
msgstr "Urządzenia MFA"
@ -3332,6 +3340,7 @@ msgid "My applications"
msgstr "Moje aplikacje"
#: src/elements/forms/DeleteBulkForm.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationForm.ts
#: src/pages/applications/ApplicationListPage.ts
#: src/pages/applications/wizard/InitialApplicationWizardPage.ts
@ -3505,6 +3514,7 @@ msgid "Nginx (standalone)"
msgstr "Nginx (standalone)"
#: src/elements/oauth/UserRefreshList.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationCheckAccessForm.ts
#: src/pages/crypto/CertificateKeyPairListPage.ts
#: src/pages/groups/GroupListPage.ts
@ -5979,6 +5989,7 @@ msgstr "Twilio Account SID"
msgid "Twilio Auth Token"
msgstr "Twilio Auth Token"
#: src/elements/user/UserDevicesList.ts
#: src/pages/flows/BoundStagesList.ts
#: src/pages/outposts/OutpostForm.ts
#: src/pages/outposts/OutpostListPage.ts
@ -6786,6 +6797,7 @@ msgid "XML-based SSO standard. Use this if your application only supports SAML."
msgstr ""
#: src/elements/oauth/UserRefreshList.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationCheckAccessForm.ts
#: src/pages/groups/GroupListPage.ts
#: src/pages/groups/MemberSelectModal.ts

View File

@ -1146,6 +1146,10 @@ msgstr ""
msgid "Configure what data should be used as unique User Identifier. For most cases, the default should be fine."
msgstr ""
#: src/elements/user/UserDevicesList.ts
msgid "Confirmed"
msgstr ""
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
#: src/user/user-settings/sources/SourceSettingsPlex.ts
msgid "Connect"
@ -3232,6 +3236,10 @@ msgstr ""
msgid "MESSAGE_CONTINUE will follow the ?next parameter if set, otherwise show a message."
msgstr ""
#: src/pages/users/UserViewPage.ts
msgid "MFA Authenticators"
msgstr ""
#: src/user/user-settings/UserSettingsPage.ts
msgid "MFA Devices"
msgstr ""
@ -3377,6 +3385,7 @@ msgid "My applications"
msgstr ""
#: src/elements/forms/DeleteBulkForm.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationForm.ts
#: src/pages/applications/ApplicationListPage.ts
#: src/pages/applications/wizard/InitialApplicationWizardPage.ts
@ -3550,6 +3559,7 @@ msgid "Nginx (standalone)"
msgstr ""
#: src/elements/oauth/UserRefreshList.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationCheckAccessForm.ts
#: src/pages/crypto/CertificateKeyPairListPage.ts
#: src/pages/groups/GroupListPage.ts
@ -6078,6 +6088,7 @@ msgstr ""
msgid "Twilio Auth Token"
msgstr ""
#: src/elements/user/UserDevicesList.ts
#: src/pages/flows/BoundStagesList.ts
#: src/pages/outposts/OutpostForm.ts
#: src/pages/outposts/OutpostListPage.ts
@ -6891,6 +6902,7 @@ msgid "XML-based SSO standard. Use this if your application only supports SAML."
msgstr ""
#: src/elements/oauth/UserRefreshList.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationCheckAccessForm.ts
#: src/pages/groups/GroupListPage.ts
#: src/pages/groups/MemberSelectModal.ts

View File

@ -1142,6 +1142,10 @@ msgstr "Farklı etki alanları için görsel ayarları ve varsayılanları yapı
msgid "Configure what data should be used as unique User Identifier. For most cases, the default should be fine."
msgstr "Hangi verilerin benzersiz Kullanıcı Tanımlayıcısı olarak kullanılması gerektiğini yapılandırın. Çoğu durumda, varsayılan seçim yeterlidir."
#: src/elements/user/UserDevicesList.ts
msgid "Confirmed"
msgstr ""
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
#: src/user/user-settings/sources/SourceSettingsPlex.ts
msgid "Connect"
@ -3192,6 +3196,10 @@ msgstr ""
msgid "MESSAGE_CONTINUE will follow the ?next parameter if set, otherwise show a message."
msgstr ""
#: src/pages/users/UserViewPage.ts
msgid "MFA Authenticators"
msgstr ""
#: src/user/user-settings/UserSettingsPage.ts
msgid "MFA Devices"
msgstr "MFA Cihazları"
@ -3336,6 +3344,7 @@ msgid "My applications"
msgstr "Uygulamalarım"
#: src/elements/forms/DeleteBulkForm.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationForm.ts
#: src/pages/applications/ApplicationListPage.ts
#: src/pages/applications/wizard/InitialApplicationWizardPage.ts
@ -3509,6 +3518,7 @@ msgid "Nginx (standalone)"
msgstr "Nginx (bağımsız)"
#: src/elements/oauth/UserRefreshList.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationCheckAccessForm.ts
#: src/pages/crypto/CertificateKeyPairListPage.ts
#: src/pages/groups/GroupListPage.ts
@ -5984,6 +5994,7 @@ msgstr "Twilio Hesabı SID"
msgid "Twilio Auth Token"
msgstr "Twilio Auth Belirteci"
#: src/elements/user/UserDevicesList.ts
#: src/pages/flows/BoundStagesList.ts
#: src/pages/outposts/OutpostForm.ts
#: src/pages/outposts/OutpostListPage.ts
@ -6791,6 +6802,7 @@ msgid "XML-based SSO standard. Use this if your application only supports SAML."
msgstr ""
#: src/elements/oauth/UserRefreshList.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationCheckAccessForm.ts
#: src/pages/groups/GroupListPage.ts
#: src/pages/groups/MemberSelectModal.ts

View File

@ -1137,6 +1137,10 @@ msgstr "配置不同域名的可视化设置和默认值。"
msgid "Configure what data should be used as unique User Identifier. For most cases, the default should be fine."
msgstr "配置应将哪些数据用作唯一用户标识符。在大多数情况下保持默认值即可。"
#: src/elements/user/UserDevicesList.ts
msgid "Confirmed"
msgstr ""
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
#: src/user/user-settings/sources/SourceSettingsPlex.ts
msgid "Connect"
@ -3174,6 +3178,10 @@ msgstr ""
msgid "MESSAGE_CONTINUE will follow the ?next parameter if set, otherwise show a message."
msgstr ""
#: src/pages/users/UserViewPage.ts
msgid "MFA Authenticators"
msgstr ""
#: src/user/user-settings/UserSettingsPage.ts
msgid "MFA Devices"
msgstr "MFA 设备"
@ -3318,6 +3326,7 @@ msgid "My applications"
msgstr "我的应用"
#: src/elements/forms/DeleteBulkForm.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationForm.ts
#: src/pages/applications/ApplicationListPage.ts
#: src/pages/applications/wizard/InitialApplicationWizardPage.ts
@ -3491,6 +3500,7 @@ msgid "Nginx (standalone)"
msgstr "Nginx独立"
#: src/elements/oauth/UserRefreshList.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationCheckAccessForm.ts
#: src/pages/crypto/CertificateKeyPairListPage.ts
#: src/pages/groups/GroupListPage.ts
@ -5945,6 +5955,7 @@ msgstr "Twilio 账户 SID"
msgid "Twilio Auth Token"
msgstr "Twilio 身份验证令牌"
#: src/elements/user/UserDevicesList.ts
#: src/pages/flows/BoundStagesList.ts
#: src/pages/outposts/OutpostForm.ts
#: src/pages/outposts/OutpostListPage.ts
@ -6753,6 +6764,7 @@ msgid "XML-based SSO standard. Use this if your application only supports SAML."
msgstr ""
#: src/elements/oauth/UserRefreshList.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationCheckAccessForm.ts
#: src/pages/groups/GroupListPage.ts
#: src/pages/groups/MemberSelectModal.ts

View File

@ -1139,6 +1139,10 @@ msgstr "配置不同域的可视化设置和默认值。"
msgid "Configure what data should be used as unique User Identifier. For most cases, the default should be fine."
msgstr "配置应将哪些数据用作唯一用户标识符。在大多数情况下,默认值应该没问题。"
#: src/elements/user/UserDevicesList.ts
msgid "Confirmed"
msgstr ""
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
#: src/user/user-settings/sources/SourceSettingsPlex.ts
msgid "Connect"
@ -3178,6 +3182,10 @@ msgstr ""
msgid "MESSAGE_CONTINUE will follow the ?next parameter if set, otherwise show a message."
msgstr ""
#: src/pages/users/UserViewPage.ts
msgid "MFA Authenticators"
msgstr ""
#: src/user/user-settings/UserSettingsPage.ts
msgid "MFA Devices"
msgstr "MFA 设备"
@ -3322,6 +3330,7 @@ msgid "My applications"
msgstr "我的应用"
#: src/elements/forms/DeleteBulkForm.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationForm.ts
#: src/pages/applications/ApplicationListPage.ts
#: src/pages/applications/wizard/InitialApplicationWizardPage.ts
@ -3495,6 +3504,7 @@ msgid "Nginx (standalone)"
msgstr "Nginx (standalone)"
#: src/elements/oauth/UserRefreshList.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationCheckAccessForm.ts
#: src/pages/crypto/CertificateKeyPairListPage.ts
#: src/pages/groups/GroupListPage.ts
@ -5954,6 +5964,7 @@ msgstr "Twilio 账户 SID"
msgid "Twilio Auth Token"
msgstr "Twilio 身份验证令牌"
#: src/elements/user/UserDevicesList.ts
#: src/pages/flows/BoundStagesList.ts
#: src/pages/outposts/OutpostForm.ts
#: src/pages/outposts/OutpostListPage.ts
@ -6763,6 +6774,7 @@ msgid "XML-based SSO standard. Use this if your application only supports SAML."
msgstr ""
#: src/elements/oauth/UserRefreshList.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationCheckAccessForm.ts
#: src/pages/groups/GroupListPage.ts
#: src/pages/groups/MemberSelectModal.ts

View File

@ -1139,6 +1139,10 @@ msgstr "配置不同域的可视化设置和默认值。"
msgid "Configure what data should be used as unique User Identifier. For most cases, the default should be fine."
msgstr "配置应将哪些数据用作唯一用户标识符。在大多数情况下,默认值应该没问题。"
#: src/elements/user/UserDevicesList.ts
msgid "Confirmed"
msgstr ""
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
#: src/user/user-settings/sources/SourceSettingsPlex.ts
msgid "Connect"
@ -3178,6 +3182,10 @@ msgstr ""
msgid "MESSAGE_CONTINUE will follow the ?next parameter if set, otherwise show a message."
msgstr ""
#: src/pages/users/UserViewPage.ts
msgid "MFA Authenticators"
msgstr ""
#: src/user/user-settings/UserSettingsPage.ts
msgid "MFA Devices"
msgstr "MFA 设备"
@ -3322,6 +3330,7 @@ msgid "My applications"
msgstr "我的应用"
#: src/elements/forms/DeleteBulkForm.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationForm.ts
#: src/pages/applications/ApplicationListPage.ts
#: src/pages/applications/wizard/InitialApplicationWizardPage.ts
@ -3495,6 +3504,7 @@ msgid "Nginx (standalone)"
msgstr "Nginx (standalone)"
#: src/elements/oauth/UserRefreshList.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationCheckAccessForm.ts
#: src/pages/crypto/CertificateKeyPairListPage.ts
#: src/pages/groups/GroupListPage.ts
@ -5954,6 +5964,7 @@ msgstr "Twilio 账户 SID"
msgid "Twilio Auth Token"
msgstr "Twilio 身份验证令牌"
#: src/elements/user/UserDevicesList.ts
#: src/pages/flows/BoundStagesList.ts
#: src/pages/outposts/OutpostForm.ts
#: src/pages/outposts/OutpostListPage.ts
@ -6763,6 +6774,7 @@ msgid "XML-based SSO standard. Use this if your application only supports SAML."
msgstr ""
#: src/elements/oauth/UserRefreshList.ts
#: src/elements/user/UserDevicesList.ts
#: src/pages/applications/ApplicationCheckAccessForm.ts
#: src/pages/groups/GroupListPage.ts
#: src/pages/groups/MemberSelectModal.ts

View File

@ -16,6 +16,7 @@ import { showMessage } from "@goauthentik/web/elements/messages/MessageContainer
import "@goauthentik/web/elements/oauth/UserRefreshList";
import "@goauthentik/web/elements/user/SessionList";
import "@goauthentik/web/elements/user/UserConsentList";
import "@goauthentik/web/elements/user/UserDevicesList";
import "@goauthentik/web/pages/groups/RelatedGroupList";
import "@goauthentik/web/pages/users/UserActiveForm";
import "@goauthentik/web/pages/users/UserForm";
@ -351,6 +352,17 @@ export class UserViewPage extends LitElement {
</div>
</div>
</section>
<section
slot="page-mfa-authenticators"
data-tab-title="${t`MFA Authenticators`}"
class="pf-c-page__main-section pf-m-no-padding-mobile"
>
<div class="pf-c-card">
<div class="pf-c-card__body">
<ak-user-device-list userId=${this.user.pk}> </ak-user-device-list>
</div>
</div>
</section>
</ak-tabs>`;
}
}

View File

@ -34,6 +34,17 @@ export function stageToAuthenticatorName(stage: UserSetting): string {
return `Invalid stage component ${stage.component}`;
}
export function deviceTypeName(device: Device): string {
switch (device.type) {
case "otp_static.StaticDevice":
return t`Static tokens`;
case "otp_totp.TOTPDevice":
return t`TOTP Device`;
default:
return device.verboseName;
}
}
@customElement("ak-user-settings-mfa")
export class MFADevicesPage extends Table<Device> {
@property({ attribute: false })
@ -143,21 +154,10 @@ export class MFADevicesPage extends Table<Device> {
</ak-forms-delete-bulk>`;
}
deviceTypeName(device: Device): string {
switch (device.type) {
case "otp_static.StaticDevice":
return t`Static tokens`;
case "otp_totp.TOTPDevice":
return t`TOTP Device`;
default:
return device.verboseName;
}
}
row(item: Device): TemplateResult[] {
return [
html`${item.name}`,
html`${this.deviceTypeName(item)}`,
html`${deviceTypeName(item)}`,
html`
<ak-forms-modal>
<span slot="submit">${t`Update`}</span>