package createuser import ( "errors" "fmt" "net/http" "strings" "git.artlef.fr/PersonalLibraryManager/internal/config" "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(db *gorm.DB, username string, password string) error { hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { return err } return CreateUserWithHashedPassword(db, username, string(hashedPassword)) } // only call this method with hashed password func CreateUserWithHashedPassword(db *gorm.DB, username string, hashedPassword string) error { var existingUser model.User err := 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("An user with this name already exists."), } } user := model.User{ Name: username, Password: hashedPassword, } return db.Model(&model.User{}).Save(&user).Error } func CreateDefaultUsers(db *gorm.DB, config *config.Config) error { usersPasswordMap := make(map[string]string) var usernames []string for _, s := range config.AddUser { splittedString := strings.Split(s, ":") if len(splittedString) < 2 { return fmt.Errorf("Error when creating user from string %s", s) } usernames = append(usernames, splittedString[0]) usersPasswordMap[splittedString[0]] = splittedString[1] } var existingUsers []model.User err := db.Where("name IN ?", usernames).Find(&existingUsers).Error if err != nil { return err } for _, username := range usernames { if isInExistingUsers(username, existingUsers) { continue } err = CreateUserWithHashedPassword(db, 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 }