Files
portainer/api/http/handler/users/user_create_test.go
2026-04-13 11:32:07 -03:00

100 lines
2.3 KiB
Go

package users
import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"time"
portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/apikey"
"github.com/portainer/portainer/api/crypto"
"github.com/portainer/portainer/api/datastore"
"github.com/portainer/portainer/api/http/security"
"github.com/portainer/portainer/api/jwt"
"github.com/stretchr/testify/require"
"golang.org/x/sync/errgroup"
)
type mockPasswordStrengthChecker struct{}
func (m mockPasswordStrengthChecker) Check(string) bool {
return true
}
func newTestHandler(t *testing.T, store *datastore.Store) (*Handler, *jwt.Service, apikey.APIKeyService) {
t.Helper()
jwtService, err := jwt.NewService("1h", store)
require.NoError(t, err)
apiKeyService := apikey.NewAPIKeyService(store.APIKeyRepository(), store.User())
requestBouncer := security.NewRequestBouncer(t.Context(), store, jwtService, apiKeyService)
rateLimiter := security.NewRateLimiter(10, 1*time.Second, 1*time.Hour)
passwordChecker := security.NewPasswordStrengthChecker(store.SettingsService)
h := NewHandler(requestBouncer, rateLimiter, apiKeyService, passwordChecker)
h.DataStore = store
return h, jwtService, apiKeyService
}
func TestConcurrentUserCreation(t *testing.T) {
t.Parallel()
_, store := datastore.MustNewTestStore(t, true, false)
h := &Handler{
passwordStrengthChecker: mockPasswordStrengthChecker{},
CryptoService: crypto.Service{},
DataStore: store,
}
ucp := userCreatePayload{
Username: "portainer",
Password: "password",
Role: int(portainer.AdministratorRole),
}
m, err := json.Marshal(ucp)
require.NoError(t, err)
errGroup := &errgroup.Group{}
n := 100
for range n {
errGroup.Go(func() error {
req, err := http.NewRequest(http.MethodPost, "/users", bytes.NewReader(m))
if err != nil {
return err
}
if err := h.userCreate(httptest.NewRecorder(), req); err != nil {
return err
}
return nil
})
}
err = errGroup.Wait()
require.Error(t, err)
users, err := store.User().ReadAll()
require.NotEmpty(t, users)
require.NoError(t, err)
userCreated := false
for _, u := range users {
if u.Username == ucp.Username {
require.False(t, userCreated)
userCreated = true
}
}
require.True(t, userCreated)
}