package createuser import ( "errors" "fmt" "net/http" "slices" "strings" "git.artlef.fr/PersonalLibraryManager/internal/appcontext" "git.artlef.fr/PersonalLibraryManager/internal/i18nresource" "git.artlef.fr/PersonalLibraryManager/internal/model" "git.artlef.fr/PersonalLibraryManager/internal/myvalidator" "golang.org/x/crypto/bcrypt" "gorm.io/gorm" ) // this method will hash the password func CreateUser(ac appcontext.AppContext, username string, password string) error { hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { return err } return CreateUserWithHashedPassword(ac, username, string(hashedPassword)) } // only call this method with hashed password func CreateUserWithHashedPassword(ac appcontext.AppContext, username string, hashedPassword string) error { var existingUser model.User err := ac.Db.Where("name = ?", username).First(&existingUser).Error if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { return err } if err == nil { return myvalidator.HttpError{ StatusCode: http.StatusInternalServerError, Err: errors.New(i18nresource.GetTranslatedMessage(&ac, "UserAlreadyExists")), } } user := model.User{ Name: username, Password: hashedPassword, } return ac.Db.Model(&model.User{}).Save(&user).Error } func CreateDefaultUsers(ac appcontext.AppContext) error { usersPasswordMap := make(map[string]string) var usernames []string for _, s := range ac.Config.AddUser { splittedString := strings.Split(s, ":") if len(splittedString) < 2 { return fmt.Errorf(i18nresource.GetTranslatedMessage(&ac, "ErrorWhenCreatingUserFromStr"), s) } usernames = append(usernames, splittedString[0]) usersPasswordMap[splittedString[0]] = splittedString[1] } if !slices.Contains(usernames, ac.Config.DemoUsername) { usernames = append(usernames, ac.Config.DemoUsername) usersPasswordMap[ac.Config.DemoUsername] = "" } var existingUsers []model.User err := ac.Db.Where("name IN ?", usernames).Find(&existingUsers).Error if err != nil { return err } for _, username := range usernames { if isInExistingUsers(username, existingUsers) { continue } err = CreateUserWithHashedPassword(ac, username, usersPasswordMap[username]) if err != nil { return err } } return nil } func isInExistingUsers(username string, existingUsers []model.User) bool { for _, existingUser := range existingUsers { if username == existingUser.Name { return true } } return false }