package authelia import ( "fmt" "strings" "time" "git.readonly.ch/bouzoure/pop-camarades/helpers" "git.readonly.ch/bouzoure/pop-camarades/models" "github.com/alexedwards/argon2id" "github.com/charmbracelet/log" "github.com/sethvargo/go-password/password" ) func SyncUsers() error { db, err := helpers.GetDatabase() if err != nil { return err } var accounts []models.PersonAccount result := db.Joins("Person").Find( &accounts, "account_created IS NULL OR update_needed = ?", true, ) if result.Error != nil { return result.Error } // If no accounts to create or update -> skip sync if result.RowsAffected <= 0 { return nil } users, err := ReadDatabase() if err != nil { return err } for _, account := range accounts { accountExists := false for uuid, user := range users.Users { if uuid == account.UUID.String() { accountExists = true // Update account user.Disabled = !account.Enabled user.Groups = strings.Split(account.Groups, "|||") user.GivenName = account.Person.FirstName user.FamilyName = account.Person.LastName user.DisplayName = fmt.Sprintf("%s %s", account.Person.FirstName, account.Person.LastName, ) user.Email = account.Person.Email // Overwrite old user struct users.Users[uuid] = user // Exit loop early break } } if !accountExists { // Generate random password randomPassword, err := password.Generate(64, 10, 10, false, false) if err != nil { log.Error(err) continue } argonParams := argon2id.Params{ Iterations: 3, Memory: 65536, Parallelism: 4, KeyLength: 32, SaltLength: 16, } hashedPassword, err := argon2id.CreateHash(randomPassword, &argonParams) if err != nil { log.Error(err) continue } // Create account user := AutheliaUser{ Disabled: !account.Enabled, Groups: strings.Split(account.Groups, "|||"), GivenName: account.Person.FirstName, FamilyName: account.Person.LastName, DisplayName: fmt.Sprintf("%s %s", account.Person.FirstName, account.Person.LastName, ), Email: account.Person.Email, Password: hashedPassword, } // Insert new user users.Users[account.UUID.String()] = user } account.UpdateNeeded = false if !account.AccountCreated.Valid { err := SendWelcomeMail(account.Person) if err != nil { log.Error(err) } account.AccountCreated.Scan(time.Now()) } db.Save(&account) } return WriteDatabase(users) }