diff --git a/internal/server/handlers_accounts.go b/internal/server/handlers_accounts.go index 9194325..7b72e82 100644 --- a/internal/server/handlers_accounts.go +++ b/internal/server/handlers_accounts.go @@ -1,12 +1,9 @@ package server import ( - "crypto/rand" "encoding/json" "errors" "log" - "math/big" - mrand "math/rand" "net/http" "regexp" "strconv" @@ -31,8 +28,7 @@ type GetAccountResponse struct { } type CreateAccountResponse struct { - ID int `json:"id"` - Password string `json:"password"` + ID int `json:"id"` } type ChangeAccountResponse struct { @@ -43,49 +39,6 @@ type DeleteAccountResponse struct { ID int `json:"id"` } -func getRandomChars(charset string, length int) (string, error) { - result := make([]byte, length) - for i := range result { - n, err := rand.Int(rand.Reader, big.NewInt(int64(len(charset)))) - if err != nil { - return "", err - } - result[i] = charset[n.Int64()] - } - return string(result), nil -} - -// Generates a random 16 chars long password that contains uppercase and lowercase characters and numbers or symbols. -func generatePassword() (string, error) { - const ( - uppercaseSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - lowercaseSet = "abcdefghijklmnopqrstuvwxyz" - numbersAndSymbolsSet = "0123456789*?@" - allCharsSet = uppercaseSet + lowercaseSet + numbersAndSymbolsSet - ) - uppercase, err := getRandomChars(uppercaseSet, 2) - if err != nil { - return "", err - } - lowercase, err := getRandomChars(lowercaseSet, 2) - if err != nil { - return "", err - } - numbersOrSymbols, err := getRandomChars(numbersAndSymbolsSet, 2) - if err != nil { - return "", err - } - allChars, err := getRandomChars(allCharsSet, 10) - if err != nil { - return "", err - } - res := []rune(uppercase + lowercase + numbersOrSymbols + allChars) - mrand.Shuffle(len(res), func(i, j int) { - res[i], res[j] = res[j], res[i] - }) - return string(res), nil -} - func validatePassword(password string) bool { if len(password) < 8 { return false @@ -180,14 +133,9 @@ func CreateAccount(env *HandlerConfig) http.HandlerFunc { writeError(w, http.StatusBadRequest, "Username is required") return } - shouldGeneratePassword := createAccountParams.Password == "" - if shouldGeneratePassword { - generatedPassword, err := generatePassword() - if err != nil { - writeError(w, http.StatusInternalServerError, "Failed to generate password") - return - } - createAccountParams.Password = generatedPassword + if createAccountParams.Password == "" { + writeError(w, http.StatusBadRequest, "Password is required") + return } if !validatePassword(createAccountParams.Password) { writeError( @@ -220,9 +168,6 @@ func CreateAccount(env *HandlerConfig) http.HandlerFunc { accountResponse := CreateAccountResponse{ ID: int(id), } - if shouldGeneratePassword { - accountResponse.Password = createAccountParams.Password - } w.WriteHeader(http.StatusCreated) err = writeJSON(w, accountResponse) if err != nil { diff --git a/internal/server/handlers_accounts_test.go b/internal/server/handlers_accounts_test.go index ef3dc22..42e2e7a 100644 --- a/internal/server/handlers_accounts_test.go +++ b/internal/server/handlers_accounts_test.go @@ -184,10 +184,10 @@ func TestAccountsEndToEnd(t *testing.T) { } }) - t.Run("3. Create account - no password", func(t *testing.T) { + t.Run("3. Create account", func(t *testing.T) { createAccountParams := &CreateAccountParams{ Username: "nopass", - Password: "", + Password: "myPassword123!", } statusCode, response, err := createAccount(ts.URL, client, adminToken, createAccountParams) if err != nil { @@ -256,7 +256,24 @@ func TestAccountsEndToEnd(t *testing.T) { } }) - t.Run("7. Change account password - success", func(t *testing.T) { + t.Run("7. Create account - no password", func(t *testing.T) { + createAccountParams := &CreateAccountParams{ + Username: "nopass", + Password: "", + } + statusCode, response, err := createAccount(ts.URL, client, adminToken, createAccountParams) + if err != nil { + t.Fatalf("couldn't create account: %s", err) + } + if statusCode != http.StatusBadRequest { + t.Fatalf("expected status %d, got %d", http.StatusBadRequest, statusCode) + } + if response.Error != "Password is required" { + t.Fatalf("expected error %q, got %q", "Password is required", response.Error) + } + }) + + t.Run("8. Change account password - success", func(t *testing.T) { changeAccountPasswordParams := &ChangeAccountPasswordParams{ Password: "newPassword1", } @@ -275,7 +292,7 @@ func TestAccountsEndToEnd(t *testing.T) { } }) - t.Run("8. Change account password - no user", func(t *testing.T) { + t.Run("9. Change account password - no user", func(t *testing.T) { changeAccountPasswordParams := &ChangeAccountPasswordParams{ Password: "newPassword1", } @@ -291,7 +308,7 @@ func TestAccountsEndToEnd(t *testing.T) { } }) - t.Run("9. Change account password - no password", func(t *testing.T) { + t.Run("10. Change account password - no password", func(t *testing.T) { changeAccountPasswordParams := &ChangeAccountPasswordParams{ Password: "", } @@ -307,7 +324,7 @@ func TestAccountsEndToEnd(t *testing.T) { } }) - t.Run("10. Change account password - bad password", func(t *testing.T) { + t.Run("11. Change account password - bad password", func(t *testing.T) { changeAccountPasswordParams := &ChangeAccountPasswordParams{ Password: "password", } @@ -323,7 +340,7 @@ func TestAccountsEndToEnd(t *testing.T) { } }) - t.Run("11. Delete account - success", func(t *testing.T) { + t.Run("12. Delete account - success", func(t *testing.T) { statusCode, response, err := deleteAccount(ts.URL, client, adminToken, 2) if err != nil { t.Fatalf("couldn't delete account: %s", err) @@ -339,7 +356,7 @@ func TestAccountsEndToEnd(t *testing.T) { } }) - t.Run("12. Delete account - no user", func(t *testing.T) { + t.Run("13. Delete account - no user", func(t *testing.T) { statusCode, response, err := deleteAccount(ts.URL, client, adminToken, 100) if err != nil { t.Fatalf("couldn't delete account: %s", err)