From d7ab3bb6333af2c7bede8c10b99b216bbe215d07 Mon Sep 17 00:00:00 2001 From: James Elliott Date: Fri, 23 Dec 2022 15:00:23 +1100 Subject: [PATCH] feat(commands): storage import/export commands (#4545) This adds commands to export and import TOTP configurations and Webauthn devices as YAML. --- .../time-based-one-time-password.md | 19 +- .../en/reference/cli/authelia/authelia.md | 4 +- .../cli/authelia/authelia_access-control.md | 4 +- .../authelia_access-control_check-policy.md | 4 +- .../cli/authelia/authelia_build-info.md | 4 +- .../reference/cli/authelia/authelia_crypto.md | 4 +- .../authelia/authelia_crypto_certificate.md | 4 +- .../authelia_crypto_certificate_ecdsa.md | 4 +- ...helia_crypto_certificate_ecdsa_generate.md | 4 +- ...thelia_crypto_certificate_ecdsa_request.md | 4 +- .../authelia_crypto_certificate_ed25519.md | 4 +- ...lia_crypto_certificate_ed25519_generate.md | 4 +- ...elia_crypto_certificate_ed25519_request.md | 4 +- .../authelia_crypto_certificate_rsa.md | 4 +- ...uthelia_crypto_certificate_rsa_generate.md | 4 +- ...authelia_crypto_certificate_rsa_request.md | 4 +- .../cli/authelia/authelia_crypto_hash.md | 4 +- .../authelia/authelia_crypto_hash_generate.md | 4 +- .../authelia_crypto_hash_generate_argon2.md | 4 +- .../authelia_crypto_hash_generate_bcrypt.md | 4 +- .../authelia_crypto_hash_generate_pbkdf2.md | 4 +- .../authelia_crypto_hash_generate_scrypt.md | 4 +- ...authelia_crypto_hash_generate_sha2crypt.md | 4 +- .../authelia/authelia_crypto_hash_validate.md | 4 +- .../cli/authelia/authelia_crypto_pair.md | 4 +- .../authelia/authelia_crypto_pair_ecdsa.md | 4 +- .../authelia_crypto_pair_ecdsa_generate.md | 4 +- .../authelia/authelia_crypto_pair_ed25519.md | 4 +- .../authelia_crypto_pair_ed25519_generate.md | 4 +- .../cli/authelia/authelia_crypto_pair_rsa.md | 4 +- .../authelia_crypto_pair_rsa_generate.md | 4 +- .../cli/authelia/authelia_crypto_rand.md | 4 +- .../cli/authelia/authelia_storage.md | 4 +- .../authelia/authelia_storage_encryption.md | 4 +- .../authelia_storage_encryption_change-key.md | 4 +- .../authelia_storage_encryption_check.md | 4 +- .../cli/authelia/authelia_storage_migrate.md | 4 +- .../authelia/authelia_storage_migrate_down.md | 4 +- .../authelia_storage_migrate_history.md | 4 +- .../authelia_storage_migrate_list-down.md | 4 +- .../authelia_storage_migrate_list-up.md | 4 +- .../authelia/authelia_storage_migrate_up.md | 4 +- .../authelia/authelia_storage_schema-info.md | 4 +- .../cli/authelia/authelia_storage_user.md | 4 +- .../authelia_storage_user_identifiers.md | 4 +- .../authelia_storage_user_identifiers_add.md | 4 +- ...uthelia_storage_user_identifiers_export.md | 6 +- ...helia_storage_user_identifiers_generate.md | 4 +- ...uthelia_storage_user_identifiers_import.md | 15 +- .../authelia/authelia_storage_user_totp.md | 5 +- .../authelia_storage_user_totp_delete.md | 4 +- .../authelia_storage_user_totp_export.md | 21 +- .../authelia_storage_user_totp_export_csv.md | 71 ++ .../authelia_storage_user_totp_export_png.md | 72 ++ .../authelia_storage_user_totp_export_uri.md | 70 ++ .../authelia_storage_user_totp_generate.md | 4 +- .../authelia_storage_user_totp_import.md | 70 ++ .../authelia_storage_user_webauthn.md | 10 +- .../authelia_storage_user_webauthn_delete.md | 10 +- .../authelia_storage_user_webauthn_export.md | 72 ++ .../authelia_storage_user_webauthn_import.md | 71 ++ .../authelia_storage_user_webauthn_list.md | 10 +- .../cli/authelia/authelia_validate-config.md | 4 +- internal/commands/const.go | 114 +- internal/commands/context.go | 21 +- internal/commands/crypto_hash.go | 8 +- internal/commands/storage.go | 188 ++- internal/commands/storage_run.go | 1116 +++++++++++------ internal/commands/util.go | 31 - internal/model/totp_configuration.go | 61 + internal/model/user_opaque_identifier.go | 2 +- internal/model/webauthn.go | 111 +- internal/suites/suite_cli_test.go | 65 +- 73 files changed, 1762 insertions(+), 673 deletions(-) create mode 100644 docs/content/en/reference/cli/authelia/authelia_storage_user_totp_export_csv.md create mode 100644 docs/content/en/reference/cli/authelia/authelia_storage_user_totp_export_png.md create mode 100644 docs/content/en/reference/cli/authelia/authelia_storage_user_totp_export_uri.md create mode 100644 docs/content/en/reference/cli/authelia/authelia_storage_user_totp_import.md create mode 100644 docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn_export.md create mode 100644 docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn_import.md diff --git a/docs/content/en/configuration/second-factor/time-based-one-time-password.md b/docs/content/en/configuration/second-factor/time-based-one-time-password.md index a7b64a3c6..0783aa149 100644 --- a/docs/content/en/configuration/second-factor/time-based-one-time-password.md +++ b/docs/content/en/configuration/second-factor/time-based-one-time-password.md @@ -169,23 +169,8 @@ This may be inconvenient for some users who wish to export TOTP keys from Authel a command specifically for exporting TOTP configurations from the database. These commands require the configuration or at least a minimal configuration that has the storage backend connection details and the encryption key. -Export in [Key URI Format](https://github.com/google/google-authenticator/wiki/Key-Uri-Format): - -```bash -authelia storage user totp export --format uri -``` - -Export as CSV: - -```bash -authelia storage user totp export --format csv -``` - -Help: - -```bash -authelia storage user totp export --help -``` +See the [CLI Documentation](../../reference/cli/authelia/authelia_storage_user_totp_export.md) for methods to perform +exports. [RFC4226]: https://www.rfc-editor.org/rfc/rfc4226.html [RFC6238]: https://www.rfc-editor.org/rfc/rfc6238.html diff --git a/docs/content/en/reference/cli/authelia/authelia.md b/docs/content/en/reference/cli/authelia/authelia.md index e4c81e9e3..c8df14ea8 100644 --- a/docs/content/en/reference/cli/authelia/authelia.md +++ b/docs/content/en/reference/cli/authelia/authelia.md @@ -42,8 +42,8 @@ authelia --config /etc/authelia/config/ ### Options ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' -h, --help help for authelia ``` diff --git a/docs/content/en/reference/cli/authelia/authelia_access-control.md b/docs/content/en/reference/cli/authelia/authelia_access-control.md index 0755b06a5..c622e04e4 100644 --- a/docs/content/en/reference/cli/authelia/authelia_access-control.md +++ b/docs/content/en/reference/cli/authelia/authelia_access-control.md @@ -35,8 +35,8 @@ authelia access-control --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_access-control_check-policy.md b/docs/content/en/reference/cli/authelia/authelia_access-control_check-policy.md index 37de027c2..5ba1eec21 100644 --- a/docs/content/en/reference/cli/authelia/authelia_access-control_check-policy.md +++ b/docs/content/en/reference/cli/authelia/authelia_access-control_check-policy.md @@ -65,8 +65,8 @@ authelia access-control check-policy --config config.yml --url https://example.c ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_build-info.md b/docs/content/en/reference/cli/authelia/authelia_build-info.md index f08113650..0d1060ed8 100644 --- a/docs/content/en/reference/cli/authelia/authelia_build-info.md +++ b/docs/content/en/reference/cli/authelia/authelia_build-info.md @@ -48,8 +48,8 @@ authelia build-info ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto.md b/docs/content/en/reference/cli/authelia/authelia_crypto.md index 7f1ccc86e..a89a1fe6e 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto.md @@ -37,8 +37,8 @@ authelia crypto --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate.md b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate.md index f275803fe..33ddd6d39 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate.md @@ -37,8 +37,8 @@ authelia crypto certificate --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa.md b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa.md index 7be5c794a..8f244b1b9 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa.md @@ -37,8 +37,8 @@ authelia crypto certificate ecdsa --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa_generate.md b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa_generate.md index e5215fa5e..13fc82481 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa_generate.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa_generate.md @@ -62,8 +62,8 @@ authelia crypto certificate ecdsa generate --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa_request.md b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa_request.md index cd813689c..271da38eb 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa_request.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa_request.md @@ -57,8 +57,8 @@ authelia crypto certificate ecdsa request --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519.md b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519.md index 1a7877fca..f3b6354a6 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519.md @@ -37,8 +37,8 @@ authelia crypto certificate ed25519 --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519_generate.md b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519_generate.md index cd59da864..44e806357 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519_generate.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519_generate.md @@ -61,8 +61,8 @@ authelia crypto certificate ed25519 request --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519_request.md b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519_request.md index a609b4332..f0f3a5f8d 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519_request.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519_request.md @@ -56,8 +56,8 @@ authelia crypto certificate ed25519 request --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa.md b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa.md index 947ea4a10..4f38b2e80 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa.md @@ -37,8 +37,8 @@ authelia crypto certificate rsa --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa_generate.md b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa_generate.md index a1df7967d..e00aaf877 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa_generate.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa_generate.md @@ -62,8 +62,8 @@ authelia crypto certificate rsa generate --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa_request.md b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa_request.md index b3dd7cfb8..544cbf553 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa_request.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa_request.md @@ -57,8 +57,8 @@ authelia crypto certificate rsa request --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_hash.md b/docs/content/en/reference/cli/authelia/authelia_crypto_hash.md index 2d8d678a4..bb48ad3eb 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_hash.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_hash.md @@ -37,8 +37,8 @@ authelia crypto hash --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate.md b/docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate.md index 85a907ac7..0b06ebfe1 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate.md @@ -49,8 +49,8 @@ authelia crypto hash generate --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_argon2.md b/docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_argon2.md index a25abbbb3..d6e1efa49 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_argon2.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_argon2.md @@ -48,8 +48,8 @@ authelia crypto hash generate argon2 --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --no-confirm skip the password confirmation prompt --password string manually supply the password rather than using the terminal prompt --random uses a randomly generated password diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_bcrypt.md b/docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_bcrypt.md index 39d1a73fa..d33a72c6c 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_bcrypt.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_bcrypt.md @@ -43,8 +43,8 @@ authelia crypto hash generate bcrypt --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --no-confirm skip the password confirmation prompt --password string manually supply the password rather than using the terminal prompt --random uses a randomly generated password diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_pbkdf2.md b/docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_pbkdf2.md index 4acd6f3af..708a47df1 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_pbkdf2.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_pbkdf2.md @@ -44,8 +44,8 @@ authelia crypto hash generate pbkdf2 --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --no-confirm skip the password confirmation prompt --password string manually supply the password rather than using the terminal prompt --random uses a randomly generated password diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_scrypt.md b/docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_scrypt.md index dbb874d4a..dd172260d 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_scrypt.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_scrypt.md @@ -46,8 +46,8 @@ authelia crypto hash generate scrypt --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --no-confirm skip the password confirmation prompt --password string manually supply the password rather than using the terminal prompt --random uses a randomly generated password diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_sha2crypt.md b/docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_sha2crypt.md index 567a9ec3c..e0cbd7412 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_sha2crypt.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_sha2crypt.md @@ -44,8 +44,8 @@ authelia crypto hash generate sha2crypt --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --no-confirm skip the password confirmation prompt --password string manually supply the password rather than using the terminal prompt --random uses a randomly generated password diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_hash_validate.md b/docs/content/en/reference/cli/authelia/authelia_crypto_hash_validate.md index 66fdfb104..16d53f8f8 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_hash_validate.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_hash_validate.md @@ -43,8 +43,8 @@ authelia crypto hash validate '$5$rounds=500000$WFjMpdCQxIkbNl0k$M0qZaZoK8Gwdh8C ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_pair.md b/docs/content/en/reference/cli/authelia/authelia_crypto_pair.md index c906cb517..5d9d3c57a 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_pair.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_pair.md @@ -37,8 +37,8 @@ authelia crypto pair --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_pair_ecdsa.md b/docs/content/en/reference/cli/authelia/authelia_crypto_pair_ecdsa.md index 4300c395c..1a2a51194 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_pair_ecdsa.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_pair_ecdsa.md @@ -41,8 +41,8 @@ authelia crypto pair ecdsa --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_pair_ecdsa_generate.md b/docs/content/en/reference/cli/authelia/authelia_crypto_pair_ecdsa_generate.md index 0e0703182..5051e957c 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_pair_ecdsa_generate.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_pair_ecdsa_generate.md @@ -46,8 +46,8 @@ authelia crypto pair ecdsa generate --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_pair_ed25519.md b/docs/content/en/reference/cli/authelia/authelia_crypto_pair_ed25519.md index 77070c5b0..2f930e3f7 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_pair_ed25519.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_pair_ed25519.md @@ -41,8 +41,8 @@ authelia crypto pair ed25519 --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_pair_ed25519_generate.md b/docs/content/en/reference/cli/authelia/authelia_crypto_pair_ed25519_generate.md index f730e25c4..f8f193683 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_pair_ed25519_generate.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_pair_ed25519_generate.md @@ -45,8 +45,8 @@ authelia crypto pair ed25519 generate --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_pair_rsa.md b/docs/content/en/reference/cli/authelia/authelia_crypto_pair_rsa.md index 4a760de6e..a04fb46c4 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_pair_rsa.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_pair_rsa.md @@ -41,8 +41,8 @@ authelia crypto pair rsa --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_pair_rsa_generate.md b/docs/content/en/reference/cli/authelia/authelia_crypto_pair_rsa_generate.md index bf4f530ef..cc13a85b9 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_pair_rsa_generate.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_pair_rsa_generate.md @@ -46,8 +46,8 @@ authelia crypto pair rsa generate --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_rand.md b/docs/content/en/reference/cli/authelia/authelia_crypto_rand.md index 5c5ff7b80..98331df88 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_rand.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_rand.md @@ -52,8 +52,8 @@ authelia crypto rand --characters 0123456789ABCDEF ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_storage.md b/docs/content/en/reference/cli/authelia/authelia_storage.md index d1cdc0b42..bb3281d5b 100644 --- a/docs/content/en/reference/cli/authelia/authelia_storage.md +++ b/docs/content/en/reference/cli/authelia/authelia_storage.md @@ -56,8 +56,8 @@ authelia storage --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_encryption.md b/docs/content/en/reference/cli/authelia/authelia_storage_encryption.md index 17905e448..062570360 100644 --- a/docs/content/en/reference/cli/authelia/authelia_storage_encryption.md +++ b/docs/content/en/reference/cli/authelia/authelia_storage_encryption.md @@ -37,8 +37,8 @@ authelia storage encryption --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --encryption-key string the storage encryption key to use --mysql.database string the MySQL database name (default "authelia") --mysql.host string the MySQL hostname diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_encryption_change-key.md b/docs/content/en/reference/cli/authelia/authelia_storage_encryption_change-key.md index 77a2c5393..6bfe33d7f 100644 --- a/docs/content/en/reference/cli/authelia/authelia_storage_encryption_change-key.md +++ b/docs/content/en/reference/cli/authelia/authelia_storage_encryption_change-key.md @@ -43,8 +43,8 @@ authelia storage encryption change-key --encryption-key b3453fde-ecc2-4a1f-9422- ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --encryption-key string the storage encryption key to use --mysql.database string the MySQL database name (default "authelia") --mysql.host string the MySQL hostname diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_encryption_check.md b/docs/content/en/reference/cli/authelia/authelia_storage_encryption_check.md index 6d8368d05..b22d5b959 100644 --- a/docs/content/en/reference/cli/authelia/authelia_storage_encryption_check.md +++ b/docs/content/en/reference/cli/authelia/authelia_storage_encryption_check.md @@ -45,8 +45,8 @@ authelia storage encryption check --verbose --encryption-key b3453fde-ecc2-4a1f- ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --encryption-key string the storage encryption key to use --mysql.database string the MySQL database name (default "authelia") --mysql.host string the MySQL hostname diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_migrate.md b/docs/content/en/reference/cli/authelia/authelia_storage_migrate.md index a80eaa8a0..d5f262cb6 100644 --- a/docs/content/en/reference/cli/authelia/authelia_storage_migrate.md +++ b/docs/content/en/reference/cli/authelia/authelia_storage_migrate.md @@ -37,8 +37,8 @@ authelia storage migrate --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --encryption-key string the storage encryption key to use --mysql.database string the MySQL database name (default "authelia") --mysql.host string the MySQL hostname diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_migrate_down.md b/docs/content/en/reference/cli/authelia/authelia_storage_migrate_down.md index 5ef59efa3..bf1379897 100644 --- a/docs/content/en/reference/cli/authelia/authelia_storage_migrate_down.md +++ b/docs/content/en/reference/cli/authelia/authelia_storage_migrate_down.md @@ -46,8 +46,8 @@ authelia storage migrate down --target 20 --encryption-key b3453fde-ecc2-4a1f-94 ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --encryption-key string the storage encryption key to use --mysql.database string the MySQL database name (default "authelia") --mysql.host string the MySQL hostname diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_migrate_history.md b/docs/content/en/reference/cli/authelia/authelia_storage_migrate_history.md index a3afa9f95..3762e80e0 100644 --- a/docs/content/en/reference/cli/authelia/authelia_storage_migrate_history.md +++ b/docs/content/en/reference/cli/authelia/authelia_storage_migrate_history.md @@ -43,8 +43,8 @@ authelia storage migrate history --encryption-key b3453fde-ecc2-4a1f-9422-2707dd ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --encryption-key string the storage encryption key to use --mysql.database string the MySQL database name (default "authelia") --mysql.host string the MySQL hostname diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_migrate_list-down.md b/docs/content/en/reference/cli/authelia/authelia_storage_migrate_list-down.md index 6ea42249e..c62a7e3e7 100644 --- a/docs/content/en/reference/cli/authelia/authelia_storage_migrate_list-down.md +++ b/docs/content/en/reference/cli/authelia/authelia_storage_migrate_list-down.md @@ -44,8 +44,8 @@ authelia storage migrate list-down --encryption-key b3453fde-ecc2-4a1f-9422-2707 ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --encryption-key string the storage encryption key to use --mysql.database string the MySQL database name (default "authelia") --mysql.host string the MySQL hostname diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_migrate_list-up.md b/docs/content/en/reference/cli/authelia/authelia_storage_migrate_list-up.md index eacaf8129..187dbedf1 100644 --- a/docs/content/en/reference/cli/authelia/authelia_storage_migrate_list-up.md +++ b/docs/content/en/reference/cli/authelia/authelia_storage_migrate_list-up.md @@ -44,8 +44,8 @@ authelia storage migrate list-up --encryption-key b3453fde-ecc2-4a1f-9422-2707dd ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --encryption-key string the storage encryption key to use --mysql.database string the MySQL database name (default "authelia") --mysql.host string the MySQL hostname diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_migrate_up.md b/docs/content/en/reference/cli/authelia/authelia_storage_migrate_up.md index 576d8a31d..d84930536 100644 --- a/docs/content/en/reference/cli/authelia/authelia_storage_migrate_up.md +++ b/docs/content/en/reference/cli/authelia/authelia_storage_migrate_up.md @@ -46,8 +46,8 @@ authelia storage migrate up --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed49 ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --encryption-key string the storage encryption key to use --mysql.database string the MySQL database name (default "authelia") --mysql.host string the MySQL hostname diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_schema-info.md b/docs/content/en/reference/cli/authelia/authelia_storage_schema-info.md index 2a4cd758b..ebecef02e 100644 --- a/docs/content/en/reference/cli/authelia/authelia_storage_schema-info.md +++ b/docs/content/en/reference/cli/authelia/authelia_storage_schema-info.md @@ -43,8 +43,8 @@ authelia storage schema-info --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed4 ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --encryption-key string the storage encryption key to use --mysql.database string the MySQL database name (default "authelia") --mysql.host string the MySQL hostname diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_user.md b/docs/content/en/reference/cli/authelia/authelia_storage_user.md index 3a83e66d9..f179c61cd 100644 --- a/docs/content/en/reference/cli/authelia/authelia_storage_user.md +++ b/docs/content/en/reference/cli/authelia/authelia_storage_user.md @@ -37,8 +37,8 @@ authelia storage user --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --encryption-key string the storage encryption key to use --mysql.database string the MySQL database name (default "authelia") --mysql.host string the MySQL hostname diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers.md b/docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers.md index 881667c15..f7ec634ef 100644 --- a/docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers.md +++ b/docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers.md @@ -37,8 +37,8 @@ authelia storage user identifiers --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --encryption-key string the storage encryption key to use --mysql.database string the MySQL database name (default "authelia") --mysql.host string the MySQL hostname diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers_add.md b/docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers_add.md index 3ea068d66..ff790e6c1 100644 --- a/docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers_add.md +++ b/docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers_add.md @@ -46,8 +46,8 @@ authelia storage user identifiers add john --identifier f0919359-9d15-4e15-bcba- ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --encryption-key string the storage encryption key to use --mysql.database string the MySQL database name (default "authelia") --mysql.host string the MySQL hostname diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers_export.md b/docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers_export.md index ea842f8fe..6dd117ca6 100644 --- a/docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers_export.md +++ b/docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers_export.md @@ -38,15 +38,15 @@ authelia storage user identifiers export --file export.yaml --encryption-key b34 ### Options ``` - -f, --file string The file name for the YAML export (default "user-opaque-identifiers.yml") + -f, --file string The file name for the YAML export (default "authelia.export.opaque-identifiers.yml") -h, --help help for export ``` ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --encryption-key string the storage encryption key to use --mysql.database string the MySQL database name (default "authelia") --mysql.host string the MySQL hostname diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers_generate.md b/docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers_generate.md index 29cd6befc..537408c65 100644 --- a/docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers_generate.md +++ b/docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers_generate.md @@ -48,8 +48,8 @@ authelia storage user identifiers generate --users john,mary --services openid - ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --encryption-key string the storage encryption key to use --mysql.database string the MySQL database name (default "authelia") --mysql.host string the MySQL hostname diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers_import.md b/docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers_import.md index 0b4b6ca2a..7993d2a82 100644 --- a/docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers_import.md +++ b/docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers_import.md @@ -26,30 +26,29 @@ The YAML file can either be automatically generated using the authelia storage u manually provided the file is in the same format. ``` -authelia storage user identifiers import [flags] +authelia storage user identifiers import [flags] ``` ### Examples ``` authelia storage user identifiers import -authelia storage user identifiers import --file export.yaml -authelia storage user identifiers import --file export.yaml --config config.yml -authelia storage user identifiers import --file export.yaml --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw +authelia storage user identifiers import authelia.export.opaque-identifiers.yaml +authelia storage user identifiers import --config config.yml export.yaml +authelia storage user identifiers import --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw export.yaml ``` ### Options ``` - -f, --file string The file name for the YAML import (default "user-opaque-identifiers.yml") - -h, --help help for import + -h, --help help for import ``` ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --encryption-key string the storage encryption key to use --mysql.database string the MySQL database name (default "authelia") --mysql.host string the MySQL hostname diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_user_totp.md b/docs/content/en/reference/cli/authelia/authelia_storage_user_totp.md index 4319cb526..77e63483a 100644 --- a/docs/content/en/reference/cli/authelia/authelia_storage_user_totp.md +++ b/docs/content/en/reference/cli/authelia/authelia_storage_user_totp.md @@ -37,8 +37,8 @@ authelia storage user totp --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --encryption-key string the storage encryption key to use --mysql.database string the MySQL database name (default "authelia") --mysql.host string the MySQL hostname @@ -64,4 +64,5 @@ authelia storage user totp --help * [authelia storage user totp delete](authelia_storage_user_totp_delete.md) - Delete a TOTP configuration for a user * [authelia storage user totp export](authelia_storage_user_totp_export.md) - Perform exports of the TOTP configurations * [authelia storage user totp generate](authelia_storage_user_totp_generate.md) - Generate a TOTP configuration for a user +* [authelia storage user totp import](authelia_storage_user_totp_import.md) - Perform imports of the TOTP configurations diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_user_totp_delete.md b/docs/content/en/reference/cli/authelia/authelia_storage_user_totp_delete.md index 8db359769..e4b637228 100644 --- a/docs/content/en/reference/cli/authelia/authelia_storage_user_totp_delete.md +++ b/docs/content/en/reference/cli/authelia/authelia_storage_user_totp_delete.md @@ -43,8 +43,8 @@ authelia storage user totp delete john --encryption-key b3453fde-ecc2-4a1f-9422- ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --encryption-key string the storage encryption key to use --mysql.database string the MySQL database name (default "authelia") --mysql.host string the MySQL hostname diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_user_totp_export.md b/docs/content/en/reference/cli/authelia/authelia_storage_user_totp_export.md index 1986a771a..be40488ce 100644 --- a/docs/content/en/reference/cli/authelia/authelia_storage_user_totp_export.md +++ b/docs/content/en/reference/cli/authelia/authelia_storage_user_totp_export.md @@ -20,7 +20,7 @@ Perform exports of the TOTP configurations Perform exports of the TOTP configurations. -This subcommand allows exporting TOTP configurations to various formats. +This subcommand allows exporting TOTP configurations to importable YAML files, or use the subcommands to export them to other non-importable formats. ``` authelia storage user totp export [flags] @@ -29,25 +29,23 @@ authelia storage user totp export [flags] ### Examples ``` -authelia storage user totp export --format csv -authelia storage user totp export --format png --dir ./totp-qr -authelia storage user totp export --format png --dir ./totp-qr --config config.yml -authelia storage user totp export --format png --dir ./totp-qr --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw +authelia storage user totp export --file example.yaml +authelia storage user totp export --config config.yml +authelia storage user totp export --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw ``` ### Options ``` - --dir string used with the png output format to specify which new directory to save the files in - --format string sets the output format, valid values are: csv, uri, png (default "uri") - -h, --help help for export + -f, --file string The file name for the YAML export (default "authelia.export.totp.yaml") + -h, --help help for export ``` ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --encryption-key string the storage encryption key to use --mysql.database string the MySQL database name (default "authelia") --mysql.host string the MySQL hostname @@ -70,4 +68,7 @@ authelia storage user totp export --format png --dir ./totp-qr --encryption-key ### SEE ALSO * [authelia storage user totp](authelia_storage_user_totp.md) - Manage TOTP configurations +* [authelia storage user totp export csv](authelia_storage_user_totp_export_csv.md) - Perform exports of the TOTP configurations to a CSV +* [authelia storage user totp export png](authelia_storage_user_totp_export_png.md) - Perform exports of the TOTP configurations to QR code PNG images +* [authelia storage user totp export uri](authelia_storage_user_totp_export_uri.md) - Perform exports of the TOTP configurations to URIs diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_user_totp_export_csv.md b/docs/content/en/reference/cli/authelia/authelia_storage_user_totp_export_csv.md new file mode 100644 index 000000000..bb80740ac --- /dev/null +++ b/docs/content/en/reference/cli/authelia/authelia_storage_user_totp_export_csv.md @@ -0,0 +1,71 @@ +--- +title: "authelia storage user totp export csv" +description: "Reference for the authelia storage user totp export csv command." +lead: "" +date: 2022-06-15T17:51:47+10:00 +draft: false +images: [] +menu: + reference: + parent: "cli-authelia" +weight: 905 +toc: true +--- + +## authelia storage user totp export csv + +Perform exports of the TOTP configurations to a CSV + +### Synopsis + +Perform exports of the TOTP configurations to a CSV. + +This subcommand allows exporting TOTP configurations to a CSV. + +``` +authelia storage user totp export csv [flags] +``` + +### Examples + +``` +authelia storage user totp export csv --file users.csv +authelia storage user totp export csv --config config.yml +authelia storage user totp export csv --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw +``` + +### Options + +``` + -f, --file string The file name for the CSV export (default "authelia.export.totp.csv") + -h, --help help for csv +``` + +### Options inherited from parent commands + +``` + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' + --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 totp export](authelia_storage_user_totp_export.md) - Perform exports of the TOTP configurations + diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_user_totp_export_png.md b/docs/content/en/reference/cli/authelia/authelia_storage_user_totp_export_png.md new file mode 100644 index 000000000..4397dc959 --- /dev/null +++ b/docs/content/en/reference/cli/authelia/authelia_storage_user_totp_export_png.md @@ -0,0 +1,72 @@ +--- +title: "authelia storage user totp export png" +description: "Reference for the authelia storage user totp export png command." +lead: "" +date: 2022-06-15T17:51:47+10:00 +draft: false +images: [] +menu: + reference: + parent: "cli-authelia" +weight: 905 +toc: true +--- + +## authelia storage user totp export png + +Perform exports of the TOTP configurations to QR code PNG images + +### Synopsis + +Perform exports of the TOTP configurations to QR code PNG images. + +This subcommand allows exporting TOTP configurations to PNG images with QR codes which represent the appropriate URI so they can be scanned. + +``` +authelia storage user totp export png [flags] +``` + +### Examples + +``` +authelia storage user totp export png +authelia storage user totp export png --directory example/dir +authelia storage user totp export png --config config.yml +authelia storage user totp export png --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw +``` + +### Options + +``` + --directory string The directory where all exported png files will be saved to + -h, --help help for png +``` + +### Options inherited from parent commands + +``` + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' + --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 totp export](authelia_storage_user_totp_export.md) - Perform exports of the TOTP configurations + diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_user_totp_export_uri.md b/docs/content/en/reference/cli/authelia/authelia_storage_user_totp_export_uri.md new file mode 100644 index 000000000..640b65f9a --- /dev/null +++ b/docs/content/en/reference/cli/authelia/authelia_storage_user_totp_export_uri.md @@ -0,0 +1,70 @@ +--- +title: "authelia storage user totp export uri" +description: "Reference for the authelia storage user totp export uri command." +lead: "" +date: 2022-06-15T17:51:47+10:00 +draft: false +images: [] +menu: + reference: + parent: "cli-authelia" +weight: 905 +toc: true +--- + +## authelia storage user totp export uri + +Perform exports of the TOTP configurations to URIs + +### Synopsis + +Perform exports of the TOTP configurations to URIs. + +This subcommand allows exporting TOTP configurations to TOTP URIs. + +``` +authelia storage user totp export uri [flags] +``` + +### Examples + +``` +authelia storage user totp export uri +authelia storage user totp export uri --config config.yml +authelia storage user totp export uri --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw +``` + +### Options + +``` + -h, --help help for uri +``` + +### Options inherited from parent commands + +``` + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' + --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 totp export](authelia_storage_user_totp_export.md) - Perform exports of the TOTP configurations + diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_user_totp_generate.md b/docs/content/en/reference/cli/authelia/authelia_storage_user_totp_generate.md index a5a3b150d..01de06534 100644 --- a/docs/content/en/reference/cli/authelia/authelia_storage_user_totp_generate.md +++ b/docs/content/en/reference/cli/authelia/authelia_storage_user_totp_generate.md @@ -55,8 +55,8 @@ authelia storage user totp generate john --algorithm SHA512 --config config.yml ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --encryption-key string the storage encryption key to use --mysql.database string the MySQL database name (default "authelia") --mysql.host string the MySQL hostname diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_user_totp_import.md b/docs/content/en/reference/cli/authelia/authelia_storage_user_totp_import.md new file mode 100644 index 000000000..866c8c404 --- /dev/null +++ b/docs/content/en/reference/cli/authelia/authelia_storage_user_totp_import.md @@ -0,0 +1,70 @@ +--- +title: "authelia storage user totp import" +description: "Reference for the authelia storage user totp import command." +lead: "" +date: 2022-06-15T17:51:47+10:00 +draft: false +images: [] +menu: + reference: + parent: "cli-authelia" +weight: 905 +toc: true +--- + +## authelia storage user totp import + +Perform imports of the TOTP configurations + +### Synopsis + +Perform imports of the TOTP configurations. + +This subcommand allows importing TOTP configurations from various formats. + +``` +authelia storage user totp import [flags] +``` + +### Examples + +``` +authelia storage user totp import authelia.export.totp.yaml +authelia storage user totp import --config config.yml authelia.export.totp.yaml +authelia storage user totp import --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw authelia.export.totp.yaml +``` + +### Options + +``` + -h, --help help for import +``` + +### Options inherited from parent commands + +``` + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' + --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 totp](authelia_storage_user_totp.md) - Manage TOTP configurations + diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn.md b/docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn.md index e2fe634e1..5b08f4244 100644 --- a/docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn.md +++ b/docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn.md @@ -37,8 +37,8 @@ authelia storage user webauthn --help ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --encryption-key string the storage encryption key to use --mysql.database string the MySQL database name (default "authelia") --mysql.host string the MySQL hostname @@ -61,6 +61,8 @@ authelia storage user webauthn --help ### 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 +* [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 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 diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn_delete.md b/docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn_delete.md index 66dfadd1c..aec44c2bf 100644 --- a/docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn_delete.md +++ b/docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn_delete.md @@ -14,13 +14,13 @@ toc: true ## authelia storage user webauthn delete -Delete a WebAuthn device +Delete a Webauthn device ### 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] @@ -52,8 +52,8 @@ authelia storage user webauthn delete --kid abc123 --encryption-key b3453fde-ecc ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --encryption-key string the storage encryption key to use --mysql.database string the MySQL database name (default "authelia") --mysql.host string the MySQL hostname diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn_export.md b/docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn_export.md new file mode 100644 index 000000000..81406c3ba --- /dev/null +++ b/docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn_export.md @@ -0,0 +1,72 @@ +--- +title: "authelia storage user webauthn export" +description: "Reference for the authelia storage user webauthn export command." +lead: "" +date: 2022-06-15T17:51:47+10:00 +draft: false +images: [] +menu: + reference: + parent: "cli-authelia" +weight: 905 +toc: true +--- + +## authelia storage user webauthn export + +Perform exports of the Webauthn devices + +### Synopsis + +Perform exports of the Webauthn devices. + +This subcommand allows exporting Webauthn devices to various formats. + +``` +authelia storage user webauthn export [flags] +``` + +### Examples + +``` +authelia storage user webauthn export +authelia storage user webauthn export --file authelia.export.webauthn.yaml +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 +``` + +### Options + +``` + -f, --file string The file name for the YAML export (default "authelia.export.webauthn.yaml") + -h, --help help for export +``` + +### Options inherited from parent commands + +``` + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' + --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 + diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn_import.md b/docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn_import.md new file mode 100644 index 000000000..3e967809c --- /dev/null +++ b/docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn_import.md @@ -0,0 +1,71 @@ +--- +title: "authelia storage user webauthn import" +description: "Reference for the authelia storage user webauthn import command." +lead: "" +date: 2022-06-15T17:51:47+10:00 +draft: false +images: [] +menu: + reference: + parent: "cli-authelia" +weight: 905 +toc: true +--- + +## authelia storage user webauthn import + +Perform imports of the Webauthn devices + +### Synopsis + +Perform imports of the Webauthn devices. + +This subcommand allows importing Webauthn devices from various formats. + +``` +authelia storage user webauthn import [flags] +``` + +### Examples + +``` +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 --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 +``` + +### Options + +``` + -h, --help help for import +``` + +### Options inherited from parent commands + +``` + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' + --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 + diff --git a/docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn_list.md b/docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn_list.md index 6fc104b0f..9a1f569fa 100644 --- a/docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn_list.md +++ b/docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn_list.md @@ -14,13 +14,13 @@ toc: true ## authelia storage user webauthn list -List WebAuthn devices +List Webauthn devices ### 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] @@ -46,8 +46,8 @@ authelia storage user webauthn list john --encryption-key b3453fde-ecc2-4a1f-942 ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --encryption-key string the storage encryption key to use --mysql.database string the MySQL database name (default "authelia") --mysql.host string the MySQL hostname diff --git a/docs/content/en/reference/cli/authelia/authelia_validate-config.md b/docs/content/en/reference/cli/authelia/authelia_validate-config.md index 0ee461f98..0d7a586d8 100644 --- a/docs/content/en/reference/cli/authelia/authelia_validate-config.md +++ b/docs/content/en/reference/cli/authelia/authelia_validate-config.md @@ -43,8 +43,8 @@ authelia validate-config --config config.yml ### Options inherited from parent commands ``` - -c, --config strings configuration files or directories to load (default [configuration.yml]) - --config.experimental.filters strings list of filters to apply to all configuration files, for more information: authelia --help authelia filters + -c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) + --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' ``` ### SEE ALSO diff --git a/internal/commands/const.go b/internal/commands/const.go index 6a1512d48..bd60b22d4 100644 --- a/internal/commands/const.go +++ b/internal/commands/const.go @@ -151,9 +151,9 @@ The YAML file can either be automatically generated using the authelia storage u manually provided the file is in the same format.` cmdAutheliaStorageUserIdentifiersImportExample = `authelia storage user identifiers import -authelia storage user identifiers import --file export.yaml -authelia storage user identifiers import --file export.yaml --config config.yml -authelia storage user identifiers import --file export.yaml --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw` +authelia storage user identifiers import authelia.export.opaque-identifiers.yaml +authelia storage user identifiers import --config config.yml export.yaml +authelia storage user identifiers import --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw export.yaml` cmdAutheliaStorageUserIdentifiersGenerateShort = "Generate opaque identifiers in bulk" @@ -177,34 +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 --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.` - cmdAutheliaStorageUserWebAuthnExample = `authelia storage user webauthn --help` + cmdAutheliaStorageUserWebauthnExample = `authelia storage user webauthn --help` - cmdAutheliaStorageUserWebAuthnListShort = "List WebAuthn devices" + cmdAutheliaStorageUserWebauthnImportShort = "Perform imports of the Webauthn devices" - cmdAutheliaStorageUserWebAuthnListLong = `List WebAuthn devices. + cmdAutheliaStorageUserWebauthnImportLong = `Perform imports of the Webauthn devices. -This subcommand allows listing WebAuthn devices.` +This subcommand allows importing Webauthn devices from various formats.` - cmdAutheliaStorageUserWebAuthnListExample = `authelia storage user webauthn list + 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 --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` + + cmdAutheliaStorageUserWebauthnExportShort = "Perform exports of the Webauthn devices" + + cmdAutheliaStorageUserWebauthnExportLong = `Perform exports of the Webauthn devices. + +This subcommand allows exporting Webauthn devices to various formats.` + + cmdAutheliaStorageUserWebauthnExportExample = `authelia storage user webauthn export +authelia storage user webauthn export --file authelia.export.webauthn.yaml +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` + + 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" + 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 --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw authelia storage user webauthn delete john --description Primary @@ -246,16 +268,56 @@ This subcommand allows deleting a TOTP configuration directly from the database authelia storage user totp delete john --config config.yml authelia storage user totp delete john --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw` + cmdAutheliaStorageUserTOTPImportShort = "Perform imports of the TOTP configurations" + + cmdAutheliaStorageUserTOTPImportLong = `Perform imports of the TOTP configurations. + +This subcommand allows importing TOTP configurations from various formats.` + + cmdAutheliaStorageUserTOTPImportExample = `authelia storage user totp import authelia.export.totp.yaml +authelia storage user totp import --config config.yml authelia.export.totp.yaml +authelia storage user totp import --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw authelia.export.totp.yaml` + cmdAutheliaStorageUserTOTPExportShort = "Perform exports of the TOTP configurations" cmdAutheliaStorageUserTOTPExportLong = `Perform exports of the TOTP configurations. -This subcommand allows exporting TOTP configurations to various formats.` +This subcommand allows exporting TOTP configurations to importable YAML files, or use the subcommands to export them to other non-importable formats.` - cmdAutheliaStorageUserTOTPExportExample = `authelia storage user totp export --format csv -authelia storage user totp export --format png --dir ./totp-qr -authelia storage user totp export --format png --dir ./totp-qr --config config.yml -authelia storage user totp export --format png --dir ./totp-qr --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw` + cmdAutheliaStorageUserTOTPExportExample = `authelia storage user totp export --file example.yaml +authelia storage user totp export --config config.yml +authelia storage user totp export --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw` + + cmdAutheliaStorageUserTOTPExportCSVShort = "Perform exports of the TOTP configurations to a CSV" + + cmdAutheliaStorageUserTOTPExportCSVLong = `Perform exports of the TOTP configurations to a CSV. + +This subcommand allows exporting TOTP configurations to a CSV.` + + cmdAutheliaStorageUserTOTPExportCSVExample = `authelia storage user totp export csv --file users.csv +authelia storage user totp export csv --config config.yml +authelia storage user totp export csv --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw` + + cmdAutheliaStorageUserTOTPExportURIShort = "Perform exports of the TOTP configurations to URIs" + + cmdAutheliaStorageUserTOTPExportURILong = `Perform exports of the TOTP configurations to URIs. + +This subcommand allows exporting TOTP configurations to TOTP URIs.` + + cmdAutheliaStorageUserTOTPExportURIExample = `authelia storage user totp export uri +authelia storage user totp export uri --config config.yml +authelia storage user totp export uri --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw` + + cmdAutheliaStorageUserTOTPExportPNGShort = "Perform exports of the TOTP configurations to QR code PNG images" + + cmdAutheliaStorageUserTOTPExportPNGLong = `Perform exports of the TOTP configurations to QR code PNG images. + +This subcommand allows exporting TOTP configurations to PNG images with QR codes which represent the appropriate URI so they can be scanned.` + + cmdAutheliaStorageUserTOTPExportPNGExample = `authelia storage user totp export png +authelia storage user totp export png --directory example/dir +authelia storage user totp export png --config config.yml +authelia storage user totp export png --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw` cmdAutheliaStorageSchemaInfoShort = "Show the storage information" @@ -471,16 +533,6 @@ const ( storageMigrateDirectionDown = "down" ) -const ( - storageTOTPExportFormatCSV = "csv" - storageTOTPExportFormatURI = "uri" - storageTOTPExportFormatPNG = "png" -) - -var ( - validStorageTOTPExportFormats = []string{storageTOTPExportFormatCSV, storageTOTPExportFormatURI, storageTOTPExportFormatPNG} -) - const ( timeLayoutCertificateNotBefore = "Jan 2 15:04:05 2006" ) @@ -571,7 +623,6 @@ const ( cmdFlagNameAlgorithm = "algorithm" cmdFlagNameIssuer = "issuer" cmdFlagNameForce = "force" - cmdFlagNameFormat = "format" cmdFlagNamePath = "path" cmdFlagNameTarget = "target" cmdFlagNameDestroyData = "destroy-data" @@ -599,6 +650,9 @@ const ( cmdUseHashBCrypt = "bcrypt" cmdUseHashSCrypt = "scrypt" + cmdUseExport = "export" + cmdUseImportFileName = "import " + cmdUseCrypto = "crypto" cmdUseRand = "rand" cmdUseCertificate = "certificate" diff --git a/internal/commands/context.go b/internal/commands/context.go index edb79bc1e..ea3026759 100644 --- a/internal/commands/context.go +++ b/internal/commands/context.go @@ -24,6 +24,7 @@ import ( "github.com/authelia/authelia/v4/internal/oidc" "github.com/authelia/authelia/v4/internal/regulation" "github.com/authelia/authelia/v4/internal/session" + "github.com/authelia/authelia/v4/internal/storage" "github.com/authelia/authelia/v4/internal/templates" "github.com/authelia/authelia/v4/internal/totp" "github.com/authelia/authelia/v4/internal/utils" @@ -80,7 +81,6 @@ type CmdCtxConfig struct { // CobraRunECmd describes a function that can be used as a *cobra.Command RunE, PreRunE, or PostRunE. type CobraRunECmd func(cmd *cobra.Command, args []string) (err error) -// CheckSchemaVersion is a utility function which checks the schema version. func (ctx *CmdCtx) CheckSchemaVersion() (err error) { if ctx.providers.StorageProvider == nil { return fmt.Errorf("storage not loaded") @@ -106,6 +106,25 @@ func (ctx *CmdCtx) CheckSchemaVersion() (err error) { } } +// CheckSchema is a utility function which checks the schema version and encryption key. +func (ctx *CmdCtx) CheckSchema() (err error) { + if err = ctx.CheckSchemaVersion(); err != nil { + return err + } + + var result storage.EncryptionValidationResult + + if result, err = ctx.providers.StorageProvider.SchemaEncryptionCheckKey(ctx, false); !result.Checked() || !result.Success() { + if err != nil { + return fmt.Errorf("failed to check the schema encryption key: %w", err) + } + + return fmt.Errorf("failed to check the schema encryption key: the key is not valid for the schema") + } + + return nil +} + // LoadTrustedCertificates loads the trusted certificates into the CmdCtx. func (ctx *CmdCtx) LoadTrustedCertificates() (warns, errs []error) { ctx.trusted, warns, errs = utils.NewX509CertPool(ctx.config.CertificatesDirectory) diff --git a/internal/commands/crypto_hash.go b/internal/commands/crypto_hash.go index 3eb4fa374..7c85f3ef3 100644 --- a/internal/commands/crypto_hash.go +++ b/internal/commands/crypto_hash.go @@ -63,7 +63,7 @@ func newCryptoHashGenerateCmd(ctx *CmdCtx) (cmd *cobra.Command) { Example: cmdAutheliaCryptoHashGenerateExample, PreRunE: ctx.ChainRunE( ctx.ConfigSetDefaultsRunE(defaults), - ctx.CryptoHashGenerateMapFlagsPreRunE, + ctx.CryptoHashGenerateMapFlagsRunE, ctx.ConfigLoadRunE, ctx.ConfigValidateSectionPasswordRunE, ), @@ -116,7 +116,7 @@ func newCryptoHashGenerateSubCmd(ctx *CmdCtx, use string) (cmd *cobra.Command) { Args: cobra.NoArgs, PersistentPreRunE: ctx.ChainRunE( ctx.ConfigSetDefaultsRunE(defaults), - ctx.CryptoHashGenerateMapFlagsPreRunE, + ctx.CryptoHashGenerateMapFlagsRunE, ctx.ConfigLoadRunE, ctx.ConfigValidateSectionPasswordRunE, ), @@ -207,9 +207,9 @@ func (ctx *CmdCtx) CryptoHashValidateRunE(cmd *cobra.Command, args []string) (er return nil } -// CryptoHashGenerateMapFlagsPreRunE is the RunE which configures the flags map configuration source for the +// CryptoHashGenerateMapFlagsRunE is the RunE which configures the flags map configuration source for the // authelia crypto hash generate commands. -func (ctx *CmdCtx) CryptoHashGenerateMapFlagsPreRunE(cmd *cobra.Command, args []string) (err error) { +func (ctx *CmdCtx) CryptoHashGenerateMapFlagsRunE(cmd *cobra.Command, args []string) (err error) { var flagsMap map[string]string switch cmd.Use { diff --git a/internal/commands/storage.go b/internal/commands/storage.go index 8a7129b79..b201af5df 100644 --- a/internal/commands/storage.go +++ b/internal/commands/storage.go @@ -15,13 +15,13 @@ func newStorageCmd(ctx *CmdCtx) (cmd *cobra.Command) { Short: cmdAutheliaStorageShort, Long: cmdAutheliaStorageLong, Example: cmdAutheliaStorageExample, - Args: cobra.NoArgs, PersistentPreRunE: ctx.ChainRunE( - ctx.ConfigStorageCommandLineConfigPersistentPreRunE, + ctx.ConfigStorageCommandLineConfigRunE, ctx.ConfigLoadRunE, - ctx.ConfigValidateStoragePersistentPreRunE, + ctx.ConfigValidateStorageRunE, ctx.LoadProvidersStorageRunE, ), + Args: cobra.NoArgs, DisableAutoGenTag: true, } @@ -63,6 +63,7 @@ func newStorageEncryptionCmd(ctx *CmdCtx) (cmd *cobra.Command) { Short: cmdAutheliaStorageEncryptionShort, Long: cmdAutheliaStorageEncryptionLong, Example: cmdAutheliaStorageEncryptionExample, + Args: cobra.NoArgs, DisableAutoGenTag: true, } @@ -82,6 +83,7 @@ func newStorageEncryptionCheckCmd(ctx *CmdCtx) (cmd *cobra.Command) { Long: cmdAutheliaStorageEncryptionCheckLong, Example: cmdAutheliaStorageEncryptionCheckExample, RunE: ctx.StorageSchemaEncryptionCheckRunE, + Args: cobra.NoArgs, DisableAutoGenTag: true, } @@ -98,6 +100,7 @@ func newStorageEncryptionChangeKeyCmd(ctx *CmdCtx) (cmd *cobra.Command) { Long: cmdAutheliaStorageEncryptionChangeKeyLong, Example: cmdAutheliaStorageEncryptionChangeKeyExample, RunE: ctx.StorageSchemaEncryptionChangeKeyRunE, + Args: cobra.NoArgs, DisableAutoGenTag: true, } @@ -113,6 +116,7 @@ func newStorageUserCmd(ctx *CmdCtx) (cmd *cobra.Command) { Short: cmdAutheliaStorageUserShort, Long: cmdAutheliaStorageUserLong, Example: cmdAutheliaStorageUserExample, + Args: cobra.NoArgs, DisableAutoGenTag: true, } @@ -120,7 +124,7 @@ func newStorageUserCmd(ctx *CmdCtx) (cmd *cobra.Command) { cmd.AddCommand( newStorageUserIdentifiersCmd(ctx), newStorageUserTOTPCmd(ctx), - newStorageUserWebAuthnCmd(ctx), + newStorageUserWebauthnCmd(ctx), ) return cmd @@ -132,6 +136,7 @@ func newStorageUserIdentifiersCmd(ctx *CmdCtx) (cmd *cobra.Command) { Short: cmdAutheliaStorageUserIdentifiersShort, Long: cmdAutheliaStorageUserIdentifiersLong, Example: cmdAutheliaStorageUserIdentifiersExample, + Args: cobra.NoArgs, DisableAutoGenTag: true, } @@ -148,33 +153,33 @@ func newStorageUserIdentifiersCmd(ctx *CmdCtx) (cmd *cobra.Command) { func newStorageUserIdentifiersExportCmd(ctx *CmdCtx) (cmd *cobra.Command) { cmd = &cobra.Command{ - Use: "export", + Use: cmdUseExport, Short: cmdAutheliaStorageUserIdentifiersExportShort, Long: cmdAutheliaStorageUserIdentifiersExportLong, Example: cmdAutheliaStorageUserIdentifiersExportExample, RunE: ctx.StorageUserIdentifiersExportRunE, + Args: cobra.NoArgs, DisableAutoGenTag: true, } - cmd.Flags().StringP(cmdFlagNameFile, "f", "user-opaque-identifiers.yml", "The file name for the YAML export") + cmd.Flags().StringP(cmdFlagNameFile, "f", "authelia.export.opaque-identifiers.yml", "The file name for the YAML export") return cmd } func newStorageUserIdentifiersImportCmd(ctx *CmdCtx) (cmd *cobra.Command) { cmd = &cobra.Command{ - Use: "import", + Use: cmdUseImportFileName, Short: cmdAutheliaStorageUserIdentifiersImportShort, Long: cmdAutheliaStorageUserIdentifiersImportLong, Example: cmdAutheliaStorageUserIdentifiersImportExample, RunE: ctx.StorageUserIdentifiersImportRunE, + Args: cobra.ExactArgs(1), DisableAutoGenTag: true, } - cmd.Flags().StringP(cmdFlagNameFile, "f", "user-opaque-identifiers.yml", "The file name for the YAML import") - return cmd } @@ -185,6 +190,7 @@ func newStorageUserIdentifiersGenerateCmd(ctx *CmdCtx) (cmd *cobra.Command) { Long: cmdAutheliaStorageUserIdentifiersGenerateLong, Example: cmdAutheliaStorageUserIdentifiersGenerateExample, RunE: ctx.StorageUserIdentifiersGenerateRunE, + Args: cobra.NoArgs, DisableAutoGenTag: true, } @@ -202,8 +208,8 @@ func newStorageUserIdentifiersAddCmd(ctx *CmdCtx) (cmd *cobra.Command) { Short: cmdAutheliaStorageUserIdentifiersAddShort, Long: cmdAutheliaStorageUserIdentifiersAddLong, Example: cmdAutheliaStorageUserIdentifiersAddExample, - Args: cobra.ExactArgs(1), RunE: ctx.StorageUserIdentifiersAddRunE, + Args: cobra.ExactArgs(1), DisableAutoGenTag: true, } @@ -215,31 +221,66 @@ func newStorageUserIdentifiersAddCmd(ctx *CmdCtx) (cmd *cobra.Command) { return cmd } -func newStorageUserWebAuthnCmd(ctx *CmdCtx) (cmd *cobra.Command) { +func newStorageUserWebauthnCmd(ctx *CmdCtx) (cmd *cobra.Command) { cmd = &cobra.Command{ Use: "webauthn", - Short: cmdAutheliaStorageUserWebAuthnShort, - Long: cmdAutheliaStorageUserWebAuthnLong, - Example: cmdAutheliaStorageUserWebAuthnExample, + Short: cmdAutheliaStorageUserWebauthnShort, + Long: cmdAutheliaStorageUserWebauthnLong, + Example: cmdAutheliaStorageUserWebauthnExample, + Args: cobra.NoArgs, DisableAutoGenTag: true, } cmd.AddCommand( - newStorageUserWebAuthnListCmd(ctx), - newStorageUserWebAuthnDeleteCmd(ctx), + newStorageUserWebauthnListCmd(ctx), + newStorageUserWebauthnDeleteCmd(ctx), + newStorageUserWebauthnExportCmd(ctx), + newStorageUserWebauthnImportCmd(ctx), ) return cmd } -func newStorageUserWebAuthnListCmd(ctx *CmdCtx) (cmd *cobra.Command) { +func newStorageUserWebauthnImportCmd(ctx *CmdCtx) (cmd *cobra.Command) { + cmd = &cobra.Command{ + Use: cmdUseImportFileName, + Short: cmdAutheliaStorageUserWebauthnImportShort, + Long: cmdAutheliaStorageUserWebauthnImportLong, + Example: cmdAutheliaStorageUserWebauthnImportExample, + RunE: ctx.StorageUserWebauthnImportRunE, + Args: cobra.ExactArgs(1), + + DisableAutoGenTag: true, + } + + return cmd +} + +func newStorageUserWebauthnExportCmd(ctx *CmdCtx) (cmd *cobra.Command) { + cmd = &cobra.Command{ + Use: cmdUseExport, + Short: cmdAutheliaStorageUserWebauthnExportShort, + Long: cmdAutheliaStorageUserWebauthnExportLong, + Example: cmdAutheliaStorageUserWebauthnExportExample, + RunE: ctx.StorageUserWebauthnExportRunE, + Args: cobra.NoArgs, + + DisableAutoGenTag: true, + } + + cmd.Flags().StringP(cmdFlagNameFile, "f", "authelia.export.webauthn.yaml", "The file name for the YAML export") + + return cmd +} + +func newStorageUserWebauthnListCmd(ctx *CmdCtx) (cmd *cobra.Command) { cmd = &cobra.Command{ Use: "list [username]", - Short: cmdAutheliaStorageUserWebAuthnListShort, - Long: cmdAutheliaStorageUserWebAuthnListLong, - Example: cmdAutheliaStorageUserWebAuthnListExample, - RunE: ctx.StorageWebauthnListRunE, + Short: cmdAutheliaStorageUserWebauthnListShort, + Long: cmdAutheliaStorageUserWebauthnListLong, + Example: cmdAutheliaStorageUserWebauthnListExample, + RunE: ctx.StorageUserWebauthnListRunE, Args: cobra.MaximumNArgs(1), DisableAutoGenTag: true, @@ -248,13 +289,13 @@ func newStorageUserWebAuthnListCmd(ctx *CmdCtx) (cmd *cobra.Command) { return cmd } -func newStorageUserWebAuthnDeleteCmd(ctx *CmdCtx) (cmd *cobra.Command) { +func newStorageUserWebauthnDeleteCmd(ctx *CmdCtx) (cmd *cobra.Command) { cmd = &cobra.Command{ Use: "delete [username]", - Short: cmdAutheliaStorageUserWebAuthnDeleteShort, - Long: cmdAutheliaStorageUserWebAuthnDeleteLong, - Example: cmdAutheliaStorageUserWebAuthnDeleteExample, - RunE: ctx.StorageWebauthnDeleteRunE, + Short: cmdAutheliaStorageUserWebauthnDeleteShort, + Long: cmdAutheliaStorageUserWebauthnDeleteLong, + Example: cmdAutheliaStorageUserWebauthnDeleteExample, + RunE: ctx.StorageUserWebauthnDeleteRunE, Args: cobra.MaximumNArgs(1), DisableAutoGenTag: true, @@ -273,6 +314,7 @@ func newStorageUserTOTPCmd(ctx *CmdCtx) (cmd *cobra.Command) { Short: cmdAutheliaStorageUserTOTPShort, Long: cmdAutheliaStorageUserTOTPLong, Example: cmdAutheliaStorageUserTOTPExample, + Args: cobra.NoArgs, DisableAutoGenTag: true, } @@ -281,6 +323,7 @@ func newStorageUserTOTPCmd(ctx *CmdCtx) (cmd *cobra.Command) { newStorageUserTOTPGenerateCmd(ctx), newStorageUserTOTPDeleteCmd(ctx), newStorageUserTOTPExportCmd(ctx), + newStorageUserTOTPImportCmd(ctx), ) return cmd @@ -292,7 +335,7 @@ func newStorageUserTOTPGenerateCmd(ctx *CmdCtx) (cmd *cobra.Command) { Short: cmdAutheliaStorageUserTOTPGenerateShort, Long: cmdAutheliaStorageUserTOTPGenerateLong, Example: cmdAutheliaStorageUserTOTPGenerateExample, - RunE: ctx.StorageTOTPGenerateRunE, + RunE: ctx.StorageUserTOTPGenerateRunE, Args: cobra.ExactArgs(1), DisableAutoGenTag: true, @@ -316,7 +359,22 @@ func newStorageUserTOTPDeleteCmd(ctx *CmdCtx) (cmd *cobra.Command) { Short: cmdAutheliaStorageUserTOTPDeleteShort, Long: cmdAutheliaStorageUserTOTPDeleteLong, Example: cmdAutheliaStorageUserTOTPDeleteExample, - RunE: ctx.StorageTOTPDeleteRunE, + RunE: ctx.StorageUserTOTPDeleteRunE, + Args: cobra.ExactArgs(1), + + DisableAutoGenTag: true, + } + + return cmd +} + +func newStorageUserTOTPImportCmd(ctx *CmdCtx) (cmd *cobra.Command) { + cmd = &cobra.Command{ + Use: cmdUseImportFileName, + Short: cmdAutheliaStorageUserTOTPImportShort, + Long: cmdAutheliaStorageUserTOTPImportLong, + Example: cmdAutheliaStorageUserTOTPImportExample, + RunE: ctx.StorageUserTOTPImportRunE, Args: cobra.ExactArgs(1), DisableAutoGenTag: true, @@ -327,17 +385,72 @@ func newStorageUserTOTPDeleteCmd(ctx *CmdCtx) (cmd *cobra.Command) { func newStorageUserTOTPExportCmd(ctx *CmdCtx) (cmd *cobra.Command) { cmd = &cobra.Command{ - Use: "export", + Use: cmdUseExport, Short: cmdAutheliaStorageUserTOTPExportShort, Long: cmdAutheliaStorageUserTOTPExportLong, Example: cmdAutheliaStorageUserTOTPExportExample, - RunE: ctx.StorageTOTPExportRunE, + RunE: ctx.StorageUserTOTPExportRunE, + Args: cobra.NoArgs, DisableAutoGenTag: true, } - cmd.Flags().String(cmdFlagNameFormat, storageTOTPExportFormatURI, fmt.Sprintf("sets the output format, valid values are: %s", strings.Join(validStorageTOTPExportFormats, ", "))) - cmd.Flags().String("dir", "", "used with the png output format to specify which new directory to save the files in") + cmd.AddCommand( + newStorageUserTOTPExportCSVCmd(ctx), + newStorageUserTOTPExportPNGCmd(ctx), + newStorageUserTOTPExportURICmd(ctx), + ) + + cmd.Flags().StringP(cmdFlagNameFile, "f", "authelia.export.totp.yaml", "The file name for the YAML export") + + return cmd +} + +func newStorageUserTOTPExportURICmd(ctx *CmdCtx) (cmd *cobra.Command) { + cmd = &cobra.Command{ + Use: "uri", + Short: cmdAutheliaStorageUserTOTPExportURIShort, + Long: cmdAutheliaStorageUserTOTPExportURILong, + Example: cmdAutheliaStorageUserTOTPExportURIExample, + RunE: ctx.StorageUserTOTPExportURIRunE, + Args: cobra.NoArgs, + + DisableAutoGenTag: true, + } + + return cmd +} + +func newStorageUserTOTPExportCSVCmd(ctx *CmdCtx) (cmd *cobra.Command) { + cmd = &cobra.Command{ + Use: "csv", + Short: cmdAutheliaStorageUserTOTPExportCSVShort, + Long: cmdAutheliaStorageUserTOTPExportCSVLong, + Example: cmdAutheliaStorageUserTOTPExportCSVExample, + RunE: ctx.StorageUserTOTPExportCSVRunE, + Args: cobra.NoArgs, + + DisableAutoGenTag: true, + } + + cmd.Flags().StringP(cmdFlagNameFile, "f", "authelia.export.totp.csv", "The file name for the CSV export") + + return cmd +} + +func newStorageUserTOTPExportPNGCmd(ctx *CmdCtx) (cmd *cobra.Command) { + cmd = &cobra.Command{ + Use: "png", + Short: cmdAutheliaStorageUserTOTPExportPNGShort, + Long: cmdAutheliaStorageUserTOTPExportPNGLong, + Example: cmdAutheliaStorageUserTOTPExportPNGExample, + RunE: ctx.StorageUserTOTPExportPNGRunE, + Args: cobra.NoArgs, + + DisableAutoGenTag: true, + } + + cmd.Flags().String(cmdFlagNameDirectory, "", "The directory where all exported png files will be saved to") return cmd } @@ -349,6 +462,7 @@ func newStorageSchemaInfoCmd(ctx *CmdCtx) (cmd *cobra.Command) { Long: cmdAutheliaStorageSchemaInfoLong, Example: cmdAutheliaStorageSchemaInfoExample, RunE: ctx.StorageSchemaInfoRunE, + Args: cobra.NoArgs, DisableAutoGenTag: true, } @@ -383,8 +497,8 @@ func newStorageMigrateHistoryCmd(ctx *CmdCtx) (cmd *cobra.Command) { Short: cmdAutheliaStorageMigrateHistoryShort, Long: cmdAutheliaStorageMigrateHistoryLong, Example: cmdAutheliaStorageMigrateHistoryExample, - Args: cobra.NoArgs, RunE: ctx.StorageMigrateHistoryRunE, + Args: cobra.NoArgs, DisableAutoGenTag: true, } @@ -398,8 +512,8 @@ func newStorageMigrateListUpCmd(ctx *CmdCtx) (cmd *cobra.Command) { Short: cmdAutheliaStorageMigrateListUpShort, Long: cmdAutheliaStorageMigrateListUpLong, Example: cmdAutheliaStorageMigrateListUpExample, - Args: cobra.NoArgs, RunE: ctx.NewStorageMigrateListRunE(true), + Args: cobra.NoArgs, DisableAutoGenTag: true, } @@ -413,8 +527,8 @@ func newStorageMigrateListDownCmd(ctx *CmdCtx) (cmd *cobra.Command) { Short: cmdAutheliaStorageMigrateListDownShort, Long: cmdAutheliaStorageMigrateListDownLong, Example: cmdAutheliaStorageMigrateListDownExample, - Args: cobra.NoArgs, RunE: ctx.NewStorageMigrateListRunE(false), + Args: cobra.NoArgs, DisableAutoGenTag: true, } @@ -428,8 +542,8 @@ func newStorageMigrateUpCmd(ctx *CmdCtx) (cmd *cobra.Command) { Short: cmdAutheliaStorageMigrateUpShort, Long: cmdAutheliaStorageMigrateUpLong, Example: cmdAutheliaStorageMigrateUpExample, - Args: cobra.NoArgs, RunE: ctx.NewStorageMigrationRunE(true), + Args: cobra.NoArgs, DisableAutoGenTag: true, } @@ -445,8 +559,8 @@ func newStorageMigrateDownCmd(ctx *CmdCtx) (cmd *cobra.Command) { Short: cmdAutheliaStorageMigrateDownShort, Long: cmdAutheliaStorageMigrateDownLong, Example: cmdAutheliaStorageMigrateDownExample, - Args: cobra.NoArgs, RunE: ctx.NewStorageMigrationRunE(false), + Args: cobra.NoArgs, DisableAutoGenTag: true, } diff --git a/internal/commands/storage_run.go b/internal/commands/storage_run.go index 42103dd6a..d2033767c 100644 --- a/internal/commands/storage_run.go +++ b/internal/commands/storage_run.go @@ -1,6 +1,7 @@ package commands import ( + "bytes" "database/sql" "errors" "fmt" @@ -48,8 +49,8 @@ func (ctx *CmdCtx) LoadProvidersStorageRunE(cmd *cobra.Command, args []string) ( } } -// ConfigStorageCommandLineConfigPersistentPreRunE configures the storage command mapping. -func (ctx *CmdCtx) ConfigStorageCommandLineConfigPersistentPreRunE(cmd *cobra.Command, _ []string) (err error) { +// ConfigStorageCommandLineConfigRunE configures the storage command mapping. +func (ctx *CmdCtx) ConfigStorageCommandLineConfigRunE(cmd *cobra.Command, _ []string) (err error) { flagsMap := map[string]string{ cmdFlagNameEncryptionKey: "storage.encryption_key", @@ -82,8 +83,8 @@ func (ctx *CmdCtx) ConfigStorageCommandLineConfigPersistentPreRunE(cmd *cobra.Co return ctx.ConfigSetFlagsMapRunE(cmd.Flags(), flagsMap, true, false) } -// ConfigValidateStoragePersistentPreRunE validates the storage config before running commands using it. -func (ctx *CmdCtx) ConfigValidateStoragePersistentPreRunE(_ *cobra.Command, _ []string) (err error) { +// ConfigValidateStorageRunE validates the storage config before running commands using it. +func (ctx *CmdCtx) ConfigValidateStorageRunE(_ *cobra.Command, _ []string) (err error) { if errs := ctx.cconfig.validator.Errors(); len(errs) != 0 { var ( i int @@ -128,15 +129,15 @@ func (ctx *CmdCtx) ConfigValidateStoragePersistentPreRunE(_ *cobra.Command, _ [] } func (ctx *CmdCtx) StorageSchemaEncryptionCheckRunE(cmd *cobra.Command, args []string) (err error) { + defer func() { + _ = ctx.providers.StorageProvider.Close() + }() + var ( verbose bool result storage.EncryptionValidationResult ) - defer func() { - _ = ctx.providers.StorageProvider.Close() - }() - if err = ctx.CheckSchemaVersion(); err != nil { return storageWrapCheckSchemaErr(err) } @@ -185,16 +186,16 @@ func (ctx *CmdCtx) StorageSchemaEncryptionCheckRunE(cmd *cobra.Command, args []s // StorageSchemaEncryptionChangeKeyRunE is the RunE for the authelia storage encryption change-key command. func (ctx *CmdCtx) StorageSchemaEncryptionChangeKeyRunE(cmd *cobra.Command, args []string) (err error) { + defer func() { + _ = ctx.providers.StorageProvider.Close() + }() + var ( key string version int ) - defer func() { - _ = ctx.providers.StorageProvider.Close() - }() - - if err = ctx.CheckSchemaVersion(); err != nil { + if err = ctx.CheckSchema(); err != nil { return storageWrapCheckSchemaErr(err) } @@ -235,300 +236,17 @@ func (ctx *CmdCtx) StorageSchemaEncryptionChangeKeyRunE(cmd *cobra.Command, args return nil } -// StorageWebauthnListRunE is the RunE for the authelia storage user webauthn list command. -func (ctx *CmdCtx) StorageWebauthnListRunE(cmd *cobra.Command, args []string) (err error) { - if len(args) == 0 || args[0] == "" { - return ctx.StorageWebauthnListAllRunE(cmd, args) - } - - defer func() { - _ = ctx.providers.StorageProvider.Close() - }() - - if err = ctx.CheckSchemaVersion(); err != nil { - return storageWrapCheckSchemaErr(err) - } - - var devices []model.WebauthnDevice - - user := args[0] - - devices, err = ctx.providers.StorageProvider.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 -} - -// StorageWebauthnListAllRunE is the RunE for the authelia storage user webauthn list command when no args are specified. -func (ctx *CmdCtx) StorageWebauthnListAllRunE(_ *cobra.Command, _ []string) (err error) { - defer func() { - _ = ctx.providers.StorageProvider.Close() - }() - - if err = ctx.CheckSchemaVersion(); err != nil { - return storageWrapCheckSchemaErr(err) - } - - var devices []model.WebauthnDevice - - limit := 10 - - output := strings.Builder{} - - for page := 0; true; page++ { - if devices, err = ctx.providers.StorageProvider.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 -} - -// StorageWebauthnDeleteRunE is the RunE for the authelia storage user webauthn delete command. -func (ctx *CmdCtx) StorageWebauthnDeleteRunE(cmd *cobra.Command, args []string) (err error) { - defer func() { - _ = ctx.providers.StorageProvider.Close() - }() - - if err = ctx.CheckSchemaVersion(); err != nil { - return storageWrapCheckSchemaErr(err) - } - - var ( - all, byKID bool - description, kid, user string - ) - - if all, byKID, description, kid, user, err = storageWebauthnDeleteRunEOptsFromFlags(cmd.Flags(), args); err != nil { - return err - } - - if byKID { - if err = ctx.providers.StorageProvider.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 = ctx.providers.StorageProvider.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 -} - -// StorageTOTPGenerateRunE is the RunE for the authelia storage user totp generate command. -func (ctx *CmdCtx) StorageTOTPGenerateRunE(cmd *cobra.Command, args []string) (err error) { - var ( - c *model.TOTPConfiguration - force bool - filename, secret string - file *os.File - img image.Image - ) - - defer func() { - _ = ctx.providers.StorageProvider.Close() - }() - - if err = ctx.CheckSchemaVersion(); err != nil { - return storageWrapCheckSchemaErr(err) - } - - if force, filename, secret, err = storageTOTPGenerateRunEOptsFromFlags(cmd.Flags()); err != nil { - return err - } - - if _, err = ctx.providers.StorageProvider.LoadTOTPConfiguration(ctx, args[0]); err == nil && !force { - return fmt.Errorf("%s already has a TOTP configuration, use --force to overwrite", args[0]) - } else if err != nil && !errors.Is(err, storage.ErrNoTOTPConfiguration) { - return err - } - - totpProvider := totp.NewTimeBasedProvider(ctx.config.TOTP) - - if c, err = totpProvider.GenerateCustom(args[0], ctx.config.TOTP.Algorithm, secret, ctx.config.TOTP.Digits, ctx.config.TOTP.Period, ctx.config.TOTP.SecretSize); err != nil { - return err - } - - extraInfo := "" - - if filename != "" { - if _, err = os.Stat(filename); !os.IsNotExist(err) { - return errors.New("image output filepath already exists") - } - - if file, err = os.Create(filename); err != nil { - return err - } - - defer file.Close() - - if img, err = c.Image(256, 256); err != nil { - return err - } - - if err = png.Encode(file, img); err != nil { - return err - } - - extraInfo = fmt.Sprintf(" and saved it as a PNG image at the path '%s'", filename) - } - - if err = ctx.providers.StorageProvider.SaveTOTPConfiguration(ctx, *c); err != nil { - return err - } - - fmt.Printf("Generated TOTP configuration for user '%s' with URI '%s'%s\n", args[0], c.URI(), extraInfo) - - return nil -} - -// StorageTOTPDeleteRunE is the RunE for the authelia storage user totp delete command. -func (ctx *CmdCtx) StorageTOTPDeleteRunE(cmd *cobra.Command, args []string) (err error) { - user := args[0] - - defer func() { - _ = ctx.providers.StorageProvider.Close() - }() - - if err = ctx.CheckSchemaVersion(); err != nil { - return storageWrapCheckSchemaErr(err) - } - - if _, err = ctx.providers.StorageProvider.LoadTOTPConfiguration(ctx, user); err != nil { - return fmt.Errorf("can't delete configuration for user '%s': %+v", user, err) - } - - if err = ctx.providers.StorageProvider.DeleteTOTPConfiguration(ctx, user); err != nil { - return fmt.Errorf("can't delete configuration for user '%s': %+v", user, err) - } - - fmt.Printf("Deleted TOTP configuration for user '%s'.", user) - - return nil -} - -// StorageTOTPExportRunE is the RunE for the authelia storage user totp export command. -func (ctx *CmdCtx) StorageTOTPExportRunE(cmd *cobra.Command, args []string) (err error) { - var ( - format, dir string - configurations []model.TOTPConfiguration - img image.Image - ) - - defer func() { - _ = ctx.providers.StorageProvider.Close() - }() - - if err = ctx.CheckSchemaVersion(); err != nil { - return storageWrapCheckSchemaErr(err) - } - - if format, dir, err = flagsGetTOTPExportOptions(cmd.Flags()); err != nil { - return err - } - - limit := 10 - - for page := 0; true; page++ { - if configurations, err = ctx.providers.StorageProvider.LoadTOTPConfigurations(ctx, limit, page); err != nil { - return err - } - - if page == 0 && format == storageTOTPExportFormatCSV { - fmt.Printf("issuer,username,algorithm,digits,period,secret\n") - } - - for _, c := range configurations { - switch format { - case storageTOTPExportFormatCSV: - fmt.Printf("%s,%s,%s,%d,%d,%s\n", c.Issuer, c.Username, c.Algorithm, c.Digits, c.Period, string(c.Secret)) - case storageTOTPExportFormatURI: - fmt.Println(c.URI()) - case storageTOTPExportFormatPNG: - file, _ := os.Create(filepath.Join(dir, fmt.Sprintf("%s.png", c.Username))) - - if img, err = c.Image(256, 256); err != nil { - _ = file.Close() - - return err - } - - if err = png.Encode(file, img); err != nil { - _ = file.Close() - - return err - } - - _ = file.Close() - } - } - - if len(configurations) < limit { - break - } - } - - if format == storageTOTPExportFormatPNG { - fmt.Printf("Exported TOTP QR codes in PNG format in the '%s' directory\n", dir) - } - - return nil -} - // StorageMigrateHistoryRunE is the RunE for the authelia storage migrate history command. func (ctx *CmdCtx) StorageMigrateHistoryRunE(_ *cobra.Command, _ []string) (err error) { + defer func() { + _ = ctx.providers.StorageProvider.Close() + }() + var ( version int migrations []model.Migration ) - defer func() { - _ = ctx.providers.StorageProvider.Close() - }() - if version, err = ctx.providers.StorageProvider.SchemaVersion(ctx); err != nil { return err } @@ -558,15 +276,15 @@ func (ctx *CmdCtx) StorageMigrateHistoryRunE(_ *cobra.Command, _ []string) (err // NewStorageMigrateListRunE creates the RunE for the authelia storage migrate list command. func (ctx *CmdCtx) NewStorageMigrateListRunE(up bool) func(cmd *cobra.Command, args []string) (err error) { return func(cmd *cobra.Command, args []string) (err error) { + defer func() { + _ = ctx.providers.StorageProvider.Close() + }() + var ( migrations []model.SchemaMigration directionStr string ) - defer func() { - _ = ctx.providers.StorageProvider.Close() - }() - if up { migrations, err = ctx.providers.StorageProvider.SchemaMigrationsUp(ctx, 0) directionStr = "Up" @@ -596,14 +314,14 @@ func (ctx *CmdCtx) NewStorageMigrateListRunE(up bool) func(cmd *cobra.Command, a // NewStorageMigrationRunE creates the RunE for the authelia storage migrate command. func (ctx *CmdCtx) NewStorageMigrationRunE(up bool) func(cmd *cobra.Command, args []string) (err error) { return func(cmd *cobra.Command, args []string) (err error) { - var ( - target int - ) - defer func() { _ = ctx.providers.StorageProvider.Close() }() + var ( + target int + ) + if target, err = cmd.Flags().GetInt(cmdFlagNameTarget); err != nil { return err } @@ -638,6 +356,10 @@ func (ctx *CmdCtx) NewStorageMigrationRunE(up bool) func(cmd *cobra.Command, arg // StorageSchemaInfoRunE is the RunE for the authelia storage schema info command. func (ctx *CmdCtx) StorageSchemaInfoRunE(_ *cobra.Command, _ []string) (err error) { + defer func() { + _ = ctx.providers.StorageProvider.Close() + }() + var ( upgradeStr, tablesStr string @@ -645,10 +367,6 @@ func (ctx *CmdCtx) StorageSchemaInfoRunE(_ *cobra.Command, _ []string) (err erro version, latest int ) - defer func() { - _ = ctx.providers.StorageProvider.Close() - }() - if version, err = ctx.providers.StorageProvider.SchemaVersion(ctx); err != nil && err.Error() != "unknown schema state" { return err } @@ -696,39 +414,659 @@ func (ctx *CmdCtx) StorageSchemaInfoRunE(_ *cobra.Command, _ []string) (err erro return nil } -// StorageUserIdentifiersExportRunE is the RunE for the authelia storage user identifiers export command. -func (ctx *CmdCtx) StorageUserIdentifiersExportRunE(cmd *cobra.Command, _ []string) (err error) { - var ( - file string - ) - - if file, err = cmd.Flags().GetString(cmdFlagNameFile); err != nil { - return err - } - - _, err = os.Stat(file) - - switch { - case err == nil: - return fmt.Errorf("must specify a file that doesn't exist but '%s' exists", file) - case !os.IsNotExist(err): - return fmt.Errorf("error occurred opening '%s': %w", file, err) - } - +func (ctx *CmdCtx) StorageUserWebauthnExportRunE(cmd *cobra.Command, args []string) (err error) { defer func() { _ = ctx.providers.StorageProvider.Close() }() - if err = ctx.CheckSchemaVersion(); err != nil { + if err = ctx.CheckSchema(); err != nil { return storageWrapCheckSchemaErr(err) } var ( - export model.UserOpaqueIdentifiersExport + filename string + ) + if filename, err = cmd.Flags().GetString(cmdFlagNameFile); err != nil { + return err + } + + switch _, err = os.Stat(filename); { + case err == nil: + return fmt.Errorf("must specify a file that doesn't exist but '%s' exists", filename) + case !os.IsNotExist(err): + return fmt.Errorf("error occurred opening '%s': %w", filename, err) + } + + limit := 10 + count := 0 + + var ( + devices []model.WebauthnDevice + ) + + export := &model.WebauthnDeviceExport{ + WebauthnDevices: nil, + } + + for page := 0; true; page++ { + if devices, err = ctx.providers.StorageProvider.LoadWebauthnDevices(ctx, limit, page); err != nil { + return err + } + + export.WebauthnDevices = append(export.WebauthnDevices, devices...) + + l := len(devices) + + count += l + + if l < limit { + break + } + } + + var data []byte + + if data, err = yaml.Marshal(export); err != nil { + return fmt.Errorf("error occurred marshalling data to YAML: %w", err) + } + + if err = os.WriteFile(filename, data, 0600); err != nil { + return fmt.Errorf("error occurred writing to file '%s': %w", filename, err) + } + + fmt.Printf(cliOutputFmtSuccessfulUserExportFile, count, "Webauthn devices", "YAML", filename) + + return nil +} + +func (ctx *CmdCtx) StorageUserWebauthnImportRunE(cmd *cobra.Command, args []string) (err error) { + defer func() { + _ = ctx.providers.StorageProvider.Close() + }() + + var ( + filename string + + stat os.FileInfo data []byte ) + filename = args[0] + + if stat, err = os.Stat(filename); err != nil { + return fmt.Errorf("must specify a filename that exists but '%s' had an error opening it: %w", filename, err) + } + + if stat.IsDir() { + return fmt.Errorf("must specify a filename that exists but '%s' is a directory", filename) + } + + if data, err = os.ReadFile(filename); err != nil { + return err + } + + export := &model.WebauthnDeviceExport{} + + if err = yaml.Unmarshal(data, export); err != nil { + return err + } + + if len(export.WebauthnDevices) == 0 { + return fmt.Errorf("can't import a YAML file without Webauthn devices data") + } + + if err = ctx.CheckSchema(); err != nil { + return storageWrapCheckSchemaErr(err) + } + + for _, device := range export.WebauthnDevices { + if err = ctx.providers.StorageProvider.SaveWebauthnDevice(ctx, device); err != nil { + return err + } + } + + fmt.Printf(cliOutputFmtSuccessfulUserImportFile, len(export.WebauthnDevices), "Webauthn devices", "YAML", filename) + + return nil +} + +// StorageUserWebauthnListRunE is the RunE for the authelia storage user webauthn list command. +func (ctx *CmdCtx) StorageUserWebauthnListRunE(cmd *cobra.Command, args []string) (err error) { + defer func() { + _ = ctx.providers.StorageProvider.Close() + }() + + if len(args) == 0 || args[0] == "" { + return ctx.StorageUserWebauthnListAllRunE(cmd, args) + } + + if err = ctx.CheckSchema(); err != nil { + return storageWrapCheckSchemaErr(err) + } + + var devices []model.WebauthnDevice + + user := args[0] + + devices, err = ctx.providers.StorageProvider.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 +} + +// 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) { + defer func() { + _ = ctx.providers.StorageProvider.Close() + }() + + if err = ctx.CheckSchema(); err != nil { + return storageWrapCheckSchemaErr(err) + } + + var devices []model.WebauthnDevice + + limit := 10 + + output := strings.Builder{} + + for page := 0; true; page++ { + if devices, err = ctx.providers.StorageProvider.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 +} + +// StorageUserWebauthnDeleteRunE is the RunE for the authelia storage user webauthn delete command. +func (ctx *CmdCtx) StorageUserWebauthnDeleteRunE(cmd *cobra.Command, args []string) (err error) { + defer func() { + _ = ctx.providers.StorageProvider.Close() + }() + + if err = ctx.CheckSchema(); err != nil { + return storageWrapCheckSchemaErr(err) + } + + var ( + all, byKID bool + description, kid, user string + ) + + if all, byKID, description, kid, user, err = storageWebauthnDeleteRunEOptsFromFlags(cmd.Flags(), args); err != nil { + return err + } + + if byKID { + if err = ctx.providers.StorageProvider.DeleteWebauthnDevice(ctx, kid); err != nil { + 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) + } else { + err = ctx.providers.StorageProvider.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("Successfully deleted all Webauthn devices for user '%s'\n", 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("Successfully deleted Webauthn device with description '%s' for user '%s'\n", description, user) + } + } + + return nil +} + +// StorageUserTOTPGenerateRunE is the RunE for the authelia storage user totp generate command. +func (ctx *CmdCtx) StorageUserTOTPGenerateRunE(cmd *cobra.Command, args []string) (err error) { + defer func() { + _ = ctx.providers.StorageProvider.Close() + }() + + var ( + c *model.TOTPConfiguration + force bool + filename, secret string + file *os.File + img image.Image + ) + + if err = ctx.CheckSchema(); err != nil { + return storageWrapCheckSchemaErr(err) + } + + if force, filename, secret, err = storageTOTPGenerateRunEOptsFromFlags(cmd.Flags()); err != nil { + return err + } + + if _, err = ctx.providers.StorageProvider.LoadTOTPConfiguration(ctx, args[0]); err == nil && !force { + return fmt.Errorf("%s already has a TOTP configuration, use --force to overwrite", args[0]) + } else if err != nil && !errors.Is(err, storage.ErrNoTOTPConfiguration) { + return err + } + + totpProvider := totp.NewTimeBasedProvider(ctx.config.TOTP) + + if c, err = totpProvider.GenerateCustom(args[0], ctx.config.TOTP.Algorithm, secret, ctx.config.TOTP.Digits, ctx.config.TOTP.Period, ctx.config.TOTP.SecretSize); err != nil { + return err + } + + extraInfo := "" + + if filename != "" { + if _, err = os.Stat(filename); !os.IsNotExist(err) { + return errors.New("image output filepath already exists") + } + + if file, err = os.Create(filename); err != nil { + return err + } + + defer file.Close() + + if img, err = c.Image(256, 256); err != nil { + return err + } + + if err = png.Encode(file, img); err != nil { + return err + } + + extraInfo = fmt.Sprintf(" and saved it as a PNG image at the path '%s'", filename) + } + + if err = ctx.providers.StorageProvider.SaveTOTPConfiguration(ctx, *c); err != nil { + return err + } + + fmt.Printf("Successfully generated TOTP configuration for user '%s' with URI '%s'%s\n", args[0], c.URI(), extraInfo) + + return nil +} + +// StorageUserTOTPDeleteRunE is the RunE for the authelia storage user totp delete command. +func (ctx *CmdCtx) StorageUserTOTPDeleteRunE(cmd *cobra.Command, args []string) (err error) { + defer func() { + _ = ctx.providers.StorageProvider.Close() + }() + + user := args[0] + + if err = ctx.CheckSchema(); err != nil { + return storageWrapCheckSchemaErr(err) + } + + if _, err = ctx.providers.StorageProvider.LoadTOTPConfiguration(ctx, user); err != nil { + return fmt.Errorf("failed to delete TOTP configuration for user '%s': %+v", user, err) + } + + if err = ctx.providers.StorageProvider.DeleteTOTPConfiguration(ctx, user); err != nil { + return fmt.Errorf("failed to delete TOTP configuration for user '%s': %+v", user, err) + } + + fmt.Printf("Successfully deleted TOTP configuration for user '%s'\n", user) + + return nil +} + +const ( + cliOutputFmtSuccessfulUserExportFile = "Successfully exported %d %s as %s to the '%s' file\n" + cliOutputFmtSuccessfulUserImportFile = "Successfully imported %d %s from the %s file '%s' into the database\n" +) + +// StorageUserTOTPExportRunE is the RunE for the authelia storage user totp export command. +func (ctx *CmdCtx) StorageUserTOTPExportRunE(cmd *cobra.Command, _ []string) (err error) { + defer func() { + _ = ctx.providers.StorageProvider.Close() + }() + + if err = ctx.CheckSchema(); err != nil { + return storageWrapCheckSchemaErr(err) + } + + var ( + filename string + ) + + if filename, err = cmd.Flags().GetString(cmdFlagNameFile); err != nil { + return err + } + + switch _, err = os.Stat(filename); { + case err == nil: + return fmt.Errorf("must specify a file that doesn't exist but '%s' exists", filename) + case !os.IsNotExist(err): + return fmt.Errorf("error occurred opening '%s': %w", filename, err) + } + + limit := 10 + count := 0 + + var ( + configs []model.TOTPConfiguration + ) + + export := &model.TOTPConfigurationExport{} + + for page := 0; true; page++ { + if configs, err = ctx.providers.StorageProvider.LoadTOTPConfigurations(ctx, limit, page); err != nil { + return err + } + + export.TOTPConfigurations = append(export.TOTPConfigurations, configs...) + + l := len(configs) + + count += l + + if l < limit { + break + } + } + + var data []byte + + if data, err = yaml.Marshal(export); err != nil { + return fmt.Errorf("error occurred marshalling data to YAML: %w", err) + } + + if err = os.WriteFile(filename, data, 0600); err != nil { + return fmt.Errorf("error occurred writing to file '%s': %w", filename, err) + } + + fmt.Printf(cliOutputFmtSuccessfulUserExportFile, count, "TOTP configurations", "YAML", filename) + + return nil +} + +func (ctx *CmdCtx) StorageUserTOTPImportRunE(_ *cobra.Command, args []string) (err error) { + defer func() { + _ = ctx.providers.StorageProvider.Close() + }() + + var ( + filename string + + stat os.FileInfo + data []byte + ) + + filename = args[0] + + if stat, err = os.Stat(filename); err != nil { + return fmt.Errorf("must specify a filename that exists but '%s' had an error opening it: %w", filename, err) + } + + if stat.IsDir() { + return fmt.Errorf("must specify a filename that exists but '%s' is a directory", filename) + } + + if data, err = os.ReadFile(filename); err != nil { + return err + } + + export := &model.TOTPConfigurationExport{} + + if err = yaml.Unmarshal(data, export); err != nil { + return err + } + + if len(export.TOTPConfigurations) == 0 { + return fmt.Errorf("can't import a YAML file without TOTP configuration data") + } + + if err = ctx.CheckSchema(); err != nil { + return storageWrapCheckSchemaErr(err) + } + + for _, config := range export.TOTPConfigurations { + if err = ctx.providers.StorageProvider.SaveTOTPConfiguration(ctx, config); err != nil { + return err + } + } + + fmt.Printf(cliOutputFmtSuccessfulUserImportFile, len(export.TOTPConfigurations), "TOTP configurations", "YAML", filename) + + return nil +} + +func (ctx *CmdCtx) StorageUserTOTPExportURIRunE(_ *cobra.Command, _ []string) (err error) { + defer func() { + _ = ctx.providers.StorageProvider.Close() + }() + + var ( + configs []model.TOTPConfiguration + ) + + if err = ctx.CheckSchema(); err != nil { + return storageWrapCheckSchemaErr(err) + } + + limit := 10 + count := 0 + + buf := &bytes.Buffer{} + + for page := 0; true; page++ { + if configs, err = ctx.providers.StorageProvider.LoadTOTPConfigurations(ctx, limit, page); err != nil { + return err + } + + for _, c := range configs { + buf.WriteString(fmt.Sprintf("%s\n", c.URI())) + } + + l := len(configs) + + count += l + + if l < limit { + break + } + } + + fmt.Print(buf.String()) + + fmt.Printf("\n\nSuccessfully exported %d TOTP configurations as TOTP URI's and printed them to the console\n", count) + + return nil +} + +func (ctx *CmdCtx) StorageUserTOTPExportCSVRunE(cmd *cobra.Command, _ []string) (err error) { + defer func() { + _ = ctx.providers.StorageProvider.Close() + }() + + var ( + filename string + configs []model.TOTPConfiguration + buf *bytes.Buffer + ) + + if err = ctx.CheckSchema(); err != nil { + return storageWrapCheckSchemaErr(err) + } + + if filename, err = cmd.Flags().GetString(cmdFlagNameFile); err != nil { + return err + } + + limit := 10 + count := 0 + + buf = &bytes.Buffer{} + + buf.WriteString("issuer,username,algorithm,digits,period,secret\n") + + for page := 0; true; page++ { + if configs, err = ctx.providers.StorageProvider.LoadTOTPConfigurations(ctx, limit, page); err != nil { + return err + } + + for _, c := range configs { + buf.WriteString(fmt.Sprintf("%s,%s,%s,%d,%d,%s\n", c.Issuer, c.Username, c.Algorithm, c.Digits, c.Period, string(c.Secret))) + } + + l := len(configs) + + count += l + + if l < limit { + break + } + } + + if err = os.WriteFile(filename, buf.Bytes(), 0600); err != nil { + return err + } + + fmt.Printf(cliOutputFmtSuccessfulUserExportFile, count, "TOTP configurations", "CSV", filename) + + return nil +} + +func (ctx *CmdCtx) StorageUserTOTPExportPNGRunE(cmd *cobra.Command, _ []string) (err error) { + defer func() { + _ = ctx.providers.StorageProvider.Close() + }() + + var ( + dir string + configs []model.TOTPConfiguration + img image.Image + ) + + if err = ctx.CheckSchema(); err != nil { + return storageWrapCheckSchemaErr(err) + } + + if dir, err = cmd.Flags().GetString(cmdFlagNameDirectory); err != nil { + return err + } + + if dir == "" { + dir = utils.RandomString(8, utils.CharSetAlphaNumeric, false) + } + + if _, err = os.Stat(dir); !os.IsNotExist(err) { + return errors.New("output directory must not exist") + } + + if err = os.MkdirAll(dir, 0700); err != nil { + return err + } + + limit := 10 + count := 0 + + var file *os.File + + for page := 0; true; page++ { + if configs, err = ctx.providers.StorageProvider.LoadTOTPConfigurations(ctx, limit, page); err != nil { + return err + } + + for _, c := range configs { + if file, err = os.Create(filepath.Join(dir, fmt.Sprintf("%s.png", c.Username))); err != nil { + return err + } + + if img, err = c.Image(256, 256); err != nil { + _ = file.Close() + + return err + } + + if err = png.Encode(file, img); err != nil { + _ = file.Close() + + return err + } + + _ = file.Close() + } + + l := len(configs) + + count += l + + if l < limit { + break + } + } + + fmt.Printf("Successfully exported %d TOTP configuration as QR codes in PNG format to the '%s' directory\n", count, dir) + + return nil +} + +// StorageUserIdentifiersExportRunE is the RunE for the authelia storage user identifiers export command. +func (ctx *CmdCtx) StorageUserIdentifiersExportRunE(cmd *cobra.Command, _ []string) (err error) { + defer func() { + _ = ctx.providers.StorageProvider.Close() + }() + + if err = ctx.CheckSchema(); err != nil { + return storageWrapCheckSchemaErr(err) + } + + var ( + filename string + ) + + if filename, err = cmd.Flags().GetString(cmdFlagNameFile); err != nil { + return err + } + + switch _, err = os.Stat(filename); { + case err == nil: + return fmt.Errorf("must specify a file that doesn't exist but '%s' exists", filename) + case !os.IsNotExist(err): + return fmt.Errorf("error occurred opening '%s': %w", filename, err) + } + + export := &model.UserOpaqueIdentifiersExport{ + Identifiers: nil, + } + if export.Identifiers, err = ctx.providers.StorageProvider.LoadUserOpaqueIdentifiers(ctx); err != nil { return err } @@ -737,60 +1075,59 @@ func (ctx *CmdCtx) StorageUserIdentifiersExportRunE(cmd *cobra.Command, _ []stri return fmt.Errorf("no data to export") } - if data, err = yaml.Marshal(&export); err != nil { + var data []byte + + if data, err = yaml.Marshal(export); err != nil { return fmt.Errorf("error occurred marshalling data to YAML: %w", err) } - if err = os.WriteFile(file, data, 0600); err != nil { - return fmt.Errorf("error occurred writing to file '%s': %w", file, err) + if err = os.WriteFile(filename, data, 0600); err != nil { + return fmt.Errorf("error occurred writing to file '%s': %w", filename, err) } - fmt.Printf("Exported %d User Opaque Identifiers to %s\n", len(export.Identifiers), file) + fmt.Printf(cliOutputFmtSuccessfulUserExportFile, len(export.Identifiers), "User Opaque Identifiers", "YAML", filename) return nil } // StorageUserIdentifiersImportRunE is the RunE for the authelia storage user identifiers import command. -func (ctx *CmdCtx) StorageUserIdentifiersImportRunE(cmd *cobra.Command, _ []string) (err error) { - var ( - file string - stat os.FileInfo - ) - - if file, err = cmd.Flags().GetString(cmdFlagNameFile); err != nil { - return err - } - - if stat, err = os.Stat(file); err != nil { - return fmt.Errorf("must specify a file that exists but '%s' had an error opening it: %w", file, err) - } - - if stat.IsDir() { - return fmt.Errorf("must specify a file that exists but '%s' is a directory", file) - } - - var ( - data []byte - export model.UserOpaqueIdentifiersExport - ) - - if data, err = os.ReadFile(file); err != nil { - return err - } - - if err = yaml.Unmarshal(data, &export); err != nil { - return err - } - - if len(export.Identifiers) == 0 { - return fmt.Errorf("can't import a file with no data") - } - +func (ctx *CmdCtx) StorageUserIdentifiersImportRunE(cmd *cobra.Command, args []string) (err error) { defer func() { _ = ctx.providers.StorageProvider.Close() }() - if err = ctx.CheckSchemaVersion(); err != nil { + var ( + filename string + + stat os.FileInfo + data []byte + ) + + filename = args[0] + + if stat, err = os.Stat(filename); err != nil { + return fmt.Errorf("must specify a file that exists but '%s' had an error opening it: %w", filename, err) + } + + if stat.IsDir() { + return fmt.Errorf("must specify a file that exists but '%s' is a directory", filename) + } + + if data, err = os.ReadFile(filename); err != nil { + return err + } + + export := &model.UserOpaqueIdentifiersExport{} + + if err = yaml.Unmarshal(data, export); err != nil { + return err + } + + if len(export.Identifiers) == 0 { + return fmt.Errorf("can't import a YAML file without User Opaque Identifiers data") + } + + if err = ctx.CheckSchema(); err != nil { return storageWrapCheckSchemaErr(err) } @@ -800,22 +1137,22 @@ func (ctx *CmdCtx) StorageUserIdentifiersImportRunE(cmd *cobra.Command, _ []stri } } - fmt.Printf("Imported User Opaque Identifiers from %s\n", file) + fmt.Printf(cliOutputFmtSuccessfulUserImportFile, len(export.Identifiers), "User Opaque Identifiers", "YAML", filename) return nil } // StorageUserIdentifiersGenerateRunE is the RunE for the authelia storage user identifiers generate command. func (ctx *CmdCtx) StorageUserIdentifiersGenerateRunE(cmd *cobra.Command, _ []string) (err error) { - var ( - users, services, sectors []string - ) - defer func() { _ = ctx.providers.StorageProvider.Close() }() - if err = ctx.CheckSchemaVersion(); err != nil { + var ( + users, services, sectors []string + ) + + if err = ctx.CheckSchema(); err != nil { return storageWrapCheckSchemaErr(err) } @@ -871,13 +1208,26 @@ func (ctx *CmdCtx) StorageUserIdentifiersGenerateRunE(cmd *cobra.Command, _ []st } } - fmt.Printf("Successfully added %d opaque identifiers and %d duplicates were skipped\n", added, duplicates) + fmt.Printf("Successfully generated and addded opaque identifiers:\n") + fmt.Printf("\tUsers: '%s'\n", strings.Join(users, "', '")) + fmt.Printf("\tSectors: '%s'\n", strings.Join(sectors, "', '")) + fmt.Printf("\tServices: '%s'\n", strings.Join(services, "', '")) + + if duplicates != 0 { + fmt.Printf("\tSkipped Duplicates: %d\n", duplicates) + } + + fmt.Printf("\tTotal: %d", added) return nil } // StorageUserIdentifiersAddRunE is the RunE for the authelia storage user identifiers add command. func (ctx *CmdCtx) StorageUserIdentifiersAddRunE(cmd *cobra.Command, args []string) (err error) { + defer func() { + _ = ctx.providers.StorageProvider.Close() + }() + var ( service, sector string ) @@ -922,11 +1272,7 @@ func (ctx *CmdCtx) StorageUserIdentifiersAddRunE(cmd *cobra.Command, args []stri } } - defer func() { - _ = ctx.providers.StorageProvider.Close() - }() - - if err = ctx.CheckSchemaVersion(); err != nil { + if err = ctx.CheckSchema(); err != nil { return storageWrapCheckSchemaErr(err) } diff --git a/internal/commands/util.go b/internal/commands/util.go index 8d1eb95d4..19072f9a4 100644 --- a/internal/commands/util.go +++ b/internal/commands/util.go @@ -46,37 +46,6 @@ func flagsGetUserIdentifiersGenerateOptions(flags *pflag.FlagSet) (users, servic return users, services, sectors, nil } -func flagsGetTOTPExportOptions(flags *pflag.FlagSet) (format, dir string, err error) { - if format, err = flags.GetString(cmdFlagNameFormat); err != nil { - return "", "", err - } - - if dir, err = flags.GetString("dir"); err != nil { - return "", "", err - } - - switch format { - case storageTOTPExportFormatCSV, storageTOTPExportFormatURI: - break - case storageTOTPExportFormatPNG: - if dir == "" { - dir = utils.RandomString(8, utils.CharSetAlphaNumeric, false) - } - - if _, err = os.Stat(dir); !os.IsNotExist(err) { - return "", "", errors.New("output directory must not exist") - } - - if err = os.MkdirAll(dir, 0700); err != nil { - return "", "", err - } - default: - return "", "", errors.New("format must be csv, uri, or png") - } - - return format, dir, nil -} - //nolint:gocyclo func flagsGetRandomCharacters(flags *pflag.FlagSet, flagNameLength, flagNameCharSet, flagNameCharacters string) (r string, err error) { var ( diff --git a/internal/model/totp_configuration.go b/internal/model/totp_configuration.go index f8f23d41b..a262ddb7b 100644 --- a/internal/model/totp_configuration.go +++ b/internal/model/totp_configuration.go @@ -2,12 +2,14 @@ package model import ( "database/sql" + "encoding/base64" "image" "net/url" "strconv" "time" "github.com/pquerna/otp" + "gopkg.in/yaml.v3" ) // TOTPConfiguration represents a users TOTP configuration row in the database. @@ -70,3 +72,62 @@ func (c *TOTPConfiguration) Image(width, height int) (img image.Image, err error return key.Image(width, height) } + +// MarshalYAML marshals this model into YAML. +func (c *TOTPConfiguration) MarshalYAML() (any, error) { + o := TOTPConfigurationData{ + CreatedAt: c.CreatedAt, + LastUsedAt: c.LastUsed(), + Username: c.Username, + Issuer: c.Issuer, + Algorithm: c.Algorithm, + Digits: c.Digits, + Period: c.Period, + Secret: base64.StdEncoding.EncodeToString(c.Secret), + } + + return yaml.Marshal(o) +} + +// UnmarshalYAML unmarshalls YAML into this model. +func (c *TOTPConfiguration) UnmarshalYAML(value *yaml.Node) (err error) { + o := &TOTPConfigurationData{} + + if err = value.Decode(o); err != nil { + return err + } + + if c.Secret, err = base64.StdEncoding.DecodeString(o.Secret); err != nil { + return err + } + + c.CreatedAt = o.CreatedAt + c.Username = o.Username + c.Issuer = o.Issuer + c.Algorithm = o.Algorithm + c.Digits = o.Digits + c.Period = o.Period + + if o.LastUsedAt != nil { + c.LastUsedAt = sql.NullTime{Valid: true, Time: *o.LastUsedAt} + } + + return nil +} + +// TOTPConfigurationData is used for marshalling/unmarshalling tasks. +type TOTPConfigurationData struct { + CreatedAt time.Time `yaml:"created_at"` + LastUsedAt *time.Time `yaml:"last_used_at"` + Username string `yaml:"username"` + Issuer string `yaml:"issuer"` + Algorithm string `yaml:"algorithm"` + Digits uint `yaml:"digits"` + Period uint `yaml:"period"` + Secret string `yaml:"secret"` +} + +// TOTPConfigurationExport represents a TOTPConfiguration export file. +type TOTPConfigurationExport struct { + TOTPConfigurations []TOTPConfiguration `yaml:"totp_configurations"` +} diff --git a/internal/model/user_opaque_identifier.go b/internal/model/user_opaque_identifier.go index 557c1370d..43f7d2f6c 100644 --- a/internal/model/user_opaque_identifier.go +++ b/internal/model/user_opaque_identifier.go @@ -24,7 +24,7 @@ func NewUserOpaqueIdentifier(service, sectorID, username string) (id *UserOpaque // UserOpaqueIdentifier represents an opaque identifier for a user. Commonly used with OAuth 2.0 and OpenID Connect. type UserOpaqueIdentifier struct { - ID int `db:"id" yaml:"id"` + ID int `db:"id" yaml:"-"` Service string `db:"service" yaml:"service"` SectorID string `db:"sector_id" yaml:"sector_id"` Username string `db:"username" yaml:"username"` diff --git a/internal/model/webauthn.go b/internal/model/webauthn.go index 415e50a69..a3a19c62e 100644 --- a/internal/model/webauthn.go +++ b/internal/model/webauthn.go @@ -2,6 +2,7 @@ package model import ( "database/sql" + "encoding/base64" "encoding/hex" "strings" "time" @@ -9,6 +10,7 @@ import ( "github.com/go-webauthn/webauthn/protocol" "github.com/go-webauthn/webauthn/webauthn" "github.com/google/uuid" + "gopkg.in/yaml.v3" ) const ( @@ -153,19 +155,114 @@ type WebauthnDevice struct { } // UpdateSignInInfo adjusts the values of the WebauthnDevice after a sign in. -func (w *WebauthnDevice) UpdateSignInInfo(config *webauthn.Config, now time.Time, signCount uint32) { - w.LastUsedAt = sql.NullTime{Time: now, Valid: true} +func (d *WebauthnDevice) UpdateSignInInfo(config *webauthn.Config, now time.Time, signCount uint32) { + d.LastUsedAt = sql.NullTime{Time: now, Valid: true} - w.SignCount = signCount + d.SignCount = signCount - if w.RPID != "" { + if d.RPID != "" { return } - switch w.AttestationType { + switch d.AttestationType { case attestationTypeFIDOU2F: - w.RPID = config.RPOrigin + d.RPID = config.RPOrigin default: - w.RPID = config.RPID + d.RPID = config.RPID } } + +func (d *WebauthnDevice) LastUsed() *time.Time { + if d.LastUsedAt.Valid { + return &d.LastUsedAt.Time + } + + return nil +} + +// MarshalYAML marshals this model into YAML. +func (d *WebauthnDevice) MarshalYAML() (any, error) { + o := WebauthnDeviceData{ + CreatedAt: d.CreatedAt, + LastUsedAt: d.LastUsed(), + RPID: d.RPID, + Username: d.Username, + Description: d.Description, + KID: d.KID.String(), + PublicKey: base64.StdEncoding.EncodeToString(d.PublicKey), + AttestationType: d.AttestationType, + Transport: d.Transport, + AAGUID: d.AAGUID.UUID.String(), + SignCount: d.SignCount, + CloneWarning: d.CloneWarning, + } + + return yaml.Marshal(o) +} + +// UnmarshalYAML unmarshalls YAML into this model. +func (d *WebauthnDevice) UnmarshalYAML(value *yaml.Node) (err error) { + o := &WebauthnDeviceData{} + + if err = value.Decode(o); err != nil { + return err + } + + if d.PublicKey, err = base64.StdEncoding.DecodeString(o.PublicKey); err != nil { + return err + } + + var aaguid uuid.UUID + + if aaguid, err = uuid.Parse(o.AAGUID); err != nil { + return err + } + + if aaguid.ID() != 0 { + d.AAGUID = uuid.NullUUID{Valid: true, UUID: aaguid} + } + + var kid []byte + + if kid, err = base64.StdEncoding.DecodeString(o.KID); err != nil { + return err + } + + d.KID = NewBase64(kid) + + d.CreatedAt = o.CreatedAt + d.RPID = o.RPID + d.Username = o.Username + d.Description = o.Description + d.AttestationType = o.AttestationType + d.Transport = o.Transport + d.SignCount = o.SignCount + d.CloneWarning = o.CloneWarning + + if o.LastUsedAt != nil { + d.LastUsedAt = sql.NullTime{Valid: true, Time: *o.LastUsedAt} + } + + return nil +} + +// WebauthnDeviceData represents a Webauthn Device in the database storage. +type WebauthnDeviceData struct { + CreatedAt time.Time `yaml:"created_at"` + LastUsedAt *time.Time `yaml:"last_used_at"` + RPID string `yaml:"rpid"` + Username string `yaml:"username"` + Description string `yaml:"description"` + KID string `yaml:"kid"` + PublicKey string `yaml:"public_key"` + AttestationType string `yaml:"attestation_type"` + Transport string `yaml:"transport"` + AAGUID string `yaml:"aaguid"` + SignCount uint32 `yaml:"sign_count"` + CloneWarning bool `yaml:"clone_warning"` +} + +// WebauthnDeviceExport represents a WebauthnDevice export file. +type WebauthnDeviceExport struct { + WebauthnDevices []WebauthnDevice `yaml:"webauthn_devices"` +} diff --git a/internal/suites/suite_cli_test.go b/internal/suites/suite_cli_test.go index 715d1fb1a..e68099aec 100644 --- a/internal/suites/suite_cli_test.go +++ b/internal/suites/suite_cli_test.go @@ -5,6 +5,7 @@ import ( "context" "fmt" "os" + "path/filepath" "regexp" "strconv" "testing" @@ -929,13 +930,17 @@ func (s *CLISuite) TestStorage03ShouldExportTOTP() { fileInfo os.FileInfo ) + dir := s.T().TempDir() + + qr := filepath.Join(dir, "qr.png") + for _, testCase := range testCases { if testCase.png { - output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "totp", "generate", testCase.config.Username, "--period", strconv.Itoa(int(testCase.config.Period)), "--algorithm", testCase.config.Algorithm, "--digits", strconv.Itoa(int(testCase.config.Digits)), "--path=/tmp/qr.png", "--config=/config/configuration.storage.yml"}) + output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "totp", "generate", testCase.config.Username, "--period", strconv.Itoa(int(testCase.config.Period)), "--algorithm", testCase.config.Algorithm, "--digits", strconv.Itoa(int(testCase.config.Digits)), "--path", qr, "--config=/config/configuration.storage.yml"}) s.Assert().NoError(err) - s.Assert().Contains(output, " and saved it as a PNG image at the path '/tmp/qr.png'") + s.Assert().Contains(output, fmt.Sprintf(" and saved it as a PNG image at the path '%s'", qr)) - fileInfo, err = os.Stat("/tmp/qr.png") + fileInfo, err = os.Stat(qr) s.Assert().NoError(err) s.Require().NotNil(fileInfo) s.Assert().False(fileInfo.IsDir()) @@ -954,30 +959,41 @@ func (s *CLISuite) TestStorage03ShouldExportTOTP() { expectedLines = append(expectedLines, config.URI()) } - output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "totp", "export", "--format=uri", "--config=/config/configuration.storage.yml"}) + yml := filepath.Join(dir, "authelia.export.totp.yaml") + output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "totp", "export", "--file", yml, "--config=/config/configuration.storage.yml"}) + s.Assert().NoError(err) + s.Assert().Contains(output, fmt.Sprintf("Successfully exported %d TOTP configurations as YAML to the '%s' file\n", len(expectedLines), yml)) + + output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "totp", "export", "uri", "--config=/config/configuration.storage.yml"}) s.Assert().NoError(err) for _, expectedLine := range expectedLines { s.Assert().Contains(output, expectedLine) } - output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "totp", "export", "--format=csv", "--config=/config/configuration.storage.yml"}) + csv := filepath.Join(dir, "authelia.export.totp.csv") + output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "totp", "export", "csv", "--file", csv, "--config=/config/configuration.storage.yml"}) + s.Assert().NoError(err) + s.Assert().Contains(output, fmt.Sprintf("Successfully exported %d TOTP configurations as CSV to the '%s' file\n", len(expectedLines), csv)) + + var data []byte + + data, err = os.ReadFile(csv) s.Assert().NoError(err) + content := string(data) for _, expectedLine := range expectedLinesCSV { - s.Assert().Contains(output, expectedLine) + s.Assert().Contains(content, expectedLine) } - output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "totp", "export", "--format=wrong", "--config=/config/configuration.storage.yml"}) - s.Assert().EqualError(err, "exit status 1") - s.Assert().Contains(output, "Error: format must be csv, uri, or png") + pngs := filepath.Join(dir, "png-qr-codes") - output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "totp", "export", "--format=png", "--dir=/tmp/qr", "--config=/config/configuration.storage.yml"}) + output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "totp", "export", "png", "--directory", pngs, "--config=/config/configuration.storage.yml"}) s.Assert().NoError(err) - s.Assert().Contains(output, "Exported TOTP QR codes in PNG format in the '/tmp/qr' directory") + s.Assert().Contains(output, fmt.Sprintf("Successfully exported %d TOTP configuration as QR codes in PNG format to the '%s' directory\n", len(expectedLines), pngs)) for _, testCase := range testCases { - fileInfo, err = os.Stat(fmt.Sprintf("/tmp/qr/%s.png", testCase.config.Username)) + fileInfo, err = os.Stat(filepath.Join(pngs, fmt.Sprintf("%s.png", testCase.config.Username))) s.Assert().NoError(err) s.Require().NotNil(fileInfo) @@ -986,13 +1002,13 @@ func (s *CLISuite) TestStorage03ShouldExportTOTP() { s.Assert().Greater(fileInfo.Size(), int64(1000)) } - output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "totp", "generate", "test", "--period=30", "--algorithm=SHA1", "--digits=6", "--path=/tmp/qr.png", "--config=/config/configuration.storage.yml"}) + output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "totp", "generate", "test", "--period=30", "--algorithm=SHA1", "--digits=6", "--path", qr, "--config=/config/configuration.storage.yml"}) s.Assert().EqualError(err, "exit status 1") s.Assert().Contains(output, "Error: image output filepath already exists") } func (s *CLISuite) TestStorage04ShouldManageUniqueID() { - _ = os.Mkdir("/tmp/out", 0777) + dir := s.T().TempDir() output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "export", "--file=out.yml", "--config=/config/configuration.storage.yml"}) s.Assert().EqualError(err, "exit status 1") @@ -1014,13 +1030,14 @@ func (s *CLISuite) TestStorage04ShouldManageUniqueID() { s.Assert().EqualError(err, "exit status 1") s.Assert().Contains(output, "Error: error occurred writing to file 'out.yml': open out.yml: permission denied") - output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "export", "--file=/tmp/out/1.yml", "--config=/config/configuration.storage.yml"}) + out1 := filepath.Join(dir, "1.yml") + output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "export", "--file", out1, "--config=/config/configuration.storage.yml"}) s.Assert().NoError(err) - s.Assert().Contains(output, "Exported 1 User Opaque Identifiers to /tmp/out/1.yml") + s.Assert().Contains(output, fmt.Sprintf("Successfully exported %d User Opaque Identifiers as YAML to the '%s' file\n", 1, out1)) - output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "export", "--file=/tmp/out/1.yml", "--config=/config/configuration.storage.yml"}) + output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "export", "--file", out1, "--config=/config/configuration.storage.yml"}) s.Assert().EqualError(err, "exit status 1") - s.Assert().Contains(output, "Error: must specify a file that doesn't exist but '/tmp/out/1.yml' exists") + s.Assert().Contains(output, fmt.Sprintf("Error: must specify a file that doesn't exist but '%s' exists", out1)) output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "add", "john", "--service=openid", "--sector=''", "--identifier=1097c8f8-83f2-4506-8138-5f40e83a1285", "--config=/config/configuration.storage.yml"}) s.Assert().EqualError(err, "exit status 1") @@ -1046,7 +1063,7 @@ func (s *CLISuite) TestStorage04ShouldManageUniqueID() { s.Assert().EqualError(err, "exit status 1") s.Assert().Contains(output, "Error: the identifier provided 'asdmklasdm' is invalid as it must be a version 4 UUID but parsing it had an error: invalid UUID length: 10") - data, err := os.ReadFile("/tmp/out/1.yml") + data, err := os.ReadFile(out1) s.Assert().NoError(err) var export model.UserOpaqueIdentifiersExport @@ -1055,32 +1072,30 @@ func (s *CLISuite) TestStorage04ShouldManageUniqueID() { s.Require().Len(export.Identifiers, 1) - s.Assert().Equal(1, export.Identifiers[0].ID) s.Assert().Equal("1097c8f8-83f2-4506-8138-5f40e83a1285", export.Identifiers[0].Identifier.String()) s.Assert().Equal("john", export.Identifiers[0].Username) s.Assert().Equal("", export.Identifiers[0].SectorID) s.Assert().Equal("openid", export.Identifiers[0].Service) - output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "export", "--file=/tmp/out/2.yml", "--config=/config/configuration.storage.yml"}) + out2 := filepath.Join(dir, "2.yml") + output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "export", "--file", out2, "--config=/config/configuration.storage.yml"}) s.Assert().NoError(err) - s.Assert().Contains(output, "Exported 2 User Opaque Identifiers to /tmp/out/2.yml") + s.Assert().Contains(output, fmt.Sprintf("Successfully exported %d User Opaque Identifiers as YAML to the '%s' file\n", 2, out2)) export = model.UserOpaqueIdentifiersExport{} - data, err = os.ReadFile("/tmp/out/2.yml") + data, err = os.ReadFile(out2) s.Assert().NoError(err) s.Assert().NoError(yaml.Unmarshal(data, &export)) s.Require().Len(export.Identifiers, 2) - s.Assert().Equal(1, export.Identifiers[0].ID) s.Assert().Equal("1097c8f8-83f2-4506-8138-5f40e83a1285", export.Identifiers[0].Identifier.String()) s.Assert().Equal("john", export.Identifiers[0].Username) s.Assert().Equal("", export.Identifiers[0].SectorID) s.Assert().Equal("openid", export.Identifiers[0].Service) - s.Assert().Equal(2, export.Identifiers[1].ID) s.Assert().Equal("b0e17f48-933c-4cba-8509-ee9bfadf8ce5", export.Identifiers[1].Identifier.String()) s.Assert().Equal("john", export.Identifiers[1].Username) s.Assert().Equal("openidconnect.net", export.Identifiers[1].SectorID)