142 lines
4.0 KiB
Go
142 lines
4.0 KiB
Go
|
|
package zitadel_test
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"encoding/json"
|
||
|
|
"io"
|
||
|
|
"net/http"
|
||
|
|
"net/http/httptest"
|
||
|
|
"net/url"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"gateway/internal/library/zitadel"
|
||
|
|
|
||
|
|
"github.com/stretchr/testify/assert"
|
||
|
|
"github.com/stretchr/testify/require"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestCreateHumanUser(t *testing.T) {
|
||
|
|
t.Parallel()
|
||
|
|
var gotAuth string
|
||
|
|
var gotBody map[string]any
|
||
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
switch {
|
||
|
|
case r.Method == http.MethodPost && r.URL.Path == "/v2/users/human":
|
||
|
|
gotAuth = r.Header.Get("Authorization")
|
||
|
|
assert.NoError(t, json.NewDecoder(r.Body).Decode(&gotBody))
|
||
|
|
w.Header().Set("Content-Type", "application/json")
|
||
|
|
_, _ = w.Write([]byte(`{"userId":"zit-123"}`))
|
||
|
|
default:
|
||
|
|
http.NotFound(w, r)
|
||
|
|
}
|
||
|
|
}))
|
||
|
|
t.Cleanup(srv.Close)
|
||
|
|
|
||
|
|
c, err := zitadel.NewClient(zitadel.Conf{
|
||
|
|
Issuer: srv.URL,
|
||
|
|
ServiceUserToken: "pat-test",
|
||
|
|
DefaultOrgID: "org-1",
|
||
|
|
})
|
||
|
|
require.NoError(t, err)
|
||
|
|
|
||
|
|
res, err := c.CreateHumanUser(context.Background(), zitadel.CreateHumanUserRequest{
|
||
|
|
Email: "alice@example.com",
|
||
|
|
Password: "Secret123!",
|
||
|
|
DisplayName: "Alice Smith",
|
||
|
|
Language: "zh-tw",
|
||
|
|
})
|
||
|
|
require.NoError(t, err)
|
||
|
|
require.Equal(t, "zit-123", res.UserID)
|
||
|
|
require.Equal(t, "Bearer pat-test", gotAuth)
|
||
|
|
require.Equal(t, "alice@example.com", gotBody["username"])
|
||
|
|
require.Equal(t, "org-1", gotBody["organizationId"])
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestCreateHumanUserConflict(t *testing.T) {
|
||
|
|
t.Parallel()
|
||
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
http.Error(w, "exists", http.StatusConflict)
|
||
|
|
}))
|
||
|
|
t.Cleanup(srv.Close)
|
||
|
|
|
||
|
|
c, err := zitadel.NewClient(zitadel.Conf{Issuer: srv.URL, ServiceUserToken: testPAT})
|
||
|
|
require.NoError(t, err)
|
||
|
|
|
||
|
|
_, err = c.CreateHumanUser(context.Background(), zitadel.CreateHumanUserRequest{
|
||
|
|
Email: "dup@example.com",
|
||
|
|
Password: "x",
|
||
|
|
})
|
||
|
|
require.ErrorIs(t, err, zitadel.ErrUserAlreadyExists)
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestDeactivateUser(t *testing.T) {
|
||
|
|
t.Parallel()
|
||
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
assert.Equal(t, http.MethodPost, r.Method)
|
||
|
|
assert.Equal(t, "/v2/users/u-99/deactivate", r.URL.Path)
|
||
|
|
w.WriteHeader(http.StatusOK)
|
||
|
|
_, _ = w.Write([]byte(`{"details":{}}`))
|
||
|
|
}))
|
||
|
|
t.Cleanup(srv.Close)
|
||
|
|
|
||
|
|
c, err := zitadel.NewClient(zitadel.Conf{Issuer: srv.URL, ServiceUserToken: testPAT})
|
||
|
|
require.NoError(t, err)
|
||
|
|
require.NoError(t, c.DeactivateUser(context.Background(), "u-99"))
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestVerifyPassword(t *testing.T) {
|
||
|
|
t.Parallel()
|
||
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
assert.Equal(t, "/oauth/v2/token", r.URL.Path)
|
||
|
|
body, _ := io.ReadAll(r.Body)
|
||
|
|
vals := parseForm(string(body))
|
||
|
|
assert.Equal(t, "password", vals["grant_type"])
|
||
|
|
assert.Equal(t, testClientID, vals["client_id"])
|
||
|
|
assert.Equal(t, "alice@example.com", vals["username"])
|
||
|
|
if vals["password"] != "ok" {
|
||
|
|
http.Error(w, "invalid", http.StatusUnauthorized)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
w.Header().Set("Content-Type", "application/json")
|
||
|
|
_, _ = w.Write([]byte(`{"access_token":"at","id_token":"id","expires_in":3600,"token_type":"Bearer"}`))
|
||
|
|
}))
|
||
|
|
t.Cleanup(srv.Close)
|
||
|
|
|
||
|
|
c, err := zitadel.NewClient(zitadel.Conf{
|
||
|
|
Issuer: srv.URL,
|
||
|
|
ServiceUserToken: testPAT,
|
||
|
|
OAuthClientID: testClientID,
|
||
|
|
OAuthClientSecret: testSecret,
|
||
|
|
})
|
||
|
|
require.NoError(t, err)
|
||
|
|
|
||
|
|
tok, err := c.VerifyPassword(context.Background(), "alice@example.com", "ok")
|
||
|
|
require.NoError(t, err)
|
||
|
|
require.Equal(t, "at", tok.AccessToken)
|
||
|
|
require.Equal(t, "id", tok.IDToken)
|
||
|
|
|
||
|
|
_, err = c.VerifyPassword(context.Background(), "alice@example.com", "bad")
|
||
|
|
require.ErrorIs(t, err, zitadel.ErrInvalidCredentials)
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestNewClientDisabledWhenIssuerEmpty(t *testing.T) {
|
||
|
|
t.Parallel()
|
||
|
|
c, err := zitadel.NewClient(zitadel.Conf{})
|
||
|
|
require.NoError(t, err)
|
||
|
|
require.Nil(t, c)
|
||
|
|
}
|
||
|
|
|
||
|
|
func parseForm(body string) map[string]string {
|
||
|
|
vals, err := url.ParseQuery(body)
|
||
|
|
if err != nil {
|
||
|
|
return map[string]string{}
|
||
|
|
}
|
||
|
|
out := make(map[string]string, len(vals))
|
||
|
|
for k, v := range vals {
|
||
|
|
if len(v) > 0 {
|
||
|
|
out[k] = v[0]
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return out
|
||
|
|
}
|