feat(commands): add webauthn device commands (#3671)
parent
52102eea8c
commit
24e41aed84
|
@ -62,4 +62,5 @@ authelia storage user --help
|
|||
* [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 totp](authelia_storage_user_totp.md) - Manage TOTP configurations
|
||||
* [authelia storage user webauthn](authelia_storage_user_webauthn.md) - Manage Webauthn devices
|
||||
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
---
|
||||
title: "authelia storage user webauthn"
|
||||
description: "Reference for the authelia storage user webauthn command."
|
||||
lead: ""
|
||||
date: 2022-06-15T17:51:47+10:00
|
||||
draft: false
|
||||
images: []
|
||||
menu:
|
||||
reference:
|
||||
parent: "cli-authelia"
|
||||
weight: 330
|
||||
toc: true
|
||||
---
|
||||
|
||||
## authelia storage user webauthn
|
||||
|
||||
Manage Webauthn devices
|
||||
|
||||
### Synopsis
|
||||
|
||||
Manage Webauthn devices.
|
||||
|
||||
This subcommand allows interacting with Webauthn devices.
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
authelia storage user webauthn --help
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for webauthn
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
-c, --config strings configuration files to load (default [configuration.yml])
|
||||
--encryption-key string the storage encryption key to use
|
||||
--mysql.database string the MySQL database name (default "authelia")
|
||||
--mysql.host string the MySQL hostname
|
||||
--mysql.password string the MySQL password
|
||||
--mysql.port int the MySQL port (default 3306)
|
||||
--mysql.username string the MySQL username (default "authelia")
|
||||
--postgres.database string the PostgreSQL database name (default "authelia")
|
||||
--postgres.host string the PostgreSQL hostname
|
||||
--postgres.password string the PostgreSQL password
|
||||
--postgres.port int the PostgreSQL port (default 5432)
|
||||
--postgres.schema string the PostgreSQL schema name (default "public")
|
||||
--postgres.ssl.certificate string the PostgreSQL ssl certificate file location
|
||||
--postgres.ssl.key string the PostgreSQL ssl key file location
|
||||
--postgres.ssl.mode string the PostgreSQL ssl mode (default "disable")
|
||||
--postgres.ssl.root_certificate string the PostgreSQL ssl root certificate file location
|
||||
--postgres.username string the PostgreSQL username (default "authelia")
|
||||
--sqlite.path string the SQLite database path
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [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 list](authelia_storage_user_webauthn_list.md) - List WebAuthn devices
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
---
|
||||
title: "authelia storage user webauthn delete"
|
||||
description: "Reference for the authelia storage user webauthn delete command."
|
||||
lead: ""
|
||||
date: 2022-06-15T17:51:47+10:00
|
||||
draft: false
|
||||
images: []
|
||||
menu:
|
||||
reference:
|
||||
parent: "cli-authelia"
|
||||
weight: 330
|
||||
toc: true
|
||||
---
|
||||
|
||||
## authelia storage user webauthn delete
|
||||
|
||||
Delete a WebAuthn device
|
||||
|
||||
### Synopsis
|
||||
|
||||
Delete a WebAuthn device.
|
||||
|
||||
This subcommand allows deleting a WebAuthn device directly from the database.
|
||||
|
||||
```
|
||||
authelia storage user webauthn delete [username] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
authelia storage user webauthn delete john --all
|
||||
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 --description Primary
|
||||
authelia storage user webauthn delete john --description Primary --config config.yml
|
||||
authelia storage user webauthn delete john --description Primary --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw
|
||||
authelia storage user webauthn delete --kid abc123
|
||||
authelia storage user webauthn delete --kid abc123 --config config.yml
|
||||
authelia storage user webauthn delete --kid abc123 --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
--all delete all of the users webauthn devices
|
||||
--description string delete a users webauthn device by description
|
||||
-h, --help help for delete
|
||||
--kid string delete a users webauthn device by key id
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
-c, --config strings configuration files to load (default [configuration.yml])
|
||||
--encryption-key string the storage encryption key to use
|
||||
--mysql.database string the MySQL database name (default "authelia")
|
||||
--mysql.host string the MySQL hostname
|
||||
--mysql.password string the MySQL password
|
||||
--mysql.port int the MySQL port (default 3306)
|
||||
--mysql.username string the MySQL username (default "authelia")
|
||||
--postgres.database string the PostgreSQL database name (default "authelia")
|
||||
--postgres.host string the PostgreSQL hostname
|
||||
--postgres.password string the PostgreSQL password
|
||||
--postgres.port int the PostgreSQL port (default 5432)
|
||||
--postgres.schema string the PostgreSQL schema name (default "public")
|
||||
--postgres.ssl.certificate string the PostgreSQL ssl certificate file location
|
||||
--postgres.ssl.key string the PostgreSQL ssl key file location
|
||||
--postgres.ssl.mode string the PostgreSQL ssl mode (default "disable")
|
||||
--postgres.ssl.root_certificate string the PostgreSQL ssl root certificate file location
|
||||
--postgres.username string the PostgreSQL username (default "authelia")
|
||||
--sqlite.path string the SQLite database path
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [authelia storage user webauthn](authelia_storage_user_webauthn.md) - Manage Webauthn devices
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
---
|
||||
title: "authelia storage user webauthn list"
|
||||
description: "Reference for the authelia storage user webauthn list command."
|
||||
lead: ""
|
||||
date: 2022-06-15T17:51:47+10:00
|
||||
draft: false
|
||||
images: []
|
||||
menu:
|
||||
reference:
|
||||
parent: "cli-authelia"
|
||||
weight: 330
|
||||
toc: true
|
||||
---
|
||||
|
||||
## authelia storage user webauthn list
|
||||
|
||||
List WebAuthn devices
|
||||
|
||||
### Synopsis
|
||||
|
||||
List WebAuthn devices.
|
||||
|
||||
This subcommand allows listing WebAuthn devices.
|
||||
|
||||
```
|
||||
authelia storage user webauthn list [username] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
authelia storage user webauthn list
|
||||
authelia storage user webauthn list john
|
||||
authelia storage user webauthn list --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 john --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for list
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
-c, --config strings configuration files to load (default [configuration.yml])
|
||||
--encryption-key string the storage encryption key to use
|
||||
--mysql.database string the MySQL database name (default "authelia")
|
||||
--mysql.host string the MySQL hostname
|
||||
--mysql.password string the MySQL password
|
||||
--mysql.port int the MySQL port (default 3306)
|
||||
--mysql.username string the MySQL username (default "authelia")
|
||||
--postgres.database string the PostgreSQL database name (default "authelia")
|
||||
--postgres.host string the PostgreSQL hostname
|
||||
--postgres.password string the PostgreSQL password
|
||||
--postgres.port int the PostgreSQL port (default 5432)
|
||||
--postgres.schema string the PostgreSQL schema name (default "public")
|
||||
--postgres.ssl.certificate string the PostgreSQL ssl certificate file location
|
||||
--postgres.ssl.key string the PostgreSQL ssl key file location
|
||||
--postgres.ssl.mode string the PostgreSQL ssl mode (default "disable")
|
||||
--postgres.ssl.root_certificate string the PostgreSQL ssl root certificate file location
|
||||
--postgres.username string the PostgreSQL username (default "authelia")
|
||||
--sqlite.path string the SQLite database path
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [authelia storage user webauthn](authelia_storage_user_webauthn.md) - Manage Webauthn devices
|
||||
|
|
@ -176,6 +176,43 @@ 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 --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||
|
||||
cmdAutheliaStorageUserWebAuthnShort = "Manage Webauthn devices"
|
||||
|
||||
cmdAutheliaStorageUserWebAuthnLong = `Manage Webauthn devices.
|
||||
|
||||
This subcommand allows interacting with Webauthn devices.`
|
||||
|
||||
cmdAutheliaStorageUserWebAuthnExample = `authelia storage user webauthn --help`
|
||||
|
||||
cmdAutheliaStorageUserWebAuthnListShort = "List WebAuthn devices"
|
||||
|
||||
cmdAutheliaStorageUserWebAuthnListLong = `List WebAuthn devices.
|
||||
|
||||
This subcommand allows listing WebAuthn devices.`
|
||||
|
||||
cmdAutheliaStorageUserWebAuthnListExample = `authelia storage user webauthn list
|
||||
authelia storage user webauthn list john
|
||||
authelia storage user webauthn list --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 john --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||
|
||||
cmdAutheliaStorageUserWebAuthnDeleteShort = "Delete a WebAuthn device"
|
||||
|
||||
cmdAutheliaStorageUserWebAuthnDeleteLong = `Delete a WebAuthn device.
|
||||
|
||||
This subcommand allows deleting a WebAuthn device directly from the database.`
|
||||
|
||||
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 --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 --config config.yml
|
||||
authelia storage user webauthn delete john --description Primary --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw
|
||||
authelia storage user webauthn delete --kid abc123
|
||||
authelia storage user webauthn delete --kid abc123 --config config.yml
|
||||
authelia storage user webauthn delete --kid abc123 --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||
|
||||
cmdAutheliaStorageUserTOTPShort = "Manage TOTP configurations"
|
||||
|
||||
cmdAutheliaStorageUserTOTPLong = `Manage TOTP configurations.
|
||||
|
|
|
@ -117,6 +117,7 @@ func newStorageUserCmd() (cmd *cobra.Command) {
|
|||
cmd.AddCommand(
|
||||
newStorageUserIdentifiersCmd(),
|
||||
newStorageUserTOTPCmd(),
|
||||
newStorageUserWebAuthnCmd(),
|
||||
)
|
||||
|
||||
return cmd
|
||||
|
@ -211,6 +212,58 @@ func newStorageUserIdentifiersAddCmd() (cmd *cobra.Command) {
|
|||
return cmd
|
||||
}
|
||||
|
||||
func newStorageUserWebAuthnCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "webauthn",
|
||||
Short: cmdAutheliaStorageUserWebAuthnShort,
|
||||
Long: cmdAutheliaStorageUserWebAuthnLong,
|
||||
Example: cmdAutheliaStorageUserWebAuthnExample,
|
||||
|
||||
DisableAutoGenTag: true,
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
newStorageUserWebAuthnListCmd(),
|
||||
newStorageUserWebAuthnDeleteCmd(),
|
||||
)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newStorageUserWebAuthnListCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "list [username]",
|
||||
Short: cmdAutheliaStorageUserWebAuthnListShort,
|
||||
Long: cmdAutheliaStorageUserWebAuthnListLong,
|
||||
Example: cmdAutheliaStorageUserWebAuthnListExample,
|
||||
RunE: storageWebAuthnListRunE,
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
|
||||
DisableAutoGenTag: true,
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newStorageUserWebAuthnDeleteCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "delete [username]",
|
||||
Short: cmdAutheliaStorageUserWebAuthnDeleteShort,
|
||||
Long: cmdAutheliaStorageUserWebAuthnDeleteLong,
|
||||
Example: cmdAutheliaStorageUserWebAuthnDeleteExample,
|
||||
RunE: storageWebAuthnDeleteRunE,
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
|
||||
DisableAutoGenTag: true,
|
||||
}
|
||||
|
||||
cmd.Flags().Bool("all", false, "delete all of the users webauthn devices")
|
||||
cmd.Flags().String("description", "", "delete a users webauthn device by description")
|
||||
cmd.Flags().String("kid", "", "delete a users webauthn device by key id")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newStorageUserTOTPCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "totp",
|
||||
|
|
|
@ -205,6 +205,187 @@ func storageSchemaEncryptionChangeKeyRunE(cmd *cobra.Command, args []string) (er
|
|||
return nil
|
||||
}
|
||||
|
||||
func storageWebAuthnListRunE(cmd *cobra.Command, args []string) (err error) {
|
||||
if len(args) == 0 || args[0] == "" {
|
||||
return storageWebAuthnListAllRunE(cmd, args)
|
||||
}
|
||||
|
||||
var (
|
||||
provider storage.Provider
|
||||
ctx = context.Background()
|
||||
)
|
||||
|
||||
provider = getStorageProvider()
|
||||
|
||||
defer func() {
|
||||
_ = provider.Close()
|
||||
}()
|
||||
|
||||
var devices []model.WebauthnDevice
|
||||
|
||||
user := args[0]
|
||||
|
||||
devices, err = provider.LoadWebauthnDevicesByUsername(ctx, user)
|
||||
|
||||
switch {
|
||||
case len(devices) == 0 || (err != nil && errors.Is(err, storage.ErrNoWebauthnDevice)):
|
||||
return fmt.Errorf("user '%s' has no webauthn devices", user)
|
||||
case err != nil:
|
||||
return fmt.Errorf("can't list devices for user '%s': %w", user, err)
|
||||
default:
|
||||
fmt.Printf("Webauthn Devices for user '%s':\n\n", user)
|
||||
fmt.Printf("ID\tKID\tDescription\n")
|
||||
|
||||
for _, device := range devices {
|
||||
fmt.Printf("%d\t%s\t%s", device.ID, device.KID, device.Description)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func storageWebAuthnListAllRunE(_ *cobra.Command, _ []string) (err error) {
|
||||
var (
|
||||
provider storage.Provider
|
||||
ctx = context.Background()
|
||||
)
|
||||
|
||||
provider = getStorageProvider()
|
||||
|
||||
defer func() {
|
||||
_ = provider.Close()
|
||||
}()
|
||||
|
||||
var devices []model.WebauthnDevice
|
||||
|
||||
limit := 10
|
||||
|
||||
output := strings.Builder{}
|
||||
|
||||
for page := 0; true; page++ {
|
||||
if devices, err = provider.LoadWebauthnDevices(ctx, limit, page); err != nil {
|
||||
return fmt.Errorf("failed to list devices: %w", err)
|
||||
}
|
||||
|
||||
if page == 0 && len(devices) == 0 {
|
||||
return errors.New("no webauthn devices in database")
|
||||
}
|
||||
|
||||
for _, device := range devices {
|
||||
output.WriteString(fmt.Sprintf("%d\t%s\t%s\t%s\n", device.ID, device.KID, device.Description, device.Username))
|
||||
}
|
||||
|
||||
if len(devices) < limit {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("Webauthn Devices:\n\nID\tKID\tDescription\tUsername\n")
|
||||
fmt.Println(output.String())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func storageWebAuthnDeleteRunE(cmd *cobra.Command, args []string) (err error) {
|
||||
var (
|
||||
provider storage.Provider
|
||||
ctx = context.Background()
|
||||
)
|
||||
|
||||
provider = getStorageProvider()
|
||||
|
||||
defer func() {
|
||||
_ = provider.Close()
|
||||
}()
|
||||
|
||||
var (
|
||||
all, byKID bool
|
||||
description, kid, user string
|
||||
)
|
||||
|
||||
if all, byKID, description, kid, user, err = storageWebAuthnDeleteGetAndValidateConfig(cmd, args); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if byKID {
|
||||
if err = provider.DeleteWebauthnDevice(ctx, kid); err != nil {
|
||||
return fmt.Errorf("failed to delete WebAuthn device with kid '%s': %w", kid, err)
|
||||
}
|
||||
|
||||
fmt.Printf("Deleted WebAuthn device with kid '%s'", kid)
|
||||
} else {
|
||||
err = provider.DeleteWebauthnDeviceByUsername(ctx, user, description)
|
||||
|
||||
if all {
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete all WebAuthn devices with username '%s': %w", user, err)
|
||||
}
|
||||
|
||||
fmt.Printf("Deleted all WebAuthn devices for user '%s'", user)
|
||||
} else {
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete WebAuthn device with username '%s' and description '%s': %w", user, description, err)
|
||||
}
|
||||
|
||||
fmt.Printf("Deleted WebAuthn device with username '%s' and description '%s'", user, description)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func storageWebAuthnDeleteGetAndValidateConfig(cmd *cobra.Command, args []string) (all, byKID bool, description, kid, user string, err error) {
|
||||
if len(args) != 0 {
|
||||
user = args[0]
|
||||
}
|
||||
|
||||
flags := 0
|
||||
|
||||
if cmd.Flags().Changed("all") {
|
||||
if all, err = cmd.Flags().GetBool("all"); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
flags++
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed("description") {
|
||||
if description, err = cmd.Flags().GetString("description"); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
flags++
|
||||
}
|
||||
|
||||
if byKID = cmd.Flags().Changed("kid"); byKID {
|
||||
if kid, err = cmd.Flags().GetString("kid"); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
flags++
|
||||
}
|
||||
|
||||
if flags > 1 {
|
||||
err = fmt.Errorf("must only supply one of the flags --all, --description, and --kid but %d were specified", flags)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if flags == 0 {
|
||||
err = fmt.Errorf("must supply one of the flags --all, --description, or --kid")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if !byKID && len(user) == 0 {
|
||||
err = fmt.Errorf("must supply the username or the --kid flag")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func storageTOTPGenerateRunE(cmd *cobra.Command, args []string) (err error) {
|
||||
var (
|
||||
provider storage.Provider
|
||||
|
|
|
@ -166,6 +166,34 @@ func (mr *MockStorageMockRecorder) DeleteTOTPConfiguration(arg0, arg1 interface{
|
|||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteTOTPConfiguration", reflect.TypeOf((*MockStorage)(nil).DeleteTOTPConfiguration), arg0, arg1)
|
||||
}
|
||||
|
||||
// DeleteWebauthnDevice mocks base method.
|
||||
func (m *MockStorage) DeleteWebauthnDevice(arg0 context.Context, arg1 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DeleteWebauthnDevice", arg0, arg1)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// DeleteWebauthnDevice indicates an expected call of DeleteWebauthnDevice.
|
||||
func (mr *MockStorageMockRecorder) DeleteWebauthnDevice(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteWebauthnDevice", reflect.TypeOf((*MockStorage)(nil).DeleteWebauthnDevice), arg0, arg1)
|
||||
}
|
||||
|
||||
// DeleteWebauthnDeviceByUsername mocks base method.
|
||||
func (m *MockStorage) DeleteWebauthnDeviceByUsername(arg0 context.Context, arg1, arg2 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DeleteWebauthnDeviceByUsername", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// DeleteWebauthnDeviceByUsername indicates an expected call of DeleteWebauthnDeviceByUsername.
|
||||
func (mr *MockStorageMockRecorder) DeleteWebauthnDeviceByUsername(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteWebauthnDeviceByUsername", reflect.TypeOf((*MockStorage)(nil).DeleteWebauthnDeviceByUsername), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// FindIdentityVerification mocks base method.
|
||||
func (m *MockStorage) FindIdentityVerification(arg0 context.Context, arg1 string) (bool, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
|
|
@ -39,6 +39,8 @@ type Provider interface {
|
|||
|
||||
SaveWebauthnDevice(ctx context.Context, device model.WebauthnDevice) (err error)
|
||||
UpdateWebauthnDeviceSignIn(ctx context.Context, id int, rpid string, lastUsedAt *time.Time, signCount uint32, cloneWarning bool) (err error)
|
||||
DeleteWebauthnDevice(ctx context.Context, kid string) (err error)
|
||||
DeleteWebauthnDeviceByUsername(ctx context.Context, username, description string) (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)
|
||||
|
||||
|
|
|
@ -56,6 +56,10 @@ func NewSQLProvider(config *schema.Configuration, name, driverName, dataSourceNa
|
|||
sqlUpdateWebauthnDeviceRecordSignIn: fmt.Sprintf(queryFmtUpdateWebauthnDeviceRecordSignIn, tableWebauthnDevices),
|
||||
sqlUpdateWebauthnDeviceRecordSignInByUsername: fmt.Sprintf(queryFmtUpdateWebauthnDeviceRecordSignInByUsername, tableWebauthnDevices),
|
||||
|
||||
sqlDeleteWebauthnDevice: fmt.Sprintf(queryFmtDeleteWebauthnDevice, tableWebauthnDevices),
|
||||
sqlDeleteWebauthnDeviceByUsername: fmt.Sprintf(queryFmtDeleteWebauthnDeviceByUsername, tableWebauthnDevices),
|
||||
sqlDeleteWebauthnDeviceByUsernameAndDescription: fmt.Sprintf(queryFmtDeleteWebauthnDeviceByUsernameAndDescription, tableWebauthnDevices),
|
||||
|
||||
sqlUpsertDuoDevice: fmt.Sprintf(queryFmtUpsertDuoDevice, tableDuoDevices),
|
||||
sqlDeleteDuoDevice: fmt.Sprintf(queryFmtDeleteDuoDevice, tableDuoDevices),
|
||||
sqlSelectDuoDevice: fmt.Sprintf(queryFmtSelectDuoDevice, tableDuoDevices),
|
||||
|
@ -169,6 +173,10 @@ type SQLProvider struct {
|
|||
sqlUpdateWebauthnDeviceRecordSignIn string
|
||||
sqlUpdateWebauthnDeviceRecordSignInByUsername string
|
||||
|
||||
sqlDeleteWebauthnDevice string
|
||||
sqlDeleteWebauthnDeviceByUsername string
|
||||
sqlDeleteWebauthnDeviceByUsernameAndDescription string
|
||||
|
||||
// Table: duo_devices.
|
||||
sqlUpsertDuoDevice string
|
||||
sqlDeleteDuoDevice string
|
||||
|
@ -841,6 +849,34 @@ func (p *SQLProvider) UpdateWebauthnDeviceSignIn(ctx context.Context, id int, rp
|
|||
return nil
|
||||
}
|
||||
|
||||
// DeleteWebauthnDevice deletes a registered Webauthn device.
|
||||
func (p *SQLProvider) DeleteWebauthnDevice(ctx context.Context, kid string) (err error) {
|
||||
if _, err = p.db.ExecContext(ctx, p.sqlDeleteWebauthnDevice, kid); err != nil {
|
||||
return fmt.Errorf("error deleting webauthn device with kid '%s': %w", kid, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteWebauthnDeviceByUsername deletes registered Webauthn devices by username or username and description.
|
||||
func (p *SQLProvider) DeleteWebauthnDeviceByUsername(ctx context.Context, username, description string) (err error) {
|
||||
if len(username) == 0 {
|
||||
return fmt.Errorf("error deleting webauthn device with username '%s' and description '%s': username must not be empty", username, description)
|
||||
}
|
||||
|
||||
if len(description) == 0 {
|
||||
if _, err = p.db.ExecContext(ctx, p.sqlDeleteWebauthnDeviceByUsername, username); err != nil {
|
||||
return fmt.Errorf("error deleting webauthn devices for username '%s': %w", username, err)
|
||||
}
|
||||
} else {
|
||||
if _, err = p.db.ExecContext(ctx, p.sqlDeleteWebauthnDeviceByUsernameAndDescription, username, description); err != nil {
|
||||
return fmt.Errorf("error deleting webauthn device with username '%s' and description '%s': %w", username, description, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoadWebauthnDevices loads Webauthn device registrations.
|
||||
func (p *SQLProvider) LoadWebauthnDevices(ctx context.Context, limit, page int) (devices []model.WebauthnDevice, err error) {
|
||||
devices = make([]model.WebauthnDevice, 0, limit)
|
||||
|
|
|
@ -61,6 +61,9 @@ func NewPostgreSQLProvider(config *schema.Configuration) (provider *PostgreSQLPr
|
|||
provider.sqlUpdateWebauthnDevicePublicKeyByUsername = provider.db.Rebind(provider.sqlUpdateWebauthnDevicePublicKeyByUsername)
|
||||
provider.sqlUpdateWebauthnDeviceRecordSignIn = provider.db.Rebind(provider.sqlUpdateWebauthnDeviceRecordSignIn)
|
||||
provider.sqlUpdateWebauthnDeviceRecordSignInByUsername = provider.db.Rebind(provider.sqlUpdateWebauthnDeviceRecordSignInByUsername)
|
||||
provider.sqlDeleteWebauthnDevice = provider.db.Rebind(provider.sqlDeleteWebauthnDevice)
|
||||
provider.sqlDeleteWebauthnDeviceByUsername = provider.db.Rebind(provider.sqlDeleteWebauthnDeviceByUsername)
|
||||
provider.sqlDeleteWebauthnDeviceByUsernameAndDescription = provider.db.Rebind(provider.sqlDeleteWebauthnDeviceByUsernameAndDescription)
|
||||
|
||||
provider.sqlSelectDuoDevice = provider.db.Rebind(provider.sqlSelectDuoDevice)
|
||||
provider.sqlDeleteDuoDevice = provider.db.Rebind(provider.sqlDeleteDuoDevice)
|
||||
|
|
|
@ -122,13 +122,13 @@ const (
|
|||
|
||||
const (
|
||||
queryFmtSelectWebauthnDevices = `
|
||||
SELECT id, created_at, last_used_at, rpid, username, description, kid, public_key, attestation_type, transport, aaguid, sign_count, clone_warning
|
||||
SELECT id, created_at, last_used_at, rpid, username, description, kid, public_key, attestation_type, transport, aaguid, sign_count, clone_warning
|
||||
FROM %s
|
||||
LIMIT ?
|
||||
OFFSET ?;`
|
||||
|
||||
queryFmtSelectWebauthnDevicesByUsername = `
|
||||
SELECT id, created_at, last_used_at, rpid, username, description, kid, public_key, attestation_type, transport, aaguid, sign_count, clone_warning
|
||||
SELECT id, created_at, last_used_at, rpid, username, description, kid, public_key, attestation_type, transport, aaguid, sign_count, clone_warning
|
||||
FROM %s
|
||||
WHERE username = ?;`
|
||||
|
||||
|
@ -144,14 +144,14 @@ const (
|
|||
|
||||
queryFmtUpdateWebauthnDeviceRecordSignIn = `
|
||||
UPDATE %s
|
||||
SET
|
||||
SET
|
||||
rpid = ?, last_used_at = ?, sign_count = ?,
|
||||
clone_warning = CASE clone_warning WHEN TRUE THEN TRUE ELSE ? END
|
||||
WHERE id = ?;`
|
||||
|
||||
queryFmtUpdateWebauthnDeviceRecordSignInByUsername = `
|
||||
UPDATE %s
|
||||
SET
|
||||
SET
|
||||
rpid = ?, last_used_at = ?, sign_count = ?,
|
||||
clone_warning = CASE clone_warning WHEN TRUE THEN TRUE ELSE ? END
|
||||
WHERE username = ? AND kid = ?;`
|
||||
|
@ -165,6 +165,18 @@ const (
|
|||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
|
||||
ON CONFLICT (username, description)
|
||||
DO UPDATE SET created_at = $1, last_used_at = $2, rpid = $3, kid = $6, public_key = $7, attestation_type = $8, transport = $9, aaguid = $10, sign_count = $11, clone_warning = $12;`
|
||||
|
||||
queryFmtDeleteWebauthnDevice = `
|
||||
DELETE FROM %s
|
||||
WHERE kid = ?;`
|
||||
|
||||
queryFmtDeleteWebauthnDeviceByUsername = `
|
||||
DELETE FROM %s
|
||||
WHERE username = ?;`
|
||||
|
||||
queryFmtDeleteWebauthnDeviceByUsernameAndDescription = `
|
||||
DELETE FROM %s
|
||||
WHERE username = ? AND description = ?;`
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -232,7 +244,7 @@ const (
|
|||
SELECT id, challenge_id, client_id, subject, authorized, granted, requested_at, responded_at, expires_at,
|
||||
form_data, requested_scopes, granted_scopes, requested_audience, granted_audience
|
||||
FROM %s
|
||||
WHERE client_id = ? AND subject = ? AND
|
||||
WHERE client_id = ? AND subject = ? AND
|
||||
authorized = TRUE AND granted = TRUE AND expires_at IS NOT NULL AND expires_at >= CURRENT_TIMESTAMP;`
|
||||
|
||||
queryFmtInsertOAuth2ConsentSession = `
|
||||
|
@ -263,8 +275,8 @@ const (
|
|||
WHERE signature = ? AND revoked = FALSE;`
|
||||
|
||||
queryFmtInsertOAuth2Session = `
|
||||
INSERT INTO %s (challenge_id, request_id, client_id, signature, subject, requested_at,
|
||||
requested_scopes, granted_scopes, requested_audience, granted_audience,
|
||||
INSERT INTO %s (challenge_id, request_id, client_id, signature, subject, requested_at,
|
||||
requested_scopes, granted_scopes, requested_audience, granted_audience,
|
||||
active, revoked, form_data, session_data)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`
|
||||
|
||||
|
|
Loading…
Reference in New Issue