summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BREAKING.md10
-rw-r--r--README.md3
-rwxr-xr-xcmd/authelia-scripts/authelia-scripts2
-rwxr-xr-xcmd/authelia-scripts/main.go2
-rw-r--r--cmd/authelia/main.go2
-rw-r--r--internal/commands/migration.go80
-rw-r--r--internal/commands/migration_local.go153
-rw-r--r--internal/commands/migration_mongo.go186
8 files changed, 5 insertions, 433 deletions
diff --git a/BREAKING.md b/BREAKING.md
index bd37586b1..5686926c3 100644
--- a/BREAKING.md
+++ b/BREAKING.md
@@ -54,16 +54,10 @@ supported by Authelia v4.
Example of usage:
```
# Migrate a local database into the targeted database defined in config-v4.yml with Docker
-docker run --rm -v /path/to/config-v4.yml:/config.yml -v /old/db/path:/db authelia/authelia authelia migrate local --config=/config.yml --db-path=/db
+docker run --rm -v /path/to/config-v4.yml:/config.yml -v /old/db/path:/db authelia/authelia:4.14.2 authelia migrate local --config=/config.yml --db-path=/db
# Migrate a mongo database into the targeted database defined in config-v4.yml with Docker
-docker run --rm -v /path/to/config-v4.yml:/config.yml authelia/authelia authelia migrate mongo --config=/config.yml --url=mongodb://myuser:mypassword@mymongo:27017 --database=authelia
-
-# Migrate a local database into the targeted database defined in config-v4.yml
-authelia-scripts migrate local --config=/path/to/config-v4.yml --db-path=/old/db/path
-
-# Migrate a mongo database into the targeted database defined in config-v4.yml
-authelia-scripts migrate mongo --config=/path/to/config-v4.yml --url=mongodb://myuser:mypassword@mymongo:27017 --database=authelia
+docker run --rm -v /path/to/config-v4.yml:/config.yml authelia/authelia:4.14.2 authelia migrate mongo --config=/config.yml --url=mongodb://myuser:mypassword@mymongo:27017 --database=authelia
```
Those commands migrate TOTP secrets, U2F devices, authentication traces and user preferences so
diff --git a/README.md b/README.md
index 5efa3062b..ab052e3cf 100644
--- a/README.md
+++ b/README.md
@@ -28,9 +28,6 @@ The architecture is shown in the diagram below.
<img src="./docs/images/archi.png"/>
</p>
-**BREAKING NEWS: Authelia v4 has been released!
-Please read BREAKING.md if you want to migrate from v3 to v4. Otherwise, start fresh in v4 and enjoy!**
-
**Authelia** can be installed as a standalone service from the [AUR](https://aur.archlinux.org/packages/authelia/), using a [Static binary](https://github.com/authelia/authelia/releases/latest), [Docker]
or can also be deployed easily on [Kubernetes] leveraging ingress controllers and ingress configuration.
diff --git a/cmd/authelia-scripts/authelia-scripts b/cmd/authelia-scripts/authelia-scripts
index 2bf8bb3ad..d9f522641 100755
--- a/cmd/authelia-scripts/authelia-scripts
+++ b/cmd/authelia-scripts/authelia-scripts
@@ -1,3 +1,3 @@
#!/bin/bash
-go run -tags migration cmd/authelia-scripts/*.go $* \ No newline at end of file
+go run cmd/authelia-scripts/*.go $* \ No newline at end of file
diff --git a/cmd/authelia-scripts/main.go b/cmd/authelia-scripts/main.go
index 19171fc31..1d50fd03b 100755
--- a/cmd/authelia-scripts/main.go
+++ b/cmd/authelia-scripts/main.go
@@ -130,7 +130,7 @@ func main() {
cobraCommands = append(cobraCommands, command)
}
- cobraCommands = append(cobraCommands, commands.HashPasswordCmd, commands.MigrateCmd)
+ cobraCommands = append(cobraCommands, commands.HashPasswordCmd)
rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "info", "Set the log level for the command")
rootCmd.AddCommand(cobraCommands...)
diff --git a/cmd/authelia/main.go b/cmd/authelia/main.go
index 0b02b5edd..9b93cc38f 100644
--- a/cmd/authelia/main.go
+++ b/cmd/authelia/main.go
@@ -130,7 +130,7 @@ func main() {
},
}
- rootCmd.AddCommand(versionCmd, commands.MigrateCmd, commands.HashPasswordCmd)
+ rootCmd.AddCommand(versionCmd, commands.HashPasswordCmd)
rootCmd.AddCommand(commands.CertificatesCmd)
if err := rootCmd.Execute(); err != nil {
log.Fatal(err)
diff --git a/internal/commands/migration.go b/internal/commands/migration.go
deleted file mode 100644
index 7f610be4f..000000000
--- a/internal/commands/migration.go
+++ /dev/null
@@ -1,80 +0,0 @@
-package commands
-
-import (
- "encoding/base64"
- "strings"
-
- "github.com/spf13/cobra"
-
- "github.com/authelia/authelia/internal/configuration"
- "github.com/authelia/authelia/internal/storage"
-)
-
-// MigrateCmd migration helper command.
-var MigrateCmd *cobra.Command
-
-func init() {
- MigrateCmd = &cobra.Command{
- Use: "migrate",
- Short: "helper function to migrate from v3 to v4",
- }
- MigrateCmd.AddCommand(MigrateLocalCmd, MigrateMongoCmd)
-}
-
-// TOTPSecretsV3 one entry of TOTP secrets in v3.
-type TOTPSecretsV3 struct {
- UserID string `json:"userId"`
- Secret struct {
- Base32 string `json:"base32"`
- } `json:"secret"`
-}
-
-// U2FDeviceHandleV3 one entry of U2F device handle in v3.
-type U2FDeviceHandleV3 struct {
- UserID string `json:"userId"`
- Registration struct {
- KeyHandle string `json:"keyHandle"`
- PublicKey string `json:"publicKey"`
- } `json:"registration"`
-}
-
-// PreferencesV3 one entry of preferences in v3.
-type PreferencesV3 struct {
- UserID string `json:"userId"`
- Method string `json:"method"`
-}
-
-// AuthenticationTraceV3 one authentication trace in v3.
-type AuthenticationTraceV3 struct {
- UserID string `json:"userId"`
- Successful bool `json:"isAuthenticationSuccessful"`
- Date struct {
- Date int64 `json:"$$date"`
- } `json:"date"`
-}
-
-func decodeWebsafeBase64(s string) ([]byte, error) {
- s = strings.ReplaceAll(s, "_", "/")
- s = strings.ReplaceAll(s, "-", "+")
-
- for len(s)%4 != 0 {
- s += "="
- }
-
- return base64.StdEncoding.DecodeString(s)
-}
-
-func createDBProvider(configurationPath string) storage.Provider {
- config, _ := configuration.Read(configurationPath)
-
- var dbProvider storage.Provider
- if config.Storage.Local != nil {
- dbProvider = storage.NewSQLiteProvider(config.Storage.Local.Path)
- } else if config.Storage.MySQL != nil {
- dbProvider = storage.NewMySQLProvider(*config.Storage.MySQL)
- } else if config.Storage.PostgreSQL != nil {
- dbProvider = storage.NewPostgreSQLProvider(*config.Storage.PostgreSQL)
- }
-
- return dbProvider
-}
diff --git a/internal/commands/migration_local.go b/internal/commands/migration_local.go
deleted file mode 100644
index a6e31ea42..000000000
--- a/internal/commands/migration_local.go
+++ /dev/null
@@ -1,153 +0,0 @@
-package commands
-
-import (
- "bufio"
- "encoding/json"
- "log"
- "os"
- "path"
- "time"
-
- "github.com/spf13/cobra"
-
- "github.com/authelia/authelia/internal/models"
- "github.com/authelia/authelia/internal/storage"
-)
-
-var configurationPath string
-var localDatabasePath string
-
-// MigrateLocalCmd migration command.
-var MigrateLocalCmd = &cobra.Command{
- Use: "localdb",
- Short: "Migrate data from v3 local database into database configured in v4 configuration file",
- Run: migrateLocal,
-}
-
-func init() {
- MigrateLocalCmd.PersistentFlags().StringVarP(&localDatabasePath, "db-path", "p", "", "The path to the v3 local database")
- MigrateLocalCmd.MarkPersistentFlagRequired("db-path") //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
-
- MigrateLocalCmd.PersistentFlags().StringVarP(&configurationPath, "config", "c", "", "The configuration file of Authelia v4")
- MigrateLocalCmd.MarkPersistentFlagRequired("config") //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
-}
-
-// migrateLocal data from v3 to v4.
-func migrateLocal(cmd *cobra.Command, args []string) {
- dbProvider := createDBProvider(configurationPath)
-
- migrateLocalTOTPSecret(dbProvider)
- migrateLocalU2FSecret(dbProvider)
- migrateLocalPreferences(dbProvider)
- migrateLocalAuthenticationTraces(dbProvider)
- // We don't need to migrate identity tokens
-
- log.Println("Migration done!")
-}
-
-func migrateLocalTOTPSecret(dbProvider storage.Provider) {
- file, err := os.Open(path.Join(localDatabasePath, "totp_secrets"))
- if err != nil {
- log.Fatal(err)
- }
- defer file.Close()
- scanner := bufio.NewScanner(file)
- scanner.Split(bufio.ScanLines)
-
- for scanner.Scan() {
- data := scanner.Text()
-
- entry := TOTPSecretsV3{}
- json.Unmarshal([]byte(data), &entry) //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
- err := dbProvider.SaveTOTPSecret(entry.UserID, entry.Secret.Base32)
-
- if err != nil {
- log.Fatal(err)
- }
- }
-}
-
-func migrateLocalU2FSecret(dbProvider storage.Provider) {
- file, err := os.Open(path.Join(localDatabasePath, "u2f_registrations"))
- if err != nil {
- log.Fatal(err)
- }
- defer file.Close()
- scanner := bufio.NewScanner(file)
- scanner.Split(bufio.ScanLines)
-
- for scanner.Scan() {
- data := scanner.Text()
-
- entry := U2FDeviceHandleV3{}
- json.Unmarshal([]byte(data), &entry) //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
-
- kH, err := decodeWebsafeBase64(entry.Registration.KeyHandle)
-
- if err != nil {
- log.Fatal(err)
- }
-
- pK, err := decodeWebsafeBase64(entry.Registration.PublicKey)
-
- if err != nil {
- log.Fatal(err)
- }
-
- err = dbProvider.SaveU2FDeviceHandle(entry.UserID, kH, pK)
-
- if err != nil {
- log.Fatal(err)
- }
- }
-}
-
-func migrateLocalPreferences(dbProvider storage.Provider) {
- file, err := os.Open(path.Join(localDatabasePath, "prefered_2fa_method")) //nolint:misspell
- if err != nil {
- log.Fatal(err)
- }
- defer file.Close()
- scanner := bufio.NewScanner(file)
- scanner.Split(bufio.ScanLines)
-
- for scanner.Scan() {
- data := scanner.Text()
-
- entry := PreferencesV3{}
- json.Unmarshal([]byte(data), &entry) //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
- err := dbProvider.SavePreferred2FAMethod(entry.UserID, entry.Method)
-
- if err != nil {
- log.Fatal(err)
- }
- }
-}
-
-func migrateLocalAuthenticationTraces(dbProvider storage.Provider) {
- file, err := os.Open(path.Join(localDatabasePath, "authentication_traces"))
- if err != nil {
- log.Fatal(err)
- }
- defer file.Close()
- scanner := bufio.NewScanner(file)
- scanner.Split(bufio.ScanLines)
-
- for scanner.Scan() {
- data := scanner.Text()
-
- entry := AuthenticationTraceV3{}
- json.Unmarshal([]byte(data), &entry) //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
-
- attempt := models.AuthenticationAttempt{
- Username: entry.UserID,
- Successful: entry.Successful,
- Time: time.Unix(entry.Date.Date/1000.0, 0),
- }
- err := dbProvider.AppendAuthenticationLog(attempt)
-
- if err != nil {
- log.Fatal(err)
- }
- }
-}
diff --git a/internal/commands/migration_mongo.go b/internal/commands/migration_mongo.go
deleted file mode 100644
index dd6dd865b..000000000
--- a/internal/commands/migration_mongo.go
+++ /dev/null
@@ -1,186 +0,0 @@
-package commands
-
-import (
- "context"
- "log"
- "time"
-
- "github.com/spf13/cobra"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/mongo"
- "go.mongodb.org/mongo-driver/mongo/options"
-
- "github.com/authelia/authelia/internal/models"
- "github.com/authelia/authelia/internal/storage"
-)
-
-var mongoURL string
-var mongoDatabase string
-
-// MigrateMongoCmd migration command.
-var MigrateMongoCmd = &cobra.Command{
- Use: "mongo",
- Short: "Migrate data from v3 mongo database into database configured in v4 configuration file",
- Run: migrateMongo,
-}
-
-func init() {
- MigrateMongoCmd.PersistentFlags().StringVar(&mongoURL, "url", "", "The address to the mongo server")
- MigrateMongoCmd.MarkPersistentFlagRequired("url") //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
-
- MigrateMongoCmd.PersistentFlags().StringVar(&mongoDatabase, "database", "", "The mongo database")
- MigrateMongoCmd.MarkPersistentFlagRequired("database") //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
-
- MigrateMongoCmd.PersistentFlags().StringVarP(&configurationPath, "config", "c", "", "The configuration file of Authelia v4")
- MigrateMongoCmd.MarkPersistentFlagRequired("config") //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
-}
-
-func migrateMongo(cmd *cobra.Command, args []string) {
- dbProvider := createDBProvider(configurationPath)
- client, err := mongo.NewClient(options.Client().ApplyURI(mongoURL))
-
- if err != nil {
- log.Fatal(err)
- }
-
- err = client.Connect(context.Background())
-
- if err != nil {
- log.Fatal(err)
- }
-
- db := client.Database(mongoDatabase)
-
- migrateMongoU2FDevices(db, dbProvider)
- migrateMongoTOTPDevices(db, dbProvider)
- migrateMongoPreferences(db, dbProvider)
- migrateMongoAuthenticationTraces(db, dbProvider)
-
- log.Println("Migration done!")
-}
-
-func migrateMongoU2FDevices(db *mongo.Database, dbProvider storage.Provider) {
- u2fCollection := db.Collection("u2f_registrations")
-
- cur, err := u2fCollection.Find(context.Background(), bson.D{})
- if err != nil {
- log.Fatal(err)
- }
- defer cur.Close(context.Background())
-
- for cur.Next(context.Background()) {
- var result U2FDeviceHandleV3
- err := cur.Decode(&result)
- if err != nil {
- log.Fatal(err)
- }
-
- kH, err := decodeWebsafeBase64(result.Registration.KeyHandle)
-
- if err != nil {
- log.Fatal(err)
- }
-
- pK, err := decodeWebsafeBase64(result.Registration.PublicKey)
-
- if err != nil {
- log.Fatal(err)
- }
-
- err = dbProvider.SaveU2FDeviceHandle(result.UserID, kH, pK)
-
- if err != nil {
- log.Fatal(err)
- }
- }
- if err := cur.Err(); err != nil {
- log.Fatal(err)
- }
-}
-
-func migrateMongoTOTPDevices(db *mongo.Database, dbProvider storage.Provider) {
- u2fCollection := db.Collection("totp_secrets")
-
- cur, err := u2fCollection.Find(context.Background(), bson.D{})
- if err != nil {
- log.Fatal(err)
- }
- defer cur.Close(context.Background())
-
- for cur.Next(context.Background()) {
- var result TOTPSecretsV3
- err := cur.Decode(&result)
- if err != nil {
- log.Fatal(err)
- }
-
- err = dbProvider.SaveTOTPSecret(result.UserID, result.Secret.Base32)
-
- if err != nil {
- log.Fatal(err)
- }
- }
- if err := cur.Err(); err != nil {
- log.Fatal(err)
- }
-}
-
-func migrateMongoPreferences(db *mongo.Database, dbProvider storage.Provider) {
- u2fCollection := db.Collection("prefered_2fa_method") //nolint:misspell
-
- cur, err := u2fCollection.Find(context.Background(), bson.D{})
- if err != nil {
- log.Fatal(err)
- }
- defer cur.Close(context.Background())
-
- for cur.Next(context.Background()) {
- var result PreferencesV3
- err := cur.Decode(&result)
- if err != nil {
- log.Fatal(err)
- }
-
- err = dbProvider.SavePreferred2FAMethod(result.UserID, result.Method)
-
- if err != nil {
- log.Fatal(err)
- }
- }
- if err := cur.Err(); err != nil {
- log.Fatal(err)
- }
-}
-
-func migrateMongoAuthenticationTraces(db *mongo.Database, dbProvider storage.Provider) {
- u2fCollection := db.Collection("authentication_traces")
-
- cur, err := u2fCollection.Find(context.Background(), bson.D{})
- if err != nil {
- log.Fatal(err)
- }
- defer cur.Close(context.Background())
-
- for cur.Next(context.Background()) {
- var result AuthenticationTraceV3
- err := cur.Decode(&result)
- if err != nil {
- log.Fatal(err)
- }
-
- attempt := models.AuthenticationAttempt{
- Username: result.UserID,
- Successful: result.Successful,
- Time: time.Unix(result.Date.Date/1000.0, 0),
- }
-
- err = dbProvider.AppendAuthenticationLog(attempt)
-
- if err != nil {
- log.Fatal(err)
- }
- }
- if err := cur.Err(); err != nil {
- log.Fatal(err)
- }
-}