summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/content/en/configuration/second-factor/time-based-one-time-password.md19
-rw-r--r--docs/content/en/reference/cli/authelia/authelia.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_access-control.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_access-control_check-policy.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_build-info.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_certificate.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa_generate.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa_request.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519_generate.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519_request.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa_generate.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa_request.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_hash.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_argon2.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_bcrypt.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_pbkdf2.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_scrypt.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_hash_generate_sha2crypt.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_hash_validate.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_pair.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_pair_ecdsa.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_pair_ecdsa_generate.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_pair_ed25519.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_pair_ed25519_generate.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_pair_rsa.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_pair_rsa_generate.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_crypto_rand.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_encryption.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_encryption_change-key.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_encryption_check.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_migrate.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_migrate_down.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_migrate_history.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_migrate_list-down.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_migrate_list-up.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_migrate_up.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_schema-info.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_user.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers_add.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers_export.md6
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers_generate.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_user_identifiers_import.md15
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_user_totp.md5
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_user_totp_delete.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_user_totp_export.md21
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_user_totp_export_csv.md71
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_user_totp_export_png.md72
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_user_totp_export_uri.md70
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_user_totp_generate.md4
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_user_totp_import.md70
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn.md10
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn_delete.md10
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn_export.md72
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn_import.md71
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_storage_user_webauthn_list.md10
-rw-r--r--docs/content/en/reference/cli/authelia/authelia_validate-config.md4
-rw-r--r--internal/commands/const.go114
-rw-r--r--internal/commands/context.go21
-rw-r--r--internal/commands/crypto_hash.go8
-rw-r--r--internal/commands/storage.go188
-rw-r--r--internal/commands/storage_run.go852
-rw-r--r--internal/commands/util.go31
-rw-r--r--internal/model/totp_configuration.go61
-rw-r--r--internal/model/user_opaque_identifier.go2
-rw-r--r--internal/model/webauthn.go111
-rw-r--r--internal/suites/suite_cli_test.go65
73 files changed, 1630 insertions, 541 deletions
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 <filename> [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 <filename> [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 <filename> [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 --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.`
- 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`
+ 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"
@@ -472,16 +534,6 @@ const (
)
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 <filename>"
+
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,17 +236,312 @@ 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)
+// 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
+ )
+
+ if version, err = ctx.providers.StorageProvider.SchemaVersion(ctx); err != nil {
+ return err
+ }
+
+ if version <= 0 {
+ fmt.Println("No migration history is available for schemas that not version 1 or above.")
+ return
+ }
+
+ if migrations, err = ctx.providers.StorageProvider.SchemaMigrationHistory(ctx); err != nil {
+ return err
+ }
+
+ if len(migrations) == 0 {
+ return errors.New("no migration history found which may indicate a broken schema")
}
+ fmt.Printf("Migration History:\n\nID\tDate\t\t\t\tBefore\tAfter\tAuthelia Version\n")
+
+ for _, m := range migrations {
+ fmt.Printf("%d\t%s\t%d\t%d\t%s\n", m.ID, m.Applied.Format("2006-01-02 15:04:05 -0700"), m.Before, m.After, m.Version)
+ }
+
+ return nil
+}
+
+// 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
+ )
+
+ if up {
+ migrations, err = ctx.providers.StorageProvider.SchemaMigrationsUp(ctx, 0)
+ directionStr = "Up"
+ } else {
+ migrations, err = ctx.providers.StorageProvider.SchemaMigrationsDown(ctx, 0)
+ directionStr = "Down"
+ }
+
+ if err != nil && !errors.Is(err, storage.ErrNoAvailableMigrations) && !errors.Is(err, storage.ErrMigrateCurrentVersionSameAsTarget) {
+ return err
+ }
+
+ if len(migrations) == 0 {
+ fmt.Printf("Storage Schema Migration List (%s)\n\nNo Migrations Available\n", directionStr)
+ } else {
+ fmt.Printf("Storage Schema Migration List (%s)\n\nVersion\t\tDescription\n", directionStr)
+
+ for _, migration := range migrations {
+ fmt.Printf("%d\t\t%s\n", migration.Version, migration.Name)
+ }
+ }
+
+ return nil
+ }
+}
+
+// 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) {
+ defer func() {
+ _ = ctx.providers.StorageProvider.Close()
+ }()
+
+ var (
+ target int
+ )
+
+ if target, err = cmd.Flags().GetInt(cmdFlagNameTarget); err != nil {
+ return err
+ }
+
+ switch {
+ case up:
+ switch cmd.Flags().Changed(cmdFlagNameTarget) {
+ case true:
+ return ctx.providers.StorageProvider.SchemaMigrate(ctx, true, target)
+ default:
+ return ctx.providers.StorageProvider.SchemaMigrate(ctx, true, storage.SchemaLatest)
+ }
+ default:
+ if !cmd.Flags().Changed(cmdFlagNameTarget) {
+ return errors.New("you must set a target version")
+ }
+
+ var confirmed bool
+
+ if confirmed, err = termReadConfirmation(cmd.Flags(), cmdFlagNameDestroyData, "Schema Down Migrations may DESTROY data, type 'DESTROY' and press return to continue: ", "DESTROY"); err != nil {
+ return err
+ }
+
+ if !confirmed {
+ return errors.New("cancelling down migration due to user not accepting data destruction")
+ }
+
+ return ctx.providers.StorageProvider.SchemaMigrate(ctx, false, target)
+ }
+ }
+}
+
+// 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()
}()
- if err = ctx.CheckSchemaVersion(); err != nil {
+ var (
+ upgradeStr, tablesStr string
+
+ tables []string
+ version, latest int
+ )
+
+ if version, err = ctx.providers.StorageProvider.SchemaVersion(ctx); err != nil && err.Error() != "unknown schema state" {
+ return err
+ }
+
+ if tables, err = ctx.providers.StorageProvider.SchemaTables(ctx); err != nil {
+ return err
+ }
+
+ if len(tables) == 0 {
+ tablesStr = "N/A"
+ } else {
+ tablesStr = strings.Join(tables, ", ")
+ }
+
+ if latest, err = ctx.providers.StorageProvider.SchemaLatestVersion(); err != nil {
+ return err
+ }
+
+ if latest > version {
+ upgradeStr = fmt.Sprintf("yes - version %d", latest)
+ } else {
+ upgradeStr = "no"
+ }
+
+ var (
+ encryption string
+ result storage.EncryptionValidationResult
+ )
+
+ switch result, err = ctx.providers.StorageProvider.SchemaEncryptionCheckKey(ctx, false); {
+ case err != nil:
+ if errors.Is(err, storage.ErrSchemaEncryptionVersionUnsupported) {
+ encryption = "unsupported (schema version)"
+ } else {
+ encryption = invalid
+ }
+ case !result.Success():
+ encryption = invalid
+ default:
+ encryption = "valid"
+ }
+
+ fmt.Printf("Schema Version: %s\nSchema Upgrade Available: %s\nSchema Tables: %s\nSchema Encryption Key: %s\n", storage.SchemaVersionToString(version), upgradeStr, tablesStr, encryption)
+
+ return nil
+}
+
+func (ctx *CmdCtx) StorageUserWebauthnExportRunE(cmd *cobra.Command, args []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 (
+ 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)
}
@@ -272,13 +568,13 @@ func (ctx *CmdCtx) StorageWebauthnListRunE(cmd *cobra.Command, args []string) (e
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) {
+// 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.CheckSchemaVersion(); err != nil {
+ if err = ctx.CheckSchema(); err != nil {
return storageWrapCheckSchemaErr(err)
}
@@ -312,13 +608,13 @@ func (ctx *CmdCtx) StorageWebauthnListAllRunE(_ *cobra.Command, _ []string) (err
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) {
+// 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.CheckSchemaVersion(); err != nil {
+ if err = ctx.CheckSchema(); err != nil {
return storageWrapCheckSchemaErr(err)
}
@@ -333,33 +629,37 @@ func (ctx *CmdCtx) StorageWebauthnDeleteRunE(cmd *cobra.Command, args []string)
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)
+ return fmt.Errorf("failed to delete webauthn device with kid '%s': %w", kid, err)
}
- fmt.Printf("Deleted WebAuthn device with kid '%s'", kid)
+ 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)
+ 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)
+ 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)
+ 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)
+ fmt.Printf("Successfully deleted Webauthn device with description '%s' for user '%s'\n", description, user)
}
}
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) {
+// 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
@@ -368,11 +668,7 @@ func (ctx *CmdCtx) StorageTOTPGenerateRunE(cmd *cobra.Command, args []string) (e
img image.Image
)
- defer func() {
- _ = ctx.providers.StorageProvider.Close()
- }()
-
- if err = ctx.CheckSchemaVersion(); err != nil {
+ if err = ctx.CheckSchema(); err != nil {
return storageWrapCheckSchemaErr(err)
}
@@ -420,315 +716,357 @@ func (ctx *CmdCtx) StorageTOTPGenerateRunE(cmd *cobra.Command, args []string) (e
return err
}
- fmt.Printf("Generated TOTP configuration for user '%s' with URI '%s'%s\n", args[0], c.URI(), extraInfo)
+ fmt.Printf("Successfully 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]
-
+// 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()
}()
- if err = ctx.CheckSchemaVersion(); err != nil {
+ 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("can't delete configuration for user '%s': %+v", user, err)
+ 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("can't delete configuration for user '%s': %+v", user, err)
+ return fmt.Errorf("failed to delete TOTP configuration for user '%s': %+v", user, err)
}
- fmt.Printf("Deleted TOTP configuration for user '%s'.", user)
+ fmt.Printf("Successfully deleted TOTP configuration for user '%s'\n", 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
- )
+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.CheckSchemaVersion(); err != nil {
+ if err = ctx.CheckSchema(); err != nil {
return storageWrapCheckSchemaErr(err)
}
- if format, dir, err = flagsGetTOTPExportOptions(cmd.Flags()); err != nil {
+ 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 configurations, err = ctx.providers.StorageProvider.LoadTOTPConfigurations(ctx, limit, page); err != nil {
+ if configs, 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")
- }
+ export.TOTPConfigurations = append(export.TOTPConfigurations, configs...)
- 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)))
+ l := len(configs)
- if img, err = c.Image(256, 256); err != nil {
- _ = file.Close()
+ count += l
- return err
- }
-
- if err = png.Encode(file, img); err != nil {
- _ = file.Close()
-
- return err
- }
-
- _ = file.Close()
- }
- }
-
- if len(configurations) < limit {
+ if l < limit {
break
}
}
- if format == storageTOTPExportFormatPNG {
- fmt.Printf("Exported TOTP QR codes in PNG format in the '%s' directory\n", dir)
+ 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
}
-// StorageMigrateHistoryRunE is the RunE for the authelia storage migrate history command.
-func (ctx *CmdCtx) StorageMigrateHistoryRunE(_ *cobra.Command, _ []string) (err error) {
- var (
- version int
- migrations []model.Migration
- )
-
+func (ctx *CmdCtx) StorageUserTOTPImportRunE(_ *cobra.Command, args []string) (err error) {
defer func() {
_ = ctx.providers.StorageProvider.Close()
}()
- if version, err = ctx.providers.StorageProvider.SchemaVersion(ctx); err != nil {
- return err
+ 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 version <= 0 {
- fmt.Println("No migration history is available for schemas that not version 1 or above.")
- return
+ if stat.IsDir() {
+ return fmt.Errorf("must specify a filename that exists but '%s' is a directory", filename)
}
- if migrations, err = ctx.providers.StorageProvider.SchemaMigrationHistory(ctx); err != nil {
+ if data, err = os.ReadFile(filename); err != nil {
return err
}
- if len(migrations) == 0 {
- return errors.New("no migration history found which may indicate a broken schema")
+ export := &model.TOTPConfigurationExport{}
+
+ if err = yaml.Unmarshal(data, export); err != nil {
+ return err
}
- fmt.Printf("Migration History:\n\nID\tDate\t\t\t\tBefore\tAfter\tAuthelia Version\n")
+ if len(export.TOTPConfigurations) == 0 {
+ return fmt.Errorf("can't import a YAML file without TOTP configuration data")
+ }
- for _, m := range migrations {
- fmt.Printf("%d\t%s\t%d\t%d\t%s\n", m.ID, m.Applied.Format("2006-01-02 15:04:05 -0700"), m.Before, m.After, m.Version)
+ 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
}
-// 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) {
- var (
- migrations []model.SchemaMigration
- directionStr string
- )
+func (ctx *CmdCtx) StorageUserTOTPExportURIRunE(_ *cobra.Command, _ []string) (err error) {
+ defer func() {
+ _ = ctx.providers.StorageProvider.Close()
+ }()
- defer func() {
- _ = ctx.providers.StorageProvider.Close()
- }()
+ var (
+ configs []model.TOTPConfiguration
+ )
- if up {
- migrations, err = ctx.providers.StorageProvider.SchemaMigrationsUp(ctx, 0)
- directionStr = "Up"
- } else {
- migrations, err = ctx.providers.StorageProvider.SchemaMigrationsDown(ctx, 0)
- directionStr = "Down"
- }
+ if err = ctx.CheckSchema(); err != nil {
+ return storageWrapCheckSchemaErr(err)
+ }
- if err != nil && !errors.Is(err, storage.ErrNoAvailableMigrations) && !errors.Is(err, storage.ErrMigrateCurrentVersionSameAsTarget) {
+ 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
}
- if len(migrations) == 0 {
- fmt.Printf("Storage Schema Migration List (%s)\n\nNo Migrations Available\n", directionStr)
- } else {
- fmt.Printf("Storage Schema Migration List (%s)\n\nVersion\t\tDescription\n", directionStr)
-
- for _, migration := range migrations {
- fmt.Printf("%d\t\t%s\n", migration.Version, migration.Name)
- }
+ for _, c := range configs {
+ buf.WriteString(fmt.Sprintf("%s\n", c.URI()))
}
- return nil
+ 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
}
-// 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
- )
+func (ctx *CmdCtx) StorageUserTOTPExportCSVRunE(cmd *cobra.Command, _ []string) (err error) {
+ defer func() {
+ _ = ctx.providers.StorageProvider.Close()
+ }()
- defer func() {
- _ = ctx.providers.StorageProvider.Close()
- }()
+ var (
+ filename string
+ configs []model.TOTPConfiguration
+ buf *bytes.Buffer
+ )
- if target, err = cmd.Flags().GetInt(cmdFlagNameTarget); err != nil {
+ 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
}
- switch {
- case up:
- switch cmd.Flags().Changed(cmdFlagNameTarget) {
- case true:
- return ctx.providers.StorageProvider.SchemaMigrate(ctx, true, target)
- default:
- return ctx.providers.StorageProvider.SchemaMigrate(ctx, true, storage.SchemaLatest)
- }
- default:
- if !cmd.Flags().Changed(cmdFlagNameTarget) {
- return errors.New("you must set a target version")
- }
-
- var confirmed bool
+ 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)))
+ }
- if confirmed, err = termReadConfirmation(cmd.Flags(), cmdFlagNameDestroyData, "Schema Down Migrations may DESTROY data, type 'DESTROY' and press return to continue: ", "DESTROY"); err != nil {
- return err
- }
+ l := len(configs)
- if !confirmed {
- return errors.New("cancelling down migration due to user not accepting data destruction")
- }
+ count += l
- return ctx.providers.StorageProvider.SchemaMigrate(ctx, false, target)
+ if l < limit {
+ break
}
}
-}
-// StorageSchemaInfoRunE is the RunE for the authelia storage schema info command.
-func (ctx *CmdCtx) StorageSchemaInfoRunE(_ *cobra.Command, _ []string) (err error) {
- var (
- upgradeStr, tablesStr string
+ if err = os.WriteFile(filename, buf.Bytes(), 0600); err != nil {
+ return err
+ }
- tables []string
- version, latest int
- )
+ 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()
}()
- if version, err = ctx.providers.StorageProvider.SchemaVersion(ctx); err != nil && err.Error() != "unknown schema state" {
- return err
+ var (
+ dir string
+ configs []model.TOTPConfiguration
+ img image.Image
+ )
+
+ if err = ctx.CheckSchema(); err != nil {
+ return storageWrapCheckSchemaErr(err)
}
- if tables, err = ctx.providers.StorageProvider.SchemaTables(ctx); err != nil {
+ if dir, err = cmd.Flags().GetString(cmdFlagNameDirectory); err != nil {
return err
}
- if len(tables) == 0 {
- tablesStr = "N/A"
- } else {
- tablesStr = strings.Join(tables, ", ")
+ if dir == "" {
+ dir = utils.RandomString(8, utils.CharSetAlphaNumeric, false)
}
- if latest, err = ctx.providers.StorageProvider.SchemaLatestVersion(); err != nil {
- return err
+ if _, err = os.Stat(dir); !os.IsNotExist(err) {
+ return errors.New("output directory must not exist")
}
- if latest > version {
- upgradeStr = fmt.Sprintf("yes - version %d", latest)
- } else {
- upgradeStr = "no"
+ if err = os.MkdirAll(dir, 0700); err != nil {
+ return err
}
- var (
- encryption string
- result storage.EncryptionValidationResult
- )
+ limit := 10
+ count := 0
- switch result, err = ctx.providers.StorageProvider.SchemaEncryptionCheckKey(ctx, false); {
- case err != nil:
- if errors.Is(err, storage.ErrSchemaEncryptionVersionUnsupported) {
- encryption = "unsupported (schema version)"
- } else {
- encryption = invalid
+ 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
}
- case !result.Success():
- encryption = invalid
- default:
- encryption = "valid"
}
- fmt.Printf("Schema Version: %s\nSchema Upgrade Available: %s\nSchema Tables: %s\nSchema Encryption Key: %s\n", storage.SchemaVersionToString(version), upgradeStr, tablesStr, encryption)
+ 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 (
- file string
+ filename string
)
- if file, err = cmd.Flags().GetString(cmdFlagNameFile); err != nil {
+ if filename, err = cmd.Flags().GetString(cmdFlagNameFile); err != nil {
return err
}
- _, err = os.Stat(file)
-
- switch {
+ switch _, err = os.Stat(filename); {
case err == nil:
- return fmt.Errorf("must specify a file that doesn't exist but '%s' exists", file)
+ 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", file, err)
+ return fmt.Errorf("error occurred opening '%s': %w", filename, err)
}
- defer func() {
- _ = ctx.providers.StorageProvider.Close()
- }()
-
- if err = ctx.CheckSchemaVersion(); err != nil {
- return storageWrapCheckSchemaErr(err)
+ export := &model.UserOpaqueIdentifiersExport{
+ Identifiers: nil,
}
- var (
- export model.UserOpaqueIdentifiersExport
-
- data []byte
- )
-
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) {
+func (ctx *CmdCtx) StorageUserIdentifiersImportRunE(cmd *cobra.Command, args []string) (err error) {
+ defer func() {
+ _ = ctx.providers.StorageProvider.Close()
+ }()
+
var (
- file string
+ filename string
+
stat os.FileInfo
+ data []byte
)
- if file, err = cmd.Flags().GetString(cmdFlagNameFile); err != nil {
- return err
- }
+ filename = args[0]
- 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, 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", file)
+ return fmt.Errorf("must specify a file that exists but '%s' is a directory", filename)
}
- var (
- data []byte
- export model.UserOpaqueIdentifiersExport
- )
-
- if data, err = os.ReadFile(file); err != nil {
+ if data, err = os.ReadFile(filename); err != nil {
return err
}
- if err = yaml.Unmarshal(data, &export); err != nil {
+ 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 file with no data")
+ return fmt.Errorf("can't import a YAML file without User Opaque Identifiers data")
}
- defer func() {
- _ = ctx.providers.StorageProvider.Close()
- }()
-
- if err = ctx.CheckSchemaVersion(); err != nil {
+ 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)