docs: adjust references of webauthn (#5203)

Signed-off-by: James Elliott <james-d-elliott@users.noreply.github.com>
pull/5205/head
James Elliott 2023-04-10 17:01:23 +10:00 committed by GitHub
parent 304467c10f
commit 157675f1f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 245 additions and 245 deletions

View File

@ -7,5 +7,5 @@
package cmd package cmd
const ( const (
versionSwaggerUI = "4.18.1" versionSwaggerUI = "4.18.2"
) )

View File

@ -49,7 +49,7 @@ authelia configuration, and authelia database prior to attempting to do so._
Notable Missing Features from this build: Notable Missing Features from this build:
- OpenID Connect 1.0 PAR - OpenID Connect 1.0 PAR
- Multi-Device Webauthn - Multi-Device WebAuthn
- Device Registration OTP - Device Registration OTP
- Container Images: - Container Images:
@ -144,7 +144,7 @@ Please see the [roadmap](../../roadmap/active/openid-connect.md) for more inform
##### Initial Implementation ##### Initial Implementation
_**Important Note:** This feature at the time of this writing, will not work well with Webauthn. Steps are being taken _**Important Note:** This feature at the time of this writing, will not work well with WebAuthn. Steps are being taken
to address this however it will not specifically delay the release of this feature._ to address this however it will not specifically delay the release of this feature._
This release see's the initial implementation of multi-domain protection. Users will be able to configure more than a This release see's the initial implementation of multi-domain protection. Users will be able to configure more than a
@ -160,14 +160,14 @@ NGINX/NGINX Proxy Manager/SWAG/HAProxy with the use of the new
[Customizable Authorization Endpoints](#customizable-authorization-endpoints). This is important as it means you only [Customizable Authorization Endpoints](#customizable-authorization-endpoints). This is important as it means you only
need to configure a single middleware or helper to perform automatic redirection. need to configure a single middleware or helper to perform automatic redirection.
## Webauthn ## WebAuthn
As part of our ongoing effort for comprehensive support for Webauthn we'll be introducing several important As part of our ongoing effort for comprehensive support for WebAuthn we'll be introducing several important
features. Please see the [roadmap](../../roadmap/active/webauthn.md) for more information. features. Please see the [roadmap](../../roadmap/active/webauthn.md) for more information.
##### Multiple Webauthn Credentials Per-User ##### Multiple WebAuthn Credentials Per-User
In this release we see full support for multiple Webauthn credentials. This is a fairly basic feature but getting the In this release we see full support for multiple WebAuthn credentials. This is a fairly basic feature but getting the
frontend experience right is important to us. This is going to be supported via the frontend experience right is important to us. This is going to be supported via the
[User Control Panel](#user-dashboard--control-panel). [User Control Panel](#user-dashboard--control-panel).

View File

@ -2,7 +2,7 @@
title: "Testing" title: "Testing"
description: "Authelia Development Testing Guidelines" description: "Authelia Development Testing Guidelines"
lead: "This section covers the testing guidelines." lead: "This section covers the testing guidelines."
date: 2022-06-15T17:51:47+10:00 date: 2023-03-20T15:03:52+11:00
draft: false draft: false
images: [] images: []
menu: menu:

View File

@ -1,6 +1,6 @@
--- ---
title: "Amir Zarrinkafsh" title: "Amir Zarrinkafsh"
date: 2022-06-15T17:51:47+10:00 date: 2023-03-19T16:29:12+10:00
draft: false draft: false
images: [] images: []
--- ---

View File

@ -1,6 +1,6 @@
--- ---
title: "Clément Michaud" title: "Clément Michaud"
date: 2022-06-15T17:51:47+10:00 date: 2023-03-19T16:29:12+10:00
draft: false draft: false
images: [] images: []
--- ---

View File

@ -1,6 +1,6 @@
--- ---
title: "Manuel Nuñez" title: "Manuel Nuñez"
date: 2022-06-15T17:51:47+10:00 date: 2023-03-19T16:29:12+10:00
draft: false draft: false
images: [] images: []
--- ---

View File

@ -1,7 +1,7 @@
--- ---
title: "About" title: "About"
description: "About Authelia and the Authelia Team" description: "About Authelia and the Authelia Team"
date: 2022-06-15T17:51:47+10:00 date: 2023-03-19T16:29:12+10:00
draft: false draft: false
images: [] images: []
aliases: aliases:

View File

@ -2,7 +2,7 @@
title: "Firezone" title: "Firezone"
description: "Integrating Firezone with the Authelia OpenID Connect Provider." description: "Integrating Firezone with the Authelia OpenID Connect Provider."
lead: "" lead: ""
date: 2023-03-25T13:07:02+10:00 date: 2023-03-28T20:29:13+11:00
draft: false draft: false
images: [] images: []
menu: menu:

View File

@ -2,7 +2,7 @@
title: "MinIO" title: "MinIO"
description: "Integrating MinIO with the Authelia OpenID Connect Provider." description: "Integrating MinIO with the Authelia OpenID Connect Provider."
lead: "" lead: ""
date: 2022-06-15T17:51:47+10:00 date: 2023-03-21T11:21:23+11:00
draft: false draft: false
images: [] images: []
menu: menu:

View File

@ -2,7 +2,7 @@
title: "Misago" title: "Misago"
description: "Integrating Misago with the Authelia OpenID Connect Provider." description: "Integrating Misago with the Authelia OpenID Connect Provider."
lead: "" lead: ""
date: 2023-03-04T13:20:00+00:00 date: 2023-03-14T08:51:13+11:00
draft: false draft: false
images: [] images: []
menu: menu:

View File

@ -73,7 +73,7 @@ serving Authelia at `auth.example.com`.
```nginx ```nginx
## Set $authelia_backend to route requests to the current domain by default ## Set $authelia_backend to route requests to the current domain by default
set $authelia_backend $http_host; set $authelia_backend $http_host;
## In order for Webauthn to work with multiple domains authelia must operate on a separate subdomain ## In order for WebAuthn to work with multiple domains authelia must operate on a separate subdomain
## To use authelia on a separate subdomain: ## To use authelia on a separate subdomain:
## * comment the $authelia_backend line above ## * comment the $authelia_backend line above
## * rename /config/nginx/proxy-confs/authelia.conf.sample to /config/nginx/proxy-confs/authelia.conf ## * rename /config/nginx/proxy-confs/authelia.conf.sample to /config/nginx/proxy-confs/authelia.conf
@ -88,7 +88,7 @@ serving Authelia at `auth.example.com`.
```nginx ```nginx
## Set $authelia_backend to route requests to the current domain by default ## Set $authelia_backend to route requests to the current domain by default
# set $authelia_backend $http_host; # set $authelia_backend $http_host;
## In order for Webauthn to work with multiple domains authelia must operate on a separate subdomain ## In order for WebAuthn to work with multiple domains authelia must operate on a separate subdomain
## To use authelia on a separate subdomain: ## To use authelia on a separate subdomain:
## * comment the $authelia_backend line above ## * comment the $authelia_backend line above
## * rename /config/nginx/proxy-confs/authelia.conf.sample to /config/nginx/proxy-confs/authelia.conf ## * rename /config/nginx/proxy-confs/authelia.conf.sample to /config/nginx/proxy-confs/authelia.conf

View File

@ -63,5 +63,5 @@ authelia storage user --help
* [authelia storage](authelia_storage.md) - Manage the Authelia storage * [authelia storage](authelia_storage.md) - Manage the Authelia storage
* [authelia storage user identifiers](authelia_storage_user_identifiers.md) - Manage user opaque identifiers * [authelia storage user identifiers](authelia_storage_user_identifiers.md) - Manage user opaque identifiers
* [authelia storage user totp](authelia_storage_user_totp.md) - Manage TOTP configurations * [authelia storage user totp](authelia_storage_user_totp.md) - Manage TOTP configurations
* [authelia storage user webauthn](authelia_storage_user_webauthn.md) - Manage Webauthn devices * [authelia storage user webauthn](authelia_storage_user_webauthn.md) - Manage WebAuthn devices

View File

@ -14,13 +14,13 @@ toc: true
## authelia storage user webauthn ## authelia storage user webauthn
Manage Webauthn devices Manage WebAuthn devices
### Synopsis ### Synopsis
Manage Webauthn devices. Manage WebAuthn devices.
This subcommand allows interacting with Webauthn devices. This subcommand allows interacting with WebAuthn devices.
### Examples ### Examples
@ -61,8 +61,8 @@ authelia storage user webauthn --help
### SEE ALSO ### SEE ALSO
* [authelia storage user](authelia_storage_user.md) - Manages user settings * [authelia storage user](authelia_storage_user.md) - Manages user settings
* [authelia storage user webauthn delete](authelia_storage_user_webauthn_delete.md) - Delete a Webauthn device * [authelia storage user webauthn delete](authelia_storage_user_webauthn_delete.md) - Delete a WebAuthn device
* [authelia storage user webauthn export](authelia_storage_user_webauthn_export.md) - Perform exports of the Webauthn devices * [authelia storage user webauthn export](authelia_storage_user_webauthn_export.md) - Perform exports of the WebAuthn devices
* [authelia storage user webauthn import](authelia_storage_user_webauthn_import.md) - Perform imports of the Webauthn devices * [authelia storage user webauthn import](authelia_storage_user_webauthn_import.md) - Perform imports of the WebAuthn devices
* [authelia storage user webauthn list](authelia_storage_user_webauthn_list.md) - List Webauthn devices * [authelia storage user webauthn list](authelia_storage_user_webauthn_list.md) - List WebAuthn devices

View File

@ -14,13 +14,13 @@ toc: true
## authelia storage user webauthn delete ## authelia storage user webauthn delete
Delete a Webauthn device Delete a WebAuthn device
### Synopsis ### Synopsis
Delete a Webauthn device. Delete a WebAuthn device.
This subcommand allows deleting a Webauthn device directly from the database. This subcommand allows deleting a WebAuthn device directly from the database.
``` ```
authelia storage user webauthn delete [username] [flags] authelia storage user webauthn delete [username] [flags]
@ -75,5 +75,5 @@ authelia storage user webauthn delete --kid abc123 --encryption-key b3453fde-ecc
### SEE ALSO ### SEE ALSO
* [authelia storage user webauthn](authelia_storage_user_webauthn.md) - Manage Webauthn devices * [authelia storage user webauthn](authelia_storage_user_webauthn.md) - Manage WebAuthn devices

View File

@ -14,13 +14,13 @@ toc: true
## authelia storage user webauthn export ## authelia storage user webauthn export
Perform exports of the Webauthn devices Perform exports of the WebAuthn devices
### Synopsis ### Synopsis
Perform exports of the Webauthn devices. Perform exports of the WebAuthn devices.
This subcommand allows exporting Webauthn devices to various formats. This subcommand allows exporting WebAuthn devices to various formats.
``` ```
authelia storage user webauthn export [flags] authelia storage user webauthn export [flags]
@ -68,5 +68,5 @@ authelia storage user webauthn export--encryption-key b3453fde-ecc2-4a1f-9422-27
### SEE ALSO ### SEE ALSO
* [authelia storage user webauthn](authelia_storage_user_webauthn.md) - Manage Webauthn devices * [authelia storage user webauthn](authelia_storage_user_webauthn.md) - Manage WebAuthn devices

View File

@ -14,13 +14,13 @@ toc: true
## authelia storage user webauthn import ## authelia storage user webauthn import
Perform imports of the Webauthn devices Perform imports of the WebAuthn devices
### Synopsis ### Synopsis
Perform imports of the Webauthn devices. Perform imports of the WebAuthn devices.
This subcommand allows importing Webauthn devices from various formats. This subcommand allows importing WebAuthn devices from various formats.
``` ```
authelia storage user webauthn import <filename> [flags] authelia storage user webauthn import <filename> [flags]
@ -67,5 +67,5 @@ authelia storage user webauthn import --file authelia.export.webauthn.yaml --enc
### SEE ALSO ### SEE ALSO
* [authelia storage user webauthn](authelia_storage_user_webauthn.md) - Manage Webauthn devices * [authelia storage user webauthn](authelia_storage_user_webauthn.md) - Manage WebAuthn devices

View File

@ -14,13 +14,13 @@ toc: true
## authelia storage user webauthn list ## authelia storage user webauthn list
List Webauthn devices List WebAuthn devices
### Synopsis ### Synopsis
List Webauthn devices. List WebAuthn devices.
This subcommand allows listing Webauthn devices. This subcommand allows listing WebAuthn devices.
``` ```
authelia storage user webauthn list [username] [flags] authelia storage user webauthn list [username] [flags]
@ -69,5 +69,5 @@ authelia storage user webauthn list john --encryption-key b3453fde-ecc2-4a1f-942
### SEE ALSO ### SEE ALSO
* [authelia storage user webauthn](authelia_storage_user_webauthn.md) - Manage Webauthn devices * [authelia storage user webauthn](authelia_storage_user_webauthn.md) - Manage WebAuthn devices

View File

@ -177,56 +177,56 @@ This subcommand allows manually adding an opaque identifier for a user to the da
authelia storage user identifiers add john --identifier f0919359-9d15-4e15-bcba-83b41620a073 --config config.yml authelia storage user identifiers add john --identifier f0919359-9d15-4e15-bcba-83b41620a073 --config config.yml
authelia storage user identifiers add john --identifier f0919359-9d15-4e15-bcba-83b41620a073 --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw` authelia storage user identifiers add john --identifier f0919359-9d15-4e15-bcba-83b41620a073 --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
cmdAutheliaStorageUserWebauthnShort = "Manage Webauthn devices" cmdAutheliaStorageUserWebAuthnShort = "Manage WebAuthn devices"
cmdAutheliaStorageUserWebauthnLong = `Manage Webauthn devices. cmdAutheliaStorageUserWebAuthnLong = `Manage WebAuthn devices.
This subcommand allows interacting with Webauthn devices.` This subcommand allows interacting with WebAuthn devices.`
cmdAutheliaStorageUserWebauthnExample = `authelia storage user webauthn --help` cmdAutheliaStorageUserWebAuthnExample = `authelia storage user webauthn --help`
cmdAutheliaStorageUserWebauthnImportShort = "Perform imports of the Webauthn devices" cmdAutheliaStorageUserWebAuthnImportShort = "Perform imports of the WebAuthn devices"
cmdAutheliaStorageUserWebauthnImportLong = `Perform imports of the Webauthn devices. cmdAutheliaStorageUserWebAuthnImportLong = `Perform imports of the WebAuthn devices.
This subcommand allows importing Webauthn devices from various formats.` This subcommand allows importing WebAuthn devices from various formats.`
cmdAutheliaStorageUserWebauthnImportExample = `authelia storage user webauthn export cmdAutheliaStorageUserWebAuthnImportExample = `authelia storage user webauthn export
authelia storage user webauthn import --file authelia.export.webauthn.yaml authelia storage user webauthn import --file authelia.export.webauthn.yaml
authelia storage user webauthn import --file authelia.export.webauthn.yaml --config config.yml authelia storage user webauthn import --file authelia.export.webauthn.yaml --config config.yml
authelia storage user webauthn import --file authelia.export.webauthn.yaml --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw` authelia storage user webauthn import --file authelia.export.webauthn.yaml --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
cmdAutheliaStorageUserWebauthnExportShort = "Perform exports of the Webauthn devices" cmdAutheliaStorageUserWebAuthnExportShort = "Perform exports of the WebAuthn devices"
cmdAutheliaStorageUserWebauthnExportLong = `Perform exports of the Webauthn devices. cmdAutheliaStorageUserWebAuthnExportLong = `Perform exports of the WebAuthn devices.
This subcommand allows exporting Webauthn devices to various formats.` This subcommand allows exporting WebAuthn devices to various formats.`
cmdAutheliaStorageUserWebauthnExportExample = `authelia storage user webauthn export cmdAutheliaStorageUserWebAuthnExportExample = `authelia storage user webauthn export
authelia storage user webauthn export --file authelia.export.webauthn.yaml authelia storage user webauthn export --file authelia.export.webauthn.yaml
authelia storage user webauthn export --config config.yml authelia storage user webauthn export --config config.yml
authelia storage user webauthn export--encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw` authelia storage user webauthn export--encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
cmdAutheliaStorageUserWebauthnListShort = "List Webauthn devices" cmdAutheliaStorageUserWebAuthnListShort = "List WebAuthn devices"
cmdAutheliaStorageUserWebauthnListLong = `List Webauthn devices. cmdAutheliaStorageUserWebAuthnListLong = `List WebAuthn devices.
This subcommand allows listing Webauthn devices.` This subcommand allows listing WebAuthn devices.`
cmdAutheliaStorageUserWebauthnListExample = `authelia storage user webauthn list cmdAutheliaStorageUserWebAuthnListExample = `authelia storage user webauthn list
authelia storage user webauthn list john authelia storage user webauthn list john
authelia storage user webauthn list --config config.yml authelia storage user webauthn list --config config.yml
authelia storage user webauthn list john --config config.yml authelia storage user webauthn list john --config config.yml
authelia storage user webauthn list --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw authelia storage user webauthn list --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw
authelia storage user webauthn list john --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw` authelia storage user webauthn list john --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
cmdAutheliaStorageUserWebauthnDeleteShort = "Delete a Webauthn device" cmdAutheliaStorageUserWebAuthnDeleteShort = "Delete a WebAuthn device"
cmdAutheliaStorageUserWebauthnDeleteLong = `Delete a Webauthn device. cmdAutheliaStorageUserWebAuthnDeleteLong = `Delete a WebAuthn device.
This subcommand allows deleting a Webauthn device directly from the database.` This subcommand allows deleting a WebAuthn device directly from the database.`
cmdAutheliaStorageUserWebauthnDeleteExample = `authelia storage user webauthn delete john --all cmdAutheliaStorageUserWebAuthnDeleteExample = `authelia storage user webauthn delete john --all
authelia storage user webauthn delete john --all --config config.yml authelia storage user webauthn delete john --all --config config.yml
authelia storage user webauthn delete john --all --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw authelia storage user webauthn delete john --all --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw
authelia storage user webauthn delete john --description Primary authelia storage user webauthn delete john --description Primary

View File

@ -68,7 +68,7 @@ func storageTOTPGenerateRunEOptsFromFlags(flags *pflag.FlagSet) (force bool, fil
return force, filename, secret, nil return force, filename, secret, nil
} }
func storageWebauthnDeleteRunEOptsFromFlags(flags *pflag.FlagSet, args []string) (all, byKID bool, description, kid, user string, err error) { func storageWebAuthnDeleteRunEOptsFromFlags(flags *pflag.FlagSet, args []string) (all, byKID bool, description, kid, user string, err error) {
if len(args) != 0 { if len(args) != 0 {
user = args[0] user = args[0]
} }

View File

@ -124,7 +124,7 @@ func newStorageUserCmd(ctx *CmdCtx) (cmd *cobra.Command) {
cmd.AddCommand( cmd.AddCommand(
newStorageUserIdentifiersCmd(ctx), newStorageUserIdentifiersCmd(ctx),
newStorageUserTOTPCmd(ctx), newStorageUserTOTPCmd(ctx),
newStorageUserWebauthnCmd(ctx), newStorageUserWebAuthnCmd(ctx),
) )
return cmd return cmd
@ -221,34 +221,34 @@ func newStorageUserIdentifiersAddCmd(ctx *CmdCtx) (cmd *cobra.Command) {
return cmd return cmd
} }
func newStorageUserWebauthnCmd(ctx *CmdCtx) (cmd *cobra.Command) { func newStorageUserWebAuthnCmd(ctx *CmdCtx) (cmd *cobra.Command) {
cmd = &cobra.Command{ cmd = &cobra.Command{
Use: "webauthn", Use: "webauthn",
Short: cmdAutheliaStorageUserWebauthnShort, Short: cmdAutheliaStorageUserWebAuthnShort,
Long: cmdAutheliaStorageUserWebauthnLong, Long: cmdAutheliaStorageUserWebAuthnLong,
Example: cmdAutheliaStorageUserWebauthnExample, Example: cmdAutheliaStorageUserWebAuthnExample,
Args: cobra.NoArgs, Args: cobra.NoArgs,
DisableAutoGenTag: true, DisableAutoGenTag: true,
} }
cmd.AddCommand( cmd.AddCommand(
newStorageUserWebauthnListCmd(ctx), newStorageUserWebAuthnListCmd(ctx),
newStorageUserWebauthnDeleteCmd(ctx), newStorageUserWebAuthnDeleteCmd(ctx),
newStorageUserWebauthnExportCmd(ctx), newStorageUserWebAuthnExportCmd(ctx),
newStorageUserWebauthnImportCmd(ctx), newStorageUserWebAuthnImportCmd(ctx),
) )
return cmd return cmd
} }
func newStorageUserWebauthnImportCmd(ctx *CmdCtx) (cmd *cobra.Command) { func newStorageUserWebAuthnImportCmd(ctx *CmdCtx) (cmd *cobra.Command) {
cmd = &cobra.Command{ cmd = &cobra.Command{
Use: cmdUseImportFileName, Use: cmdUseImportFileName,
Short: cmdAutheliaStorageUserWebauthnImportShort, Short: cmdAutheliaStorageUserWebAuthnImportShort,
Long: cmdAutheliaStorageUserWebauthnImportLong, Long: cmdAutheliaStorageUserWebAuthnImportLong,
Example: cmdAutheliaStorageUserWebauthnImportExample, Example: cmdAutheliaStorageUserWebAuthnImportExample,
RunE: ctx.StorageUserWebauthnImportRunE, RunE: ctx.StorageUserWebAuthnImportRunE,
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
DisableAutoGenTag: true, DisableAutoGenTag: true,
@ -257,13 +257,13 @@ func newStorageUserWebauthnImportCmd(ctx *CmdCtx) (cmd *cobra.Command) {
return cmd return cmd
} }
func newStorageUserWebauthnExportCmd(ctx *CmdCtx) (cmd *cobra.Command) { func newStorageUserWebAuthnExportCmd(ctx *CmdCtx) (cmd *cobra.Command) {
cmd = &cobra.Command{ cmd = &cobra.Command{
Use: cmdUseExport, Use: cmdUseExport,
Short: cmdAutheliaStorageUserWebauthnExportShort, Short: cmdAutheliaStorageUserWebAuthnExportShort,
Long: cmdAutheliaStorageUserWebauthnExportLong, Long: cmdAutheliaStorageUserWebAuthnExportLong,
Example: cmdAutheliaStorageUserWebauthnExportExample, Example: cmdAutheliaStorageUserWebAuthnExportExample,
RunE: ctx.StorageUserWebauthnExportRunE, RunE: ctx.StorageUserWebAuthnExportRunE,
Args: cobra.NoArgs, Args: cobra.NoArgs,
DisableAutoGenTag: true, DisableAutoGenTag: true,
@ -274,13 +274,13 @@ func newStorageUserWebauthnExportCmd(ctx *CmdCtx) (cmd *cobra.Command) {
return cmd return cmd
} }
func newStorageUserWebauthnListCmd(ctx *CmdCtx) (cmd *cobra.Command) { func newStorageUserWebAuthnListCmd(ctx *CmdCtx) (cmd *cobra.Command) {
cmd = &cobra.Command{ cmd = &cobra.Command{
Use: "list [username]", Use: "list [username]",
Short: cmdAutheliaStorageUserWebauthnListShort, Short: cmdAutheliaStorageUserWebAuthnListShort,
Long: cmdAutheliaStorageUserWebauthnListLong, Long: cmdAutheliaStorageUserWebAuthnListLong,
Example: cmdAutheliaStorageUserWebauthnListExample, Example: cmdAutheliaStorageUserWebAuthnListExample,
RunE: ctx.StorageUserWebauthnListRunE, RunE: ctx.StorageUserWebAuthnListRunE,
Args: cobra.MaximumNArgs(1), Args: cobra.MaximumNArgs(1),
DisableAutoGenTag: true, DisableAutoGenTag: true,
@ -289,13 +289,13 @@ func newStorageUserWebauthnListCmd(ctx *CmdCtx) (cmd *cobra.Command) {
return cmd return cmd
} }
func newStorageUserWebauthnDeleteCmd(ctx *CmdCtx) (cmd *cobra.Command) { func newStorageUserWebAuthnDeleteCmd(ctx *CmdCtx) (cmd *cobra.Command) {
cmd = &cobra.Command{ cmd = &cobra.Command{
Use: "delete [username]", Use: "delete [username]",
Short: cmdAutheliaStorageUserWebauthnDeleteShort, Short: cmdAutheliaStorageUserWebAuthnDeleteShort,
Long: cmdAutheliaStorageUserWebauthnDeleteLong, Long: cmdAutheliaStorageUserWebAuthnDeleteLong,
Example: cmdAutheliaStorageUserWebauthnDeleteExample, Example: cmdAutheliaStorageUserWebAuthnDeleteExample,
RunE: ctx.StorageUserWebauthnDeleteRunE, RunE: ctx.StorageUserWebAuthnDeleteRunE,
Args: cobra.MaximumNArgs(1), Args: cobra.MaximumNArgs(1),
DisableAutoGenTag: true, DisableAutoGenTag: true,

View File

@ -415,7 +415,7 @@ func (ctx *CmdCtx) StorageSchemaInfoRunE(_ *cobra.Command, _ []string) (err erro
return nil return nil
} }
func (ctx *CmdCtx) StorageUserWebauthnExportRunE(cmd *cobra.Command, args []string) (err error) { func (ctx *CmdCtx) StorageUserWebAuthnExportRunE(cmd *cobra.Command, args []string) (err error) {
defer func() { defer func() {
_ = ctx.providers.StorageProvider.Close() _ = ctx.providers.StorageProvider.Close()
}() }()
@ -443,11 +443,11 @@ func (ctx *CmdCtx) StorageUserWebauthnExportRunE(cmd *cobra.Command, args []stri
count := 0 count := 0
var ( var (
devices []model.WebauthnDevice devices []model.WebAuthnDevice
) )
export := &model.WebauthnDeviceExport{ export := &model.WebAuthnDeviceExport{
WebauthnDevices: nil, WebAuthnDevices: nil,
} }
for page := 0; true; page++ { for page := 0; true; page++ {
@ -455,7 +455,7 @@ func (ctx *CmdCtx) StorageUserWebauthnExportRunE(cmd *cobra.Command, args []stri
return err return err
} }
export.WebauthnDevices = append(export.WebauthnDevices, devices...) export.WebAuthnDevices = append(export.WebAuthnDevices, devices...)
l := len(devices) l := len(devices)
@ -476,12 +476,12 @@ func (ctx *CmdCtx) StorageUserWebauthnExportRunE(cmd *cobra.Command, args []stri
return fmt.Errorf("error occurred writing to file '%s': %w", filename, err) return fmt.Errorf("error occurred writing to file '%s': %w", filename, err)
} }
fmt.Printf(cliOutputFmtSuccessfulUserExportFile, count, "Webauthn devices", "YAML", filename) fmt.Printf(cliOutputFmtSuccessfulUserExportFile, count, "WebAuthn devices", "YAML", filename)
return nil return nil
} }
func (ctx *CmdCtx) StorageUserWebauthnImportRunE(cmd *cobra.Command, args []string) (err error) { func (ctx *CmdCtx) StorageUserWebAuthnImportRunE(cmd *cobra.Command, args []string) (err error) {
defer func() { defer func() {
_ = ctx.providers.StorageProvider.Close() _ = ctx.providers.StorageProvider.Close()
}() }()
@ -507,46 +507,46 @@ func (ctx *CmdCtx) StorageUserWebauthnImportRunE(cmd *cobra.Command, args []stri
return err return err
} }
export := &model.WebauthnDeviceExport{} export := &model.WebAuthnDeviceExport{}
if err = yaml.Unmarshal(data, export); err != nil { if err = yaml.Unmarshal(data, export); err != nil {
return err return err
} }
if len(export.WebauthnDevices) == 0 { if len(export.WebAuthnDevices) == 0 {
return fmt.Errorf("can't import a YAML file without Webauthn devices data") return fmt.Errorf("can't import a YAML file without WebAuthn devices data")
} }
if err = ctx.CheckSchema(); err != nil { if err = ctx.CheckSchema(); err != nil {
return storageWrapCheckSchemaErr(err) return storageWrapCheckSchemaErr(err)
} }
for _, device := range export.WebauthnDevices { for _, device := range export.WebAuthnDevices {
if err = ctx.providers.StorageProvider.SaveWebauthnDevice(ctx, device); err != nil { if err = ctx.providers.StorageProvider.SaveWebauthnDevice(ctx, device); err != nil {
return err return err
} }
} }
fmt.Printf(cliOutputFmtSuccessfulUserImportFile, len(export.WebauthnDevices), "Webauthn devices", "YAML", filename) fmt.Printf(cliOutputFmtSuccessfulUserImportFile, len(export.WebAuthnDevices), "WebAuthn devices", "YAML", filename)
return nil return nil
} }
// StorageUserWebauthnListRunE is the RunE for the authelia storage user webauthn list command. // StorageUserWebAuthnListRunE is the RunE for the authelia storage user webauthn list command.
func (ctx *CmdCtx) StorageUserWebauthnListRunE(cmd *cobra.Command, args []string) (err error) { func (ctx *CmdCtx) StorageUserWebAuthnListRunE(cmd *cobra.Command, args []string) (err error) {
defer func() { defer func() {
_ = ctx.providers.StorageProvider.Close() _ = ctx.providers.StorageProvider.Close()
}() }()
if len(args) == 0 || args[0] == "" { if len(args) == 0 || args[0] == "" {
return ctx.StorageUserWebauthnListAllRunE(cmd, args) return ctx.StorageUserWebAuthnListAllRunE(cmd, args)
} }
if err = ctx.CheckSchema(); err != nil { if err = ctx.CheckSchema(); err != nil {
return storageWrapCheckSchemaErr(err) return storageWrapCheckSchemaErr(err)
} }
var devices []model.WebauthnDevice var devices []model.WebAuthnDevice
user := args[0] user := args[0]
@ -558,7 +558,7 @@ func (ctx *CmdCtx) StorageUserWebauthnListRunE(cmd *cobra.Command, args []string
case err != nil: case err != nil:
return fmt.Errorf("can't list devices for user '%s': %w", user, err) return fmt.Errorf("can't list devices for user '%s': %w", user, err)
default: default:
fmt.Printf("Webauthn Devices for user '%s':\n\n", user) fmt.Printf("WebAuthn Devices for user '%s':\n\n", user)
fmt.Printf("ID\tKID\tDescription\n") fmt.Printf("ID\tKID\tDescription\n")
for _, device := range devices { for _, device := range devices {
@ -569,8 +569,8 @@ func (ctx *CmdCtx) StorageUserWebauthnListRunE(cmd *cobra.Command, args []string
return nil return nil
} }
// StorageUserWebauthnListAllRunE is the RunE for the authelia storage user webauthn list command when no args are specified. // StorageUserWebAuthnListAllRunE is the RunE for the authelia storage user webauthn list command when no args are specified.
func (ctx *CmdCtx) StorageUserWebauthnListAllRunE(_ *cobra.Command, _ []string) (err error) { func (ctx *CmdCtx) StorageUserWebAuthnListAllRunE(_ *cobra.Command, _ []string) (err error) {
defer func() { defer func() {
_ = ctx.providers.StorageProvider.Close() _ = ctx.providers.StorageProvider.Close()
}() }()
@ -579,7 +579,7 @@ func (ctx *CmdCtx) StorageUserWebauthnListAllRunE(_ *cobra.Command, _ []string)
return storageWrapCheckSchemaErr(err) return storageWrapCheckSchemaErr(err)
} }
var devices []model.WebauthnDevice var devices []model.WebAuthnDevice
limit := 10 limit := 10
@ -603,14 +603,14 @@ func (ctx *CmdCtx) StorageUserWebauthnListAllRunE(_ *cobra.Command, _ []string)
} }
} }
fmt.Printf("Webauthn Devices:\n\nID\tKID\tDescription\tUsername\n") fmt.Printf("WebAuthn Devices:\n\nID\tKID\tDescription\tUsername\n")
fmt.Println(output.String()) fmt.Println(output.String())
return nil return nil
} }
// StorageUserWebauthnDeleteRunE is the RunE for the authelia storage user webauthn delete command. // StorageUserWebAuthnDeleteRunE is the RunE for the authelia storage user webauthn delete command.
func (ctx *CmdCtx) StorageUserWebauthnDeleteRunE(cmd *cobra.Command, args []string) (err error) { func (ctx *CmdCtx) StorageUserWebAuthnDeleteRunE(cmd *cobra.Command, args []string) (err error) {
defer func() { defer func() {
_ = ctx.providers.StorageProvider.Close() _ = ctx.providers.StorageProvider.Close()
}() }()
@ -624,7 +624,7 @@ func (ctx *CmdCtx) StorageUserWebauthnDeleteRunE(cmd *cobra.Command, args []stri
description, kid, user string description, kid, user string
) )
if all, byKID, description, kid, user, err = storageWebauthnDeleteRunEOptsFromFlags(cmd.Flags(), args); err != nil { if all, byKID, description, kid, user, err = storageWebAuthnDeleteRunEOptsFromFlags(cmd.Flags(), args); err != nil {
return err return err
} }
@ -633,7 +633,7 @@ func (ctx *CmdCtx) StorageUserWebauthnDeleteRunE(cmd *cobra.Command, args []stri
return fmt.Errorf("failed to delete webauthn device with kid '%s': %w", kid, err) return fmt.Errorf("failed to delete webauthn device with kid '%s': %w", kid, err)
} }
fmt.Printf("Successfully deleted Webauthn device with key id '%s'\n", kid) fmt.Printf("Successfully deleted WebAuthn device with key id '%s'\n", kid)
} else { } else {
err = ctx.providers.StorageProvider.DeleteWebauthnDeviceByUsername(ctx, user, description) err = ctx.providers.StorageProvider.DeleteWebauthnDeviceByUsername(ctx, user, description)
@ -642,13 +642,13 @@ func (ctx *CmdCtx) StorageUserWebauthnDeleteRunE(cmd *cobra.Command, args []stri
return fmt.Errorf("failed to delete all webauthn devices with username '%s': %w", user, err) return fmt.Errorf("failed to delete all webauthn devices with username '%s': %w", user, err)
} }
fmt.Printf("Successfully deleted all Webauthn devices for user '%s'\n", user) fmt.Printf("Successfully deleted all WebAuthn devices for user '%s'\n", user)
} else { } else {
if err != nil { if err != nil {
return fmt.Errorf("failed to delete webauthn device with username '%s' and description '%s': %w", user, description, err) return fmt.Errorf("failed to delete webauthn device with username '%s' and description '%s': %w", user, description, err)
} }
fmt.Printf("Successfully deleted Webauthn device with description '%s' for user '%s'\n", description, user) fmt.Printf("Successfully deleted WebAuthn device with description '%s' for user '%s'\n", description, user)
} }
} }

View File

@ -33,7 +33,7 @@ var WebauthnIdentityFinish = middlewares.IdentityVerificationFinish(
func SecondFactorWebauthnAttestationGET(ctx *middlewares.AutheliaCtx, _ string) { func SecondFactorWebauthnAttestationGET(ctx *middlewares.AutheliaCtx, _ string) {
var ( var (
w *webauthn.WebAuthn w *webauthn.WebAuthn
user *model.WebauthnUser user *model.WebAuthnUser
userSession session.UserSession userSession session.UserSession
err error err error
) )
@ -94,7 +94,7 @@ func WebauthnAttestationPOST(ctx *middlewares.AutheliaCtx) {
var ( var (
err error err error
w *webauthn.WebAuthn w *webauthn.WebAuthn
user *model.WebauthnUser user *model.WebAuthnUser
userSession session.UserSession userSession session.UserSession
@ -150,7 +150,7 @@ func WebauthnAttestationPOST(ctx *middlewares.AutheliaCtx) {
return return
} }
device := model.NewWebauthnDeviceFromCredential(w.Config.RPID, userSession.Username, "Primary", credential) device := model.NewWebAuthnDeviceFromCredential(w.Config.RPID, userSession.Username, "Primary", credential)
if err = ctx.Providers.StorageProvider.SaveWebauthnDevice(ctx, device); err != nil { if err = ctx.Providers.StorageProvider.SaveWebauthnDevice(ctx, device); err != nil {
ctx.Logger.Errorf("Unable to load %s devices for assertion challenge for user '%s': %+v", regulation.AuthTypeWebauthn, userSession.Username, err) ctx.Logger.Errorf("Unable to load %s devices for assertion challenge for user '%s': %+v", regulation.AuthTypeWebauthn, userSession.Username, err)

View File

@ -16,7 +16,7 @@ import (
func WebauthnAssertionGET(ctx *middlewares.AutheliaCtx) { func WebauthnAssertionGET(ctx *middlewares.AutheliaCtx) {
var ( var (
w *webauthn.WebAuthn w *webauthn.WebAuthn
user *model.WebauthnUser user *model.WebAuthnUser
userSession session.UserSession userSession session.UserSession
err error err error
) )
@ -134,7 +134,7 @@ func WebauthnAssertionPOST(ctx *middlewares.AutheliaCtx) {
var ( var (
assertionResponse *protocol.ParsedCredentialAssertionData assertionResponse *protocol.ParsedCredentialAssertionData
credential *webauthn.Credential credential *webauthn.Credential
user *model.WebauthnUser user *model.WebAuthnUser
) )
if assertionResponse, err = protocol.ParseCredentialRequestResponseBody(bytes.NewReader(ctx.PostBody())); err != nil { if assertionResponse, err = protocol.ParseCredentialRequestResponseBody(bytes.NewReader(ctx.PostBody())); err != nil {

View File

@ -62,7 +62,7 @@ func TestUserInfoEndpoint_SetCorrectMethod(t *testing.T) {
{ {
db: model.UserInfo{ db: model.UserInfo{
Method: "webauthn", Method: "webauthn",
HasWebauthn: true, HasWebAuthn: true,
HasTOTP: true, HasTOTP: true,
}, },
err: nil, err: nil,
@ -70,7 +70,7 @@ func TestUserInfoEndpoint_SetCorrectMethod(t *testing.T) {
{ {
db: model.UserInfo{ db: model.UserInfo{
Method: "webauthn", Method: "webauthn",
HasWebauthn: true, HasWebAuthn: true,
HasTOTP: false, HasTOTP: false,
}, },
err: nil, err: nil,
@ -78,7 +78,7 @@ func TestUserInfoEndpoint_SetCorrectMethod(t *testing.T) {
{ {
db: model.UserInfo{ db: model.UserInfo{
Method: "mobile_push", Method: "mobile_push",
HasWebauthn: false, HasWebAuthn: false,
HasTOTP: false, HasTOTP: false,
}, },
err: nil, err: nil,
@ -128,7 +128,7 @@ func TestUserInfoEndpoint_SetCorrectMethod(t *testing.T) {
}) })
t.Run("registered webauthn", func(t *testing.T) { t.Run("registered webauthn", func(t *testing.T) {
assert.Equal(t, resp.api.HasWebauthn, actualPreferences.HasWebauthn) assert.Equal(t, resp.api.HasWebAuthn, actualPreferences.HasWebAuthn)
}) })
t.Run("registered totp", func(t *testing.T) { t.Run("registered totp", func(t *testing.T) {
@ -160,13 +160,13 @@ func TestUserInfoEndpoint_SetDefaultMethod(t *testing.T) {
db: model.UserInfo{ db: model.UserInfo{
Method: "", Method: "",
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
HasDuo: false, HasDuo: false,
}, },
api: &model.UserInfo{ api: &model.UserInfo{
Method: "totp", Method: "totp",
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
HasDuo: false, HasDuo: false,
}, },
config: &schema.Configuration{}, config: &schema.Configuration{},
@ -178,13 +178,13 @@ func TestUserInfoEndpoint_SetDefaultMethod(t *testing.T) {
db: model.UserInfo{ db: model.UserInfo{
Method: "", Method: "",
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
HasDuo: true, HasDuo: true,
}, },
api: &model.UserInfo{ api: &model.UserInfo{
Method: "mobile_push", Method: "mobile_push",
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
HasDuo: true, HasDuo: true,
}, },
config: &schema.Configuration{}, config: &schema.Configuration{},
@ -196,13 +196,13 @@ func TestUserInfoEndpoint_SetDefaultMethod(t *testing.T) {
db: model.UserInfo{ db: model.UserInfo{
Method: "", Method: "",
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
HasDuo: true, HasDuo: true,
}, },
api: &model.UserInfo{ api: &model.UserInfo{
Method: "totp", Method: "totp",
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
HasDuo: true, HasDuo: true,
}, },
config: &schema.Configuration{DuoAPI: schema.DuoAPIConfiguration{Disable: true}}, config: &schema.Configuration{DuoAPI: schema.DuoAPIConfiguration{Disable: true}},
@ -214,13 +214,13 @@ func TestUserInfoEndpoint_SetDefaultMethod(t *testing.T) {
db: model.UserInfo{ db: model.UserInfo{
Method: "", Method: "",
HasTOTP: true, HasTOTP: true,
HasWebauthn: true, HasWebAuthn: true,
HasDuo: true, HasDuo: true,
}, },
api: &model.UserInfo{ api: &model.UserInfo{
Method: "webauthn", Method: "webauthn",
HasTOTP: true, HasTOTP: true,
HasWebauthn: true, HasWebAuthn: true,
HasDuo: true, HasDuo: true,
}, },
config: &schema.Configuration{ config: &schema.Configuration{
@ -236,13 +236,13 @@ func TestUserInfoEndpoint_SetDefaultMethod(t *testing.T) {
db: model.UserInfo{ db: model.UserInfo{
Method: "", Method: "",
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
HasDuo: false, HasDuo: false,
}, },
api: &model.UserInfo{ api: &model.UserInfo{
Method: "totp", Method: "totp",
HasTOTP: true, HasTOTP: true,
HasWebauthn: true, HasWebAuthn: true,
HasDuo: true, HasDuo: true,
}, },
config: &schema.Configuration{}, config: &schema.Configuration{},
@ -322,7 +322,7 @@ func TestUserInfoEndpoint_SetDefaultMethod(t *testing.T) {
}) })
t.Run("registered webauthn", func(t *testing.T) { t.Run("registered webauthn", func(t *testing.T) {
assert.Equal(t, resp.api.HasWebauthn, actualPreferences.HasWebauthn) assert.Equal(t, resp.api.HasWebAuthn, actualPreferences.HasWebAuthn)
}) })
t.Run("registered totp", func(t *testing.T) { t.Run("registered totp", func(t *testing.T) {

View File

@ -12,8 +12,8 @@ import (
"github.com/authelia/authelia/v4/internal/session" "github.com/authelia/authelia/v4/internal/session"
) )
func getWebAuthnUser(ctx *middlewares.AutheliaCtx, userSession session.UserSession) (user *model.WebauthnUser, err error) { func getWebAuthnUser(ctx *middlewares.AutheliaCtx, userSession session.UserSession) (user *model.WebAuthnUser, err error) {
user = &model.WebauthnUser{ user = &model.WebAuthnUser{
Username: userSession.Username, Username: userSession.Username,
DisplayName: userSession.DisplayName, DisplayName: userSession.DisplayName,
} }

View File

@ -21,7 +21,7 @@ func TestWebauthnGetUser(t *testing.T) {
DisplayName: "John Smith", DisplayName: "John Smith",
} }
ctx.StorageMock.EXPECT().LoadWebauthnDevicesByUsername(ctx.Ctx, "john").Return([]model.WebauthnDevice{ ctx.StorageMock.EXPECT().LoadWebauthnDevicesByUsername(ctx.Ctx, "john").Return([]model.WebAuthnDevice{
{ {
ID: 1, ID: 1,
RPID: "https://example.com", RPID: "https://example.com",
@ -106,7 +106,7 @@ func TestWebauthnGetUserWithoutDisplayName(t *testing.T) {
Username: "john", Username: "john",
} }
ctx.StorageMock.EXPECT().LoadWebauthnDevicesByUsername(ctx.Ctx, "john").Return([]model.WebauthnDevice{ ctx.StorageMock.EXPECT().LoadWebauthnDevicesByUsername(ctx.Ctx, "john").Return([]model.WebAuthnDevice{
{ {
ID: 1, ID: 1,
RPID: "https://example.com", RPID: "https://example.com",

View File

@ -50,7 +50,7 @@ func (ctx *AutheliaCtx) AvailableSecondFactorMethods() (methods []string) {
} }
if !ctx.Configuration.Webauthn.Disable { if !ctx.Configuration.Webauthn.Disable {
methods = append(methods, model.SecondFactorMethodWebauthn) methods = append(methods, model.SecondFactorMethodWebAuthn)
} }
if !ctx.Configuration.DuoAPI.Disable { if !ctx.Configuration.DuoAPI.Disable {

View File

@ -235,15 +235,15 @@ func TestShouldReturnCorrectSecondFactorMethods(t *testing.T) {
mock.Ctx.Configuration.DuoAPI.Disable = true mock.Ctx.Configuration.DuoAPI.Disable = true
assert.Equal(t, []string{model.SecondFactorMethodTOTP, model.SecondFactorMethodWebauthn}, mock.Ctx.AvailableSecondFactorMethods()) assert.Equal(t, []string{model.SecondFactorMethodTOTP, model.SecondFactorMethodWebAuthn}, mock.Ctx.AvailableSecondFactorMethods())
mock.Ctx.Configuration.DuoAPI.Disable = false mock.Ctx.Configuration.DuoAPI.Disable = false
assert.Equal(t, []string{model.SecondFactorMethodTOTP, model.SecondFactorMethodWebauthn, model.SecondFactorMethodDuo}, mock.Ctx.AvailableSecondFactorMethods()) assert.Equal(t, []string{model.SecondFactorMethodTOTP, model.SecondFactorMethodWebAuthn, model.SecondFactorMethodDuo}, mock.Ctx.AvailableSecondFactorMethods())
mock.Ctx.Configuration.TOTP.Disable = true mock.Ctx.Configuration.TOTP.Disable = true
assert.Equal(t, []string{model.SecondFactorMethodWebauthn, model.SecondFactorMethodDuo}, mock.Ctx.AvailableSecondFactorMethods()) assert.Equal(t, []string{model.SecondFactorMethodWebAuthn, model.SecondFactorMethodDuo}, mock.Ctx.AvailableSecondFactorMethods())
mock.Ctx.Configuration.Webauthn.Disable = true mock.Ctx.Configuration.Webauthn.Disable = true

View File

@ -421,10 +421,10 @@ func (mr *MockStorageMockRecorder) LoadUserOpaqueIdentifiers(arg0 interface{}) *
} }
// LoadWebauthnDevices mocks base method. // LoadWebauthnDevices mocks base method.
func (m *MockStorage) LoadWebauthnDevices(arg0 context.Context, arg1, arg2 int) ([]model.WebauthnDevice, error) { func (m *MockStorage) LoadWebauthnDevices(arg0 context.Context, arg1, arg2 int) ([]model.WebAuthnDevice, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "LoadWebauthnDevices", arg0, arg1, arg2) ret := m.ctrl.Call(m, "LoadWebauthnDevices", arg0, arg1, arg2)
ret0, _ := ret[0].([]model.WebauthnDevice) ret0, _ := ret[0].([]model.WebAuthnDevice)
ret1, _ := ret[1].(error) ret1, _ := ret[1].(error)
return ret0, ret1 return ret0, ret1
} }
@ -436,10 +436,10 @@ func (mr *MockStorageMockRecorder) LoadWebauthnDevices(arg0, arg1, arg2 interfac
} }
// LoadWebauthnDevicesByUsername mocks base method. // LoadWebauthnDevicesByUsername mocks base method.
func (m *MockStorage) LoadWebauthnDevicesByUsername(arg0 context.Context, arg1 string) ([]model.WebauthnDevice, error) { func (m *MockStorage) LoadWebauthnDevicesByUsername(arg0 context.Context, arg1 string) ([]model.WebAuthnDevice, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "LoadWebauthnDevicesByUsername", arg0, arg1) ret := m.ctrl.Call(m, "LoadWebauthnDevicesByUsername", arg0, arg1)
ret0, _ := ret[0].([]model.WebauthnDevice) ret0, _ := ret[0].([]model.WebAuthnDevice)
ret1, _ := ret[1].(error) ret1, _ := ret[1].(error)
return ret0, ret1 return ret0, ret1
} }
@ -690,7 +690,7 @@ func (mr *MockStorageMockRecorder) SaveUserOpaqueIdentifier(arg0, arg1 interface
} }
// SaveWebauthnDevice mocks base method. // SaveWebauthnDevice mocks base method.
func (m *MockStorage) SaveWebauthnDevice(arg0 context.Context, arg1 model.WebauthnDevice) error { func (m *MockStorage) SaveWebauthnDevice(arg0 context.Context, arg1 model.WebAuthnDevice) error {
m.ctrl.T.Helper() m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SaveWebauthnDevice", arg0, arg1) ret := m.ctrl.Call(m, "SaveWebauthnDevice", arg0, arg1)
ret0, _ := ret[0].(error) ret0, _ := ret[0].(error)

View File

@ -15,8 +15,8 @@ const (
// SecondFactorMethodTOTP method using Time-Based One-Time Password applications like Google Authenticator. // SecondFactorMethodTOTP method using Time-Based One-Time Password applications like Google Authenticator.
SecondFactorMethodTOTP = "totp" SecondFactorMethodTOTP = "totp"
// SecondFactorMethodWebauthn method using Webauthn devices like YubiKey's. // SecondFactorMethodWebAuthn method using WebAuthn devices like YubiKey's.
SecondFactorMethodWebauthn = "webauthn" SecondFactorMethodWebAuthn = "webauthn"
// SecondFactorMethodDuo method using Duo application to receive push notifications. // SecondFactorMethodDuo method using Duo application to receive push notifications.
SecondFactorMethodDuo = "mobile_push" SecondFactorMethodDuo = "mobile_push"

View File

@ -15,8 +15,8 @@ type UserInfo struct {
// True if a TOTP device has been registered. // True if a TOTP device has been registered.
HasTOTP bool `db:"has_totp" json:"has_totp" valid:"required"` HasTOTP bool `db:"has_totp" json:"has_totp" valid:"required"`
// True if a Webauthn device has been registered. // True if a WebAuthn device has been registered.
HasWebauthn bool `db:"has_webauthn" json:"has_webauthn" valid:"required"` HasWebAuthn bool `db:"has_webauthn" json:"has_webauthn" valid:"required"`
// True if a duo device has been configured as the preferred. // True if a duo device has been configured as the preferred.
HasDuo bool `db:"has_duo" json:"has_duo" valid:"required"` HasDuo bool `db:"has_duo" json:"has_duo" valid:"required"`
@ -31,7 +31,7 @@ func (i *UserInfo) SetDefaultPreferred2FAMethod(methods []string, fallback strin
before := i.Method before := i.Method
totp, webauthn, duo := utils.IsStringInSlice(SecondFactorMethodTOTP, methods), utils.IsStringInSlice(SecondFactorMethodWebauthn, methods), utils.IsStringInSlice(SecondFactorMethodDuo, methods) totp, webauthn, duo := utils.IsStringInSlice(SecondFactorMethodTOTP, methods), utils.IsStringInSlice(SecondFactorMethodWebAuthn, methods), utils.IsStringInSlice(SecondFactorMethodDuo, methods)
if i.Method == "" && utils.IsStringInSlice(fallback, methods) { if i.Method == "" && utils.IsStringInSlice(fallback, methods) {
i.Method = fallback i.Method = fallback
@ -50,8 +50,8 @@ func (i *UserInfo) setMethod(totp, webauthn, duo bool, methods []string, fallbac
switch { switch {
case i.HasTOTP && totp: case i.HasTOTP && totp:
i.Method = SecondFactorMethodTOTP i.Method = SecondFactorMethodTOTP
case i.HasWebauthn && webauthn: case i.HasWebAuthn && webauthn:
i.Method = SecondFactorMethodWebauthn i.Method = SecondFactorMethodWebAuthn
case i.HasDuo && duo: case i.HasDuo && duo:
i.Method = SecondFactorMethodDuo i.Method = SecondFactorMethodDuo
case fallback != "" && utils.IsStringInSlice(fallback, methods): case fallback != "" && utils.IsStringInSlice(fallback, methods):
@ -59,7 +59,7 @@ func (i *UserInfo) setMethod(totp, webauthn, duo bool, methods []string, fallbac
case totp: case totp:
i.Method = SecondFactorMethodTOTP i.Method = SecondFactorMethodTOTP
case webauthn: case webauthn:
i.Method = SecondFactorMethodWebauthn i.Method = SecondFactorMethodWebAuthn
case duo: case duo:
i.Method = SecondFactorMethodDuo i.Method = SecondFactorMethodDuo
} }

View File

@ -20,7 +20,7 @@ func TestUserInfo_SetDefaultMethod(t *testing.T) {
has := "" has := ""
if have.HasTOTP || have.HasDuo || have.HasWebauthn { if have.HasTOTP || have.HasDuo || have.HasWebAuthn {
has += " has" has += " has"
if have.HasTOTP { if have.HasTOTP {
@ -31,8 +31,8 @@ func TestUserInfo_SetDefaultMethod(t *testing.T) {
has += " " + SecondFactorMethodDuo has += " " + SecondFactorMethodDuo
} }
if have.HasWebauthn { if have.HasWebAuthn {
has += " " + SecondFactorMethodWebauthn has += " " + SecondFactorMethodWebAuthn
} }
} }
@ -62,60 +62,60 @@ func TestUserInfo_SetDefaultMethod(t *testing.T) {
Method: SecondFactorMethodTOTP, Method: SecondFactorMethodTOTP,
HasDuo: true, HasDuo: true,
HasTOTP: true, HasTOTP: true,
HasWebauthn: true, HasWebAuthn: true,
}, },
want: UserInfo{ want: UserInfo{
Method: SecondFactorMethodWebauthn, Method: SecondFactorMethodWebAuthn,
HasDuo: true, HasDuo: true,
HasTOTP: true, HasTOTP: true,
HasWebauthn: true, HasWebAuthn: true,
}, },
methods: []string{SecondFactorMethodWebauthn, SecondFactorMethodDuo}, methods: []string{SecondFactorMethodWebAuthn, SecondFactorMethodDuo},
changed: true, changed: true,
}, },
{ {
have: UserInfo{ have: UserInfo{
HasDuo: true, HasDuo: true,
HasTOTP: true, HasTOTP: true,
HasWebauthn: true, HasWebAuthn: true,
}, },
want: UserInfo{ want: UserInfo{
Method: SecondFactorMethodTOTP, Method: SecondFactorMethodTOTP,
HasDuo: true, HasDuo: true,
HasTOTP: true, HasTOTP: true,
HasWebauthn: true, HasWebAuthn: true,
}, },
methods: []string{SecondFactorMethodTOTP, SecondFactorMethodWebauthn, SecondFactorMethodDuo}, methods: []string{SecondFactorMethodTOTP, SecondFactorMethodWebAuthn, SecondFactorMethodDuo},
changed: true, changed: true,
}, },
{ {
have: UserInfo{ have: UserInfo{
Method: SecondFactorMethodWebauthn, Method: SecondFactorMethodWebAuthn,
HasDuo: true, HasDuo: true,
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
}, },
want: UserInfo{ want: UserInfo{
Method: SecondFactorMethodTOTP, Method: SecondFactorMethodTOTP,
HasDuo: true, HasDuo: true,
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
}, },
methods: []string{SecondFactorMethodTOTP}, methods: []string{SecondFactorMethodTOTP},
changed: true, changed: true,
}, },
{ {
have: UserInfo{ have: UserInfo{
Method: SecondFactorMethodWebauthn, Method: SecondFactorMethodWebAuthn,
HasDuo: false, HasDuo: false,
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
}, },
want: UserInfo{ want: UserInfo{
Method: SecondFactorMethodTOTP, Method: SecondFactorMethodTOTP,
HasDuo: false, HasDuo: false,
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
}, },
methods: []string{SecondFactorMethodTOTP}, methods: []string{SecondFactorMethodTOTP},
changed: true, changed: true,
@ -125,15 +125,15 @@ func TestUserInfo_SetDefaultMethod(t *testing.T) {
Method: SecondFactorMethodTOTP, Method: SecondFactorMethodTOTP,
HasDuo: false, HasDuo: false,
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
}, },
want: UserInfo{ want: UserInfo{
Method: SecondFactorMethodWebauthn, Method: SecondFactorMethodWebAuthn,
HasDuo: false, HasDuo: false,
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
}, },
methods: []string{SecondFactorMethodWebauthn}, methods: []string{SecondFactorMethodWebAuthn},
changed: true, changed: true,
}, },
{ {
@ -141,31 +141,31 @@ func TestUserInfo_SetDefaultMethod(t *testing.T) {
Method: SecondFactorMethodTOTP, Method: SecondFactorMethodTOTP,
HasDuo: false, HasDuo: false,
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
}, },
want: UserInfo{ want: UserInfo{
Method: SecondFactorMethodDuo, Method: SecondFactorMethodDuo,
HasDuo: false, HasDuo: false,
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
}, },
methods: []string{SecondFactorMethodDuo}, methods: []string{SecondFactorMethodDuo},
changed: true, changed: true,
}, },
{ {
have: UserInfo{ have: UserInfo{
Method: SecondFactorMethodWebauthn, Method: SecondFactorMethodWebAuthn,
HasDuo: false, HasDuo: false,
HasTOTP: true, HasTOTP: true,
HasWebauthn: true, HasWebAuthn: true,
}, },
want: UserInfo{ want: UserInfo{
Method: SecondFactorMethodWebauthn, Method: SecondFactorMethodWebAuthn,
HasDuo: false, HasDuo: false,
HasTOTP: true, HasTOTP: true,
HasWebauthn: true, HasWebAuthn: true,
}, },
methods: []string{SecondFactorMethodTOTP, SecondFactorMethodWebauthn, SecondFactorMethodDuo}, methods: []string{SecondFactorMethodTOTP, SecondFactorMethodWebAuthn, SecondFactorMethodDuo},
changed: false, changed: false,
}, },
{ {
@ -173,15 +173,15 @@ func TestUserInfo_SetDefaultMethod(t *testing.T) {
Method: "", Method: "",
HasDuo: false, HasDuo: false,
HasTOTP: true, HasTOTP: true,
HasWebauthn: true, HasWebAuthn: true,
}, },
want: UserInfo{ want: UserInfo{
Method: SecondFactorMethodWebauthn, Method: SecondFactorMethodWebAuthn,
HasDuo: false, HasDuo: false,
HasTOTP: true, HasTOTP: true,
HasWebauthn: true, HasWebAuthn: true,
}, },
methods: []string{SecondFactorMethodWebauthn, SecondFactorMethodDuo}, methods: []string{SecondFactorMethodWebAuthn, SecondFactorMethodDuo},
changed: true, changed: true,
}, },
{ {
@ -189,13 +189,13 @@ func TestUserInfo_SetDefaultMethod(t *testing.T) {
Method: "", Method: "",
HasDuo: false, HasDuo: false,
HasTOTP: true, HasTOTP: true,
HasWebauthn: true, HasWebAuthn: true,
}, },
want: UserInfo{ want: UserInfo{
Method: SecondFactorMethodDuo, Method: SecondFactorMethodDuo,
HasDuo: false, HasDuo: false,
HasTOTP: true, HasTOTP: true,
HasWebauthn: true, HasWebAuthn: true,
}, },
methods: []string{SecondFactorMethodDuo}, methods: []string{SecondFactorMethodDuo},
changed: true, changed: true,
@ -205,13 +205,13 @@ func TestUserInfo_SetDefaultMethod(t *testing.T) {
Method: "", Method: "",
HasDuo: false, HasDuo: false,
HasTOTP: true, HasTOTP: true,
HasWebauthn: true, HasWebAuthn: true,
}, },
want: UserInfo{ want: UserInfo{
Method: "", Method: "",
HasDuo: false, HasDuo: false,
HasTOTP: true, HasTOTP: true,
HasWebauthn: true, HasWebAuthn: true,
}, },
methods: nil, methods: nil,
changed: false, changed: false,
@ -221,15 +221,15 @@ func TestUserInfo_SetDefaultMethod(t *testing.T) {
Method: "", Method: "",
HasDuo: false, HasDuo: false,
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
}, },
want: UserInfo{ want: UserInfo{
Method: SecondFactorMethodDuo, Method: SecondFactorMethodDuo,
HasDuo: false, HasDuo: false,
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
}, },
methods: []string{SecondFactorMethodTOTP, SecondFactorMethodWebauthn, SecondFactorMethodDuo}, methods: []string{SecondFactorMethodTOTP, SecondFactorMethodWebAuthn, SecondFactorMethodDuo},
fallback: SecondFactorMethodDuo, fallback: SecondFactorMethodDuo,
changed: true, changed: true,
}, },
@ -238,15 +238,15 @@ func TestUserInfo_SetDefaultMethod(t *testing.T) {
Method: "", Method: "",
HasDuo: false, HasDuo: false,
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
}, },
want: UserInfo{ want: UserInfo{
Method: SecondFactorMethodTOTP, Method: SecondFactorMethodTOTP,
HasDuo: false, HasDuo: false,
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
}, },
methods: []string{SecondFactorMethodTOTP, SecondFactorMethodWebauthn}, methods: []string{SecondFactorMethodTOTP, SecondFactorMethodWebAuthn},
fallback: SecondFactorMethodDuo, fallback: SecondFactorMethodDuo,
changed: true, changed: true,
}, },
@ -255,15 +255,15 @@ func TestUserInfo_SetDefaultMethod(t *testing.T) {
Method: SecondFactorMethodTOTP, Method: SecondFactorMethodTOTP,
HasDuo: true, HasDuo: true,
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
}, },
want: UserInfo{ want: UserInfo{
Method: SecondFactorMethodDuo, Method: SecondFactorMethodDuo,
HasDuo: true, HasDuo: true,
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
}, },
methods: []string{SecondFactorMethodWebauthn, SecondFactorMethodDuo}, methods: []string{SecondFactorMethodWebAuthn, SecondFactorMethodDuo},
changed: true, changed: true,
}, },
{ {
@ -271,30 +271,30 @@ func TestUserInfo_SetDefaultMethod(t *testing.T) {
Method: SecondFactorMethodTOTP, Method: SecondFactorMethodTOTP,
HasDuo: false, HasDuo: false,
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
}, },
want: UserInfo{ want: UserInfo{
Method: SecondFactorMethodWebauthn, Method: SecondFactorMethodWebAuthn,
HasDuo: false, HasDuo: false,
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
}, },
methods: []string{SecondFactorMethodWebauthn, SecondFactorMethodDuo}, methods: []string{SecondFactorMethodWebAuthn, SecondFactorMethodDuo},
fallback: SecondFactorMethodWebauthn, fallback: SecondFactorMethodWebAuthn,
changed: true, changed: true,
}, },
{ {
have: UserInfo{ have: UserInfo{
Method: SecondFactorMethodWebauthn, Method: SecondFactorMethodWebAuthn,
HasDuo: false, HasDuo: false,
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
}, },
want: UserInfo{ want: UserInfo{
Method: SecondFactorMethodDuo, Method: SecondFactorMethodDuo,
HasDuo: false, HasDuo: false,
HasTOTP: false, HasTOTP: false,
HasWebauthn: false, HasWebAuthn: false,
}, },
methods: []string{SecondFactorMethodTOTP, SecondFactorMethodDuo}, methods: []string{SecondFactorMethodTOTP, SecondFactorMethodDuo},
fallback: SecondFactorMethodDuo, fallback: SecondFactorMethodDuo,

View File

@ -17,15 +17,15 @@ const (
attestationTypeFIDOU2F = "fido-u2f" attestationTypeFIDOU2F = "fido-u2f"
) )
// WebauthnUser is an object to represent a user for the Webauthn lib. // WebAuthnUser is an object to represent a user for the WebAuthn lib.
type WebauthnUser struct { type WebAuthnUser struct {
Username string Username string
DisplayName string DisplayName string
Devices []WebauthnDevice Devices []WebAuthnDevice
} }
// HasFIDOU2F returns true if the user has any attestation type `fido-u2f` devices. // HasFIDOU2F returns true if the user has any attestation type `fido-u2f` devices.
func (w WebauthnUser) HasFIDOU2F() bool { func (w WebAuthnUser) HasFIDOU2F() bool {
for _, c := range w.Devices { for _, c := range w.Devices {
if c.AttestationType == attestationTypeFIDOU2F { if c.AttestationType == attestationTypeFIDOU2F {
return true return true
@ -36,27 +36,27 @@ func (w WebauthnUser) HasFIDOU2F() bool {
} }
// WebAuthnID implements the webauthn.User interface. // WebAuthnID implements the webauthn.User interface.
func (w WebauthnUser) WebAuthnID() []byte { func (w WebAuthnUser) WebAuthnID() []byte {
return []byte(w.Username) return []byte(w.Username)
} }
// WebAuthnName implements the webauthn.User interface. // WebAuthnName implements the webauthn.User interface.
func (w WebauthnUser) WebAuthnName() string { func (w WebAuthnUser) WebAuthnName() string {
return w.Username return w.Username
} }
// WebAuthnDisplayName implements the webauthn.User interface. // WebAuthnDisplayName implements the webauthn.User interface.
func (w WebauthnUser) WebAuthnDisplayName() string { func (w WebAuthnUser) WebAuthnDisplayName() string {
return w.DisplayName return w.DisplayName
} }
// WebAuthnIcon implements the webauthn.User interface. // WebAuthnIcon implements the webauthn.User interface.
func (w WebauthnUser) WebAuthnIcon() string { func (w WebAuthnUser) WebAuthnIcon() string {
return "" return ""
} }
// WebAuthnCredentials implements the webauthn.User interface. // WebAuthnCredentials implements the webauthn.User interface.
func (w WebauthnUser) WebAuthnCredentials() (credentials []webauthn.Credential) { func (w WebAuthnUser) WebAuthnCredentials() (credentials []webauthn.Credential) {
credentials = make([]webauthn.Credential, len(w.Devices)) credentials = make([]webauthn.Credential, len(w.Devices))
var credential webauthn.Credential var credential webauthn.Credential
@ -96,7 +96,7 @@ func (w WebauthnUser) WebAuthnCredentials() (credentials []webauthn.Credential)
} }
// WebAuthnCredentialDescriptors decodes the users credentials into protocol.CredentialDescriptor's. // WebAuthnCredentialDescriptors decodes the users credentials into protocol.CredentialDescriptor's.
func (w WebauthnUser) WebAuthnCredentialDescriptors() (descriptors []protocol.CredentialDescriptor) { func (w WebAuthnUser) WebAuthnCredentialDescriptors() (descriptors []protocol.CredentialDescriptor) {
credentials := w.WebAuthnCredentials() credentials := w.WebAuthnCredentials()
descriptors = make([]protocol.CredentialDescriptor, len(credentials)) descriptors = make([]protocol.CredentialDescriptor, len(credentials))
@ -108,15 +108,15 @@ func (w WebauthnUser) WebAuthnCredentialDescriptors() (descriptors []protocol.Cr
return descriptors return descriptors
} }
// NewWebauthnDeviceFromCredential creates a WebauthnDevice from a webauthn.Credential. // NewWebAuthnDeviceFromCredential creates a WebAuthnDevice from a webauthn.Credential.
func NewWebauthnDeviceFromCredential(rpid, username, description string, credential *webauthn.Credential) (device WebauthnDevice) { func NewWebAuthnDeviceFromCredential(rpid, username, description string, credential *webauthn.Credential) (device WebAuthnDevice) {
transport := make([]string, len(credential.Transport)) transport := make([]string, len(credential.Transport))
for i, t := range credential.Transport { for i, t := range credential.Transport {
transport[i] = string(t) transport[i] = string(t)
} }
device = WebauthnDevice{ device = WebAuthnDevice{
RPID: rpid, RPID: rpid,
Username: username, Username: username,
CreatedAt: time.Now(), CreatedAt: time.Now(),
@ -137,8 +137,8 @@ func NewWebauthnDeviceFromCredential(rpid, username, description string, credent
return device return device
} }
// WebauthnDevice represents a Webauthn Device in the database storage. // WebAuthnDevice represents a WebAuthn Device in the database storage.
type WebauthnDevice struct { type WebAuthnDevice struct {
ID int `db:"id"` ID int `db:"id"`
CreatedAt time.Time `db:"created_at"` CreatedAt time.Time `db:"created_at"`
LastUsedAt sql.NullTime `db:"last_used_at"` LastUsedAt sql.NullTime `db:"last_used_at"`
@ -154,8 +154,8 @@ type WebauthnDevice struct {
CloneWarning bool `db:"clone_warning"` CloneWarning bool `db:"clone_warning"`
} }
// UpdateSignInInfo adjusts the values of the WebauthnDevice after a sign in. // UpdateSignInInfo adjusts the values of the WebAuthnDevice after a sign in.
func (d *WebauthnDevice) UpdateSignInInfo(config *webauthn.Config, now time.Time, signCount uint32) { func (d *WebAuthnDevice) UpdateSignInInfo(config *webauthn.Config, now time.Time, signCount uint32) {
d.LastUsedAt = sql.NullTime{Time: now, Valid: true} d.LastUsedAt = sql.NullTime{Time: now, Valid: true}
d.SignCount = signCount d.SignCount = signCount
@ -172,7 +172,7 @@ func (d *WebauthnDevice) UpdateSignInInfo(config *webauthn.Config, now time.Time
} }
} }
func (d *WebauthnDevice) LastUsed() *time.Time { func (d *WebAuthnDevice) LastUsed() *time.Time {
if d.LastUsedAt.Valid { if d.LastUsedAt.Valid {
return &d.LastUsedAt.Time return &d.LastUsedAt.Time
} }
@ -181,8 +181,8 @@ func (d *WebauthnDevice) LastUsed() *time.Time {
} }
// MarshalYAML marshals this model into YAML. // MarshalYAML marshals this model into YAML.
func (d *WebauthnDevice) MarshalYAML() (any, error) { func (d *WebAuthnDevice) MarshalYAML() (any, error) {
o := WebauthnDeviceData{ o := WebAuthnDeviceData{
CreatedAt: d.CreatedAt, CreatedAt: d.CreatedAt,
LastUsedAt: d.LastUsed(), LastUsedAt: d.LastUsed(),
RPID: d.RPID, RPID: d.RPID,
@ -201,8 +201,8 @@ func (d *WebauthnDevice) MarshalYAML() (any, error) {
} }
// UnmarshalYAML unmarshalls YAML into this model. // UnmarshalYAML unmarshalls YAML into this model.
func (d *WebauthnDevice) UnmarshalYAML(value *yaml.Node) (err error) { func (d *WebAuthnDevice) UnmarshalYAML(value *yaml.Node) (err error) {
o := &WebauthnDeviceData{} o := &WebAuthnDeviceData{}
if err = value.Decode(o); err != nil { if err = value.Decode(o); err != nil {
return err return err
@ -246,8 +246,8 @@ func (d *WebauthnDevice) UnmarshalYAML(value *yaml.Node) (err error) {
return nil return nil
} }
// WebauthnDeviceData represents a Webauthn Device in the database storage. // WebAuthnDeviceData represents a WebAuthn Device in the database storage.
type WebauthnDeviceData struct { type WebAuthnDeviceData struct {
CreatedAt time.Time `yaml:"created_at"` CreatedAt time.Time `yaml:"created_at"`
LastUsedAt *time.Time `yaml:"last_used_at"` LastUsedAt *time.Time `yaml:"last_used_at"`
RPID string `yaml:"rpid"` RPID string `yaml:"rpid"`
@ -262,7 +262,7 @@ type WebauthnDeviceData struct {
CloneWarning bool `yaml:"clone_warning"` CloneWarning bool `yaml:"clone_warning"`
} }
// WebauthnDeviceExport represents a WebauthnDevice export file. // WebAuthnDeviceExport represents a WebAuthnDevice export file.
type WebauthnDeviceExport struct { type WebAuthnDeviceExport struct {
WebauthnDevices []WebauthnDevice `yaml:"webauthn_devices"` WebAuthnDevices []WebAuthnDevice `yaml:"webauthn_devices"`
} }

View File

@ -38,12 +38,12 @@ type Provider interface {
LoadTOTPConfiguration(ctx context.Context, username string) (config *model.TOTPConfiguration, err error) LoadTOTPConfiguration(ctx context.Context, username string) (config *model.TOTPConfiguration, err error)
LoadTOTPConfigurations(ctx context.Context, limit, page int) (configs []model.TOTPConfiguration, err error) LoadTOTPConfigurations(ctx context.Context, limit, page int) (configs []model.TOTPConfiguration, err error)
SaveWebauthnDevice(ctx context.Context, device model.WebauthnDevice) (err error) SaveWebauthnDevice(ctx context.Context, device model.WebAuthnDevice) (err error)
UpdateWebauthnDeviceSignIn(ctx context.Context, id int, rpid string, lastUsedAt sql.NullTime, signCount uint32, cloneWarning bool) (err error) UpdateWebauthnDeviceSignIn(ctx context.Context, id int, rpid string, lastUsedAt sql.NullTime, signCount uint32, cloneWarning bool) (err error)
DeleteWebauthnDevice(ctx context.Context, kid string) (err error) DeleteWebauthnDevice(ctx context.Context, kid string) (err error)
DeleteWebauthnDeviceByUsername(ctx context.Context, username, description string) (err error) DeleteWebauthnDeviceByUsername(ctx context.Context, username, description string) (err error)
LoadWebauthnDevices(ctx context.Context, limit, page int) (devices []model.WebauthnDevice, err error) LoadWebauthnDevices(ctx context.Context, limit, page int) (devices []model.WebAuthnDevice, err error)
LoadWebauthnDevicesByUsername(ctx context.Context, username string) (devices []model.WebauthnDevice, err error) LoadWebauthnDevicesByUsername(ctx context.Context, username string) (devices []model.WebAuthnDevice, err error)
SavePreferredDuoDevice(ctx context.Context, device model.DuoDevice) (err error) SavePreferredDuoDevice(ctx context.Context, device model.DuoDevice) (err error)
DeletePreferredDuoDevice(ctx context.Context, username string) (err error) DeletePreferredDuoDevice(ctx context.Context, username string) (err error)

View File

@ -882,7 +882,7 @@ func (p *SQLProvider) LoadTOTPConfigurations(ctx context.Context, limit, page in
} }
// SaveWebauthnDevice saves a registered Webauthn device. // SaveWebauthnDevice saves a registered Webauthn device.
func (p *SQLProvider) SaveWebauthnDevice(ctx context.Context, device model.WebauthnDevice) (err error) { func (p *SQLProvider) SaveWebauthnDevice(ctx context.Context, device model.WebAuthnDevice) (err error) {
if device.PublicKey, err = p.encrypt(device.PublicKey); err != nil { if device.PublicKey, err = p.encrypt(device.PublicKey); err != nil {
return fmt.Errorf("error encrypting Webauthn device public key for user '%s' kid '%x': %w", device.Username, device.KID, err) return fmt.Errorf("error encrypting Webauthn device public key for user '%s' kid '%x': %w", device.Username, device.KID, err)
} }
@ -937,8 +937,8 @@ func (p *SQLProvider) DeleteWebauthnDeviceByUsername(ctx context.Context, userna
} }
// LoadWebauthnDevices loads Webauthn device registrations. // LoadWebauthnDevices loads Webauthn device registrations.
func (p *SQLProvider) LoadWebauthnDevices(ctx context.Context, limit, page int) (devices []model.WebauthnDevice, err error) { func (p *SQLProvider) LoadWebauthnDevices(ctx context.Context, limit, page int) (devices []model.WebAuthnDevice, err error) {
devices = make([]model.WebauthnDevice, 0, limit) devices = make([]model.WebAuthnDevice, 0, limit)
if err = p.db.SelectContext(ctx, &devices, p.sqlSelectWebauthnDevices, limit, limit*page); err != nil { if err = p.db.SelectContext(ctx, &devices, p.sqlSelectWebauthnDevices, limit, limit*page); err != nil {
if errors.Is(err, sql.ErrNoRows) { if errors.Is(err, sql.ErrNoRows) {
@ -958,7 +958,7 @@ func (p *SQLProvider) LoadWebauthnDevices(ctx context.Context, limit, page int)
} }
// LoadWebauthnDevicesByUsername loads all webauthn devices registration for a given username. // LoadWebauthnDevicesByUsername loads all webauthn devices registration for a given username.
func (p *SQLProvider) LoadWebauthnDevicesByUsername(ctx context.Context, username string) (devices []model.WebauthnDevice, err error) { func (p *SQLProvider) LoadWebauthnDevicesByUsername(ctx context.Context, username string) (devices []model.WebAuthnDevice, err error) {
if err = p.db.SelectContext(ctx, &devices, p.sqlSelectWebauthnDevicesByUsername, username); err != nil { if err = p.db.SelectContext(ctx, &devices, p.sqlSelectWebauthnDevicesByUsername, username); err != nil {
if errors.Is(err, sql.ErrNoRows) { if errors.Is(err, sql.ErrNoRows) {
return nil, ErrNoWebauthnDevice return nil, ErrNoWebauthnDevice