diff --git a/authentik/api/v2/urls.py b/authentik/api/v2/urls.py index 51fd9bbb8..6dce33066 100644 --- a/authentik/api/v2/urls.py +++ b/authentik/api/v2/urls.py @@ -64,7 +64,11 @@ from authentik.sources.oauth.api.source_connection import ( ) from authentik.sources.plex.api import PlexSourceViewSet from authentik.sources.saml.api import SAMLSourceViewSet -from authentik.stages.authenticator_duo.api import AuthenticatorDuoStageViewSet +from authentik.stages.authenticator_duo.api import ( + AuthenticatorDuoStageViewSet, + DuoAdminDeviceViewSet, + DuoDeviceViewSet, +) from authentik.stages.authenticator_static.api import ( AuthenticatorStaticStageViewSet, StaticAdminDeviceViewSet, @@ -159,9 +163,15 @@ router.register("propertymappings/ldap", LDAPPropertyMappingViewSet) router.register("propertymappings/saml", SAMLPropertyMappingViewSet) router.register("propertymappings/scope", ScopeMappingViewSet) +router.register("authenticators/duo", DuoDeviceViewSet) router.register("authenticators/static", StaticDeviceViewSet) router.register("authenticators/totp", TOTPDeviceViewSet) router.register("authenticators/webauthn", WebAuthnDeviceViewSet) +router.register( + "authenticators/admin/duo", + DuoAdminDeviceViewSet, + basename="admin-duodevice", +) router.register( "authenticators/admin/static", StaticAdminDeviceViewSet, diff --git a/authentik/stages/authenticator_duo/models.py b/authentik/stages/authenticator_duo/models.py index 25a938aaa..7edd1bda5 100644 --- a/authentik/stages/authenticator_duo/models.py +++ b/authentik/stages/authenticator_duo/models.py @@ -15,7 +15,7 @@ from authentik.flows.models import ConfigurableStage, Stage class AuthenticatorDuoStage(ConfigurableStage, Stage): - """Duo stage""" + """Setup Duo authenticator devices""" client_id = models.TextField() client_secret = models.TextField() diff --git a/schema.yml b/schema.yml index b5c1abaae..a3ba86cb1 100644 --- a/schema.yml +++ b/schema.yml @@ -167,6 +167,82 @@ paths: $ref: '#/components/schemas/ValidationError' '403': $ref: '#/components/schemas/GenericError' + /api/v2beta/authenticators/admin/duo/: + get: + operationId: authenticators_admin_duo_list + description: Viewset for Duo authenticator devices (for admins) + parameters: + - in: query + name: name + schema: + type: string + - name: ordering + required: false + in: query + description: Which field to use when ordering the results. + schema: + type: string + - name: page + required: false + in: query + description: A page number within the paginated result set. + schema: + type: integer + - name: page_size + required: false + in: query + description: Number of results to return per page. + schema: + type: integer + - name: search + required: false + in: query + description: A search term. + schema: + type: string + tags: + - authenticators + security: + - authentik: [] + - cookieAuth: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/PaginatedDuoDeviceList' + description: '' + '400': + $ref: '#/components/schemas/ValidationError' + '403': + $ref: '#/components/schemas/GenericError' + /api/v2beta/authenticators/admin/duo/{id}/: + get: + operationId: authenticators_admin_duo_retrieve + description: Viewset for Duo authenticator devices (for admins) + parameters: + - in: path + name: id + schema: + type: integer + description: A unique integer value identifying this Duo Device. + required: true + tags: + - authenticators + security: + - authentik: [] + - cookieAuth: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/DuoDevice' + description: '' + '400': + $ref: '#/components/schemas/ValidationError' + '403': + $ref: '#/components/schemas/GenericError' /api/v2beta/authenticators/admin/static/: get: operationId: authenticators_admin_static_list @@ -395,6 +471,179 @@ paths: $ref: '#/components/schemas/ValidationError' '403': $ref: '#/components/schemas/GenericError' + /api/v2beta/authenticators/duo/: + get: + operationId: authenticators_duo_list + description: Viewset for Duo authenticator devices + parameters: + - in: query + name: name + schema: + type: string + - name: ordering + required: false + in: query + description: Which field to use when ordering the results. + schema: + type: string + - name: page + required: false + in: query + description: A page number within the paginated result set. + schema: + type: integer + - name: page_size + required: false + in: query + description: Number of results to return per page. + schema: + type: integer + - name: search + required: false + in: query + description: A search term. + schema: + type: string + tags: + - authenticators + security: + - authentik: [] + - cookieAuth: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/PaginatedDuoDeviceList' + description: '' + '400': + $ref: '#/components/schemas/ValidationError' + '403': + $ref: '#/components/schemas/GenericError' + /api/v2beta/authenticators/duo/{id}/: + get: + operationId: authenticators_duo_retrieve + description: Viewset for Duo authenticator devices + parameters: + - in: path + name: id + schema: + type: integer + description: A unique integer value identifying this Duo Device. + required: true + tags: + - authenticators + security: + - authentik: [] + - cookieAuth: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/DuoDevice' + description: '' + '400': + $ref: '#/components/schemas/ValidationError' + '403': + $ref: '#/components/schemas/GenericError' + put: + operationId: authenticators_duo_update + description: Viewset for Duo authenticator devices + parameters: + - in: path + name: id + schema: + type: integer + description: A unique integer value identifying this Duo Device. + required: true + tags: + - authenticators + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/DuoDeviceRequest' + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/DuoDeviceRequest' + multipart/form-data: + schema: + $ref: '#/components/schemas/DuoDeviceRequest' + required: true + security: + - authentik: [] + - cookieAuth: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/DuoDevice' + description: '' + '400': + $ref: '#/components/schemas/ValidationError' + '403': + $ref: '#/components/schemas/GenericError' + patch: + operationId: authenticators_duo_partial_update + description: Viewset for Duo authenticator devices + parameters: + - in: path + name: id + schema: + type: integer + description: A unique integer value identifying this Duo Device. + required: true + tags: + - authenticators + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PatchedDuoDeviceRequest' + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/PatchedDuoDeviceRequest' + multipart/form-data: + schema: + $ref: '#/components/schemas/PatchedDuoDeviceRequest' + security: + - authentik: [] + - cookieAuth: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/DuoDevice' + description: '' + '400': + $ref: '#/components/schemas/ValidationError' + '403': + $ref: '#/components/schemas/GenericError' + delete: + operationId: authenticators_duo_destroy + description: Viewset for Duo authenticator devices + parameters: + - in: path + name: id + schema: + type: integer + description: A unique integer value identifying this Duo Device. + required: true + tags: + - authenticators + security: + - authentik: [] + - cookieAuth: [] + responses: + '204': + description: No response body + '400': + $ref: '#/components/schemas/ValidationError' + '403': + $ref: '#/components/schemas/GenericError' /api/v2beta/authenticators/static/: get: operationId: authenticators_static_list @@ -16316,6 +16565,31 @@ components: $ref: '#/components/schemas/FlowRequest' required: - name + DuoDevice: + type: object + description: Serializer for Duo authenticator devices + properties: + pk: + type: integer + readOnly: true + title: ID + name: + type: string + description: The human-readable name of this device. + maxLength: 64 + required: + - name + - pk + DuoDeviceRequest: + type: object + description: Serializer for Duo authenticator devices + properties: + name: + type: string + description: The human-readable name of this device. + maxLength: 64 + required: + - name EmailChallenge: type: object description: Email challenge @@ -18940,6 +19214,41 @@ components: required: - pagination - results + PaginatedDuoDeviceList: + type: object + properties: + pagination: + type: object + properties: + next: + type: number + previous: + type: number + count: + type: number + current: + type: number + total_pages: + type: number + start_index: + type: number + end_index: + type: number + required: + - next + - previous + - count + - current + - total_pages + - start_index + - end_index + results: + type: array + items: + $ref: '#/components/schemas/DuoDevice' + required: + - pagination + - results PaginatedEmailStageList: type: object properties: @@ -21421,6 +21730,14 @@ components: type: array items: $ref: '#/components/schemas/FlowRequest' + PatchedDuoDeviceRequest: + type: object + description: Serializer for Duo authenticator devices + properties: + name: + type: string + description: The human-readable name of this device. + maxLength: 64 PatchedEmailStageRequest: type: object description: EmailStage Serializer diff --git a/web/src/flows/FlowExecutor.ts b/web/src/flows/FlowExecutor.ts index b141e8a37..44bfc9429 100644 --- a/web/src/flows/FlowExecutor.ts +++ b/web/src/flows/FlowExecutor.ts @@ -100,7 +100,6 @@ export class FlowExecutor extends LitElement implements StageHost { submit(payload: FlowChallengeResponseRequest): Promise { // @ts-ignore payload.component = this.challenge?.component; - console.log(payload); this.loading = true; return new FlowsApi(DEFAULT_CONFIG).flowsExecutorSolve({ flowSlug: this.flowSlug, diff --git a/web/src/pages/providers/saml/SAMLProviderForm.ts b/web/src/pages/providers/saml/SAMLProviderForm.ts index d001a2783..42bd43188 100644 --- a/web/src/pages/providers/saml/SAMLProviderForm.ts +++ b/web/src/pages/providers/saml/SAMLProviderForm.ts @@ -13,7 +13,6 @@ import "../../../elements/forms/FormGroup"; export class SAMLProviderFormPage extends ModelForm { loadInstance(pk: number): Promise { - console.log("reading saml provider"); return new ProvidersApi(DEFAULT_CONFIG).providersSamlRetrieve({ id: pk, }); diff --git a/web/src/pages/user-settings/settings/UserSettingsAuthenticatorDuo.ts b/web/src/pages/user-settings/settings/UserSettingsAuthenticatorDuo.ts index 2648cd3ac..8c5b93c02 100644 --- a/web/src/pages/user-settings/settings/UserSettingsAuthenticatorDuo.ts +++ b/web/src/pages/user-settings/settings/UserSettingsAuthenticatorDuo.ts @@ -18,27 +18,17 @@ export class UserSettingsAuthenticatorDuo extends BaseUserSettings { ${t`Status: Enabled`}

-
    - ${until(new AuthenticatorsApi(DEFAULT_CONFIG).authenticatorsStaticList({}).then((devices) => { - if (devices.results.length < 1) { - return; - } - return devices.results[0].tokenSet?.map((token) => { - return html`
  • ${token.token}
  • `; - }); - }))} -
${this.renderDisabled()} - ${until(new AuthenticatorsApi(DEFAULT_CONFIG).authenticatorsStaticList({}).then((devices) => { + ${until(new AuthenticatorsApi(DEFAULT_CONFIG).authenticatorsDuoList({}).then((devices) => { return devices.results.length > 0 ? this.renderEnabled() : this.renderDisabled(); }))} `;