forked from baron/baron-sso
worksmobile 연동 & ory stack 26.2.0으로 업그레이드
This commit is contained in:
145
backend/internal/service/worksmobile_live_flow_test.go
Normal file
145
backend/internal/service/worksmobile_live_flow_test.go
Normal file
@@ -0,0 +1,145 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"baron-sso-backend/internal/domain"
|
||||
"baron-sso-backend/internal/repository"
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func TestWorksmobileLiveSamanUsersDirectoryProvisioning(t *testing.T) {
|
||||
if os.Getenv("WORKSMOBILE_LIVE_SAMAN_PROVISIONING") != "1" {
|
||||
t.Skip("live Worksmobile Saman provisioning is disabled")
|
||||
}
|
||||
ctx := context.Background()
|
||||
db, err := gorm.Open(postgres.Open(worksmobileLiveDSN()), &gorm.Config{})
|
||||
require.NoError(t, err)
|
||||
|
||||
tenantRepo := repository.NewTenantRepository(db)
|
||||
userRepo := repository.NewUserRepository(db)
|
||||
userGroupRepo := repository.NewUserGroupRepository(db)
|
||||
outboxRepo := repository.NewWorksmobileOutboxRepository(db)
|
||||
tenantService := NewTenantService(tenantRepo, userRepo, userGroupRepo, nil)
|
||||
client := NewWorksmobileHTTPClientWithAuth("", os.Getenv("SAMAN_SCIM_LONGLIVE_TOKEN"), WorksmobileOAuthConfig{
|
||||
ClientID: os.Getenv("WORKS_ADMIN_OAUTH_CLIENT_ID"),
|
||||
ClientSecret: os.Getenv("WORKS_ADMIN_OAUTH_CLIENT_SECRET"),
|
||||
ServiceAccount: os.Getenv("WORKS_ADMIN_OAUTH_CLIENT_SERVICE_ACCOUNT"),
|
||||
PrivateKey: os.Getenv("WORKS_ADMIN_OAUTH_CLIENT_PRIVATE_KEY"),
|
||||
Scope: getenvDefault("WORKS_ADMIN_OAUTH_SCOPE", "directory"),
|
||||
})
|
||||
syncService := NewWorksmobileSyncService(tenantService, userRepo, outboxRepo, client)
|
||||
worker := NewWorksmobileRelayWorker(outboxRepo, client)
|
||||
|
||||
root, err := tenantService.GetTenantBySlug(ctx, HanmacFamilyTenantSlug)
|
||||
require.NoError(t, err)
|
||||
samanTenant, err := tenantService.GetTenantBySlug(ctx, "saman")
|
||||
require.NoError(t, err)
|
||||
createWorksmobileLiveOrgUnitIfMissing(t, ctx, client, *samanTenant)
|
||||
|
||||
targetEmails := []string{"tester@samaneng.com", "orgadmin@samaneng.com"}
|
||||
for _, email := range targetEmails {
|
||||
user, err := userRepo.FindByEmail(ctx, email)
|
||||
require.NoError(t, err)
|
||||
dedupeKey := "user:" + strings.ToLower(WorksmobileUserStatusAction(user.Status)) + ":" + user.ID
|
||||
job := findWorksmobileLiveOutboxByDedupe(t, db, dedupeKey)
|
||||
if job.Status != domain.WorksmobileOutboxStatusProcessed {
|
||||
remote, err := client.FindUser(ctx, user.Email)
|
||||
require.NoError(t, err)
|
||||
if remote != nil {
|
||||
require.NoError(t, outboxRepo.MarkProcessed(ctx, job.ID))
|
||||
continue
|
||||
}
|
||||
item, err := syncService.EnqueueUserSync(ctx, root.ID, user.ID)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, item)
|
||||
require.NoError(t, outboxRepo.MarkRetry(ctx, job.ID))
|
||||
job = findWorksmobileLiveOutboxByDedupe(t, db, dedupeKey)
|
||||
err = worker.processJob(ctx, job)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
processed, err := outboxRepo.FindByID(ctx, job.ID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, domain.WorksmobileOutboxStatusProcessed, processed.Status)
|
||||
}
|
||||
|
||||
credentials, err := syncService.ListInitialPasswordCredentials(ctx, root.ID)
|
||||
require.NoError(t, err)
|
||||
seen := map[string]bool{}
|
||||
for _, credential := range credentials {
|
||||
if credential.Email == "tester@samaneng.com" || credential.Email == "orgadmin@samaneng.com" {
|
||||
require.Equal(t, domain.WorksmobileOutboxStatusProcessed, credential.Status)
|
||||
require.Len(t, credential.InitialPassword, 16)
|
||||
seen[credential.Email] = true
|
||||
}
|
||||
}
|
||||
require.True(t, seen["tester@samaneng.com"])
|
||||
require.True(t, seen["orgadmin@samaneng.com"])
|
||||
|
||||
remoteUsers, err := client.ListUsers(ctx)
|
||||
require.NoError(t, err)
|
||||
remoteByEmail := map[string]WorksmobileRemoteUser{}
|
||||
for _, user := range remoteUsers {
|
||||
remoteByEmail[user.Email] = user
|
||||
}
|
||||
require.NotEmpty(t, remoteByEmail["tester@samaneng.com"].ID)
|
||||
require.NotEmpty(t, remoteByEmail["orgadmin@samaneng.com"].ID)
|
||||
|
||||
remoteGroups, err := client.ListGroups(ctx)
|
||||
require.NoError(t, err)
|
||||
foundSamanOrgUnit := false
|
||||
for _, group := range remoteGroups {
|
||||
if group.ExternalID == samanTenant.ID {
|
||||
foundSamanOrgUnit = true
|
||||
require.Equal(t, "삼안", group.DisplayName)
|
||||
}
|
||||
}
|
||||
require.True(t, foundSamanOrgUnit)
|
||||
}
|
||||
|
||||
func createWorksmobileLiveOrgUnitIfMissing(t *testing.T, ctx context.Context, client *WorksmobileHTTPClient, tenant domain.Tenant) {
|
||||
t.Helper()
|
||||
payload, err := BuildWorksmobileOrgUnitPayload(tenant, nil, 1)
|
||||
require.NoError(t, err)
|
||||
if tenant.ParentID != nil {
|
||||
payload.ParentOrgUnitID = ""
|
||||
}
|
||||
err = client.CreateOrgUnit(ctx, payload)
|
||||
if apiErr, ok := err.(WorksmobileHTTPError); ok && apiErr.StatusCode == 409 {
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func worksmobileLiveDSN() string {
|
||||
host := getenvDefault("DB_HOST", "localhost")
|
||||
port := getenvDefault("DB_PORT", "5432")
|
||||
user := getenvDefault("DB_USER", "baron")
|
||||
password := os.Getenv("DB_PASSWORD")
|
||||
name := getenvDefault("DB_NAME", "baron_sso")
|
||||
return fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=disable TimeZone=Asia/Seoul", host, user, password, name, port)
|
||||
}
|
||||
|
||||
func findWorksmobileLiveOutboxByDedupe(t *testing.T, db *gorm.DB, dedupeKey string) domain.WorksmobileOutbox {
|
||||
t.Helper()
|
||||
var job domain.WorksmobileOutbox
|
||||
deadline := time.Now().Add(3 * time.Second)
|
||||
for {
|
||||
err := db.Where("dedupe_key = ?", dedupeKey).First(&job).Error
|
||||
if err == nil {
|
||||
return job
|
||||
}
|
||||
if time.Now().After(deadline) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user