1
0
forked from baron/baron-sso

kratos SSOT 재설계

This commit is contained in:
2026-06-12 18:36:18 +09:00
parent b96c8100e0
commit 8e9d015443
39 changed files with 3960 additions and 501 deletions

View File

@@ -434,6 +434,9 @@ func (c *WorksmobileHTTPClient) DeleteUser(ctx context.Context, userID string) e
if userID == "" {
return fmt.Errorf("worksmobile user id is required")
}
if c.directoryAuthConfigured() && strings.Contains(userID, "@") {
return c.sendDirectoryJSON(ctx, http.MethodDelete, "/v1.0/users/"+url.PathEscape(userID), nil)
}
remote, err := c.FindUser(ctx, userID)
if err != nil {
return err
@@ -450,6 +453,14 @@ func (c *WorksmobileHTTPClient) DeleteUser(ctx context.Context, userID string) e
return c.sendJSON(ctx, http.MethodDelete, "/scim/v2/Users/"+url.PathEscape(remote.ID), nil)
}
func (c *WorksmobileHTTPClient) ForceDeleteUser(ctx context.Context, userID string) error {
userID = strings.TrimSpace(userID)
if userID == "" {
return fmt.Errorf("worksmobile user id is required")
}
return c.sendDirectoryJSON(ctx, http.MethodDelete, "/v1.0/users/"+url.PathEscape(userID)+"/forcedelete", nil)
}
func (c *WorksmobileHTTPClient) SetUserActive(ctx context.Context, userID string, active bool) error {
userID = strings.TrimSpace(userID)
if userID == "" {
@@ -465,7 +476,18 @@ func (c *WorksmobileHTTPClient) SetUserActive(ctx context.Context, userID string
if remote == nil {
return nil
}
return c.sendJSON(ctx, http.MethodPatch, "/scim/v2/Users/"+url.PathEscape(remote.ID), map[string]any{
return c.SetSCIMUserActiveByID(ctx, remote.ID, active)
}
func (c *WorksmobileHTTPClient) SetSCIMUserActiveByID(ctx context.Context, scimID string, active bool) error {
scimID = strings.TrimSpace(scimID)
if scimID == "" {
return fmt.Errorf("worksmobile scim user id is required")
}
if strings.TrimSpace(c.SCIMToken) == "" {
return fmt.Errorf("worksmobile scim token is not configured")
}
return c.sendJSON(ctx, http.MethodPatch, "/scim/v2/Users/"+url.PathEscape(scimID), map[string]any{
"schemas": []string{"urn:ietf:params:scim:api:messages:2.0:PatchOp"},
"Operations": []map[string]any{
{
@@ -926,6 +948,7 @@ type WorksmobileRemoteUser struct {
PrimaryOrgUnitIsManager *bool `json:"primaryOrgUnitIsManager,omitempty"`
OrgUnitManagers map[string]*bool `json:"orgUnitManagers,omitempty"`
Organizations []WorksmobileUserOrganization `json:"organizations,omitempty"`
AccountStatus string `json:"accountStatus,omitempty"`
Active bool `json:"active"`
IsAwaiting bool `json:"isAwaiting"`
IsPending bool `json:"isPending"`
@@ -1010,12 +1033,21 @@ func worksmobileSCIMPreferredLanguage(locale string) string {
}
func parseWorksmobileRemoteUser(resource map[string]any) WorksmobileRemoteUser {
active := boolFromMap(resource, "active")
user := WorksmobileRemoteUser{
ID: stringFromMap(resource, "id"),
ExternalID: stringFromMap(resource, "externalId"),
UserName: stringFromMap(resource, "userName"),
DisplayName: stringFromMap(resource, "displayName"),
Active: boolFromMap(resource, "active"),
AccountStatus: normalizeWorksmobileAccountStatus(
firstStringFromMap(resource, "accountStatus", "status", "userStatus"),
active,
false,
false,
false,
false,
),
Active: active,
}
if emails, ok := resource["emails"].([]any); ok {
for _, raw := range emails {
@@ -1077,6 +1109,14 @@ func parseWorksmobileDirectoryUser(resource map[string]any) WorksmobileRemoteUse
user.IsPending = boolFromMap(resource, "isPending")
user.IsSuspended = boolFromMap(resource, "isSuspended")
user.IsDeleted = boolFromMap(resource, "isDeleted")
user.AccountStatus = normalizeWorksmobileAccountStatus(
firstStringFromMap(resource, "accountStatus", "status", "userStatus", "loginStatus"),
user.Active,
user.IsAwaiting,
user.IsPending,
user.IsSuspended,
user.IsDeleted,
)
primaryOrgUnit := parseWorksmobilePrimaryOrgUnitDetail(resource)
user.PrimaryOrgUnitID = primaryOrgUnit.ID
user.PrimaryOrgUnitName = primaryOrgUnit.Name
@@ -1088,6 +1128,37 @@ func parseWorksmobileDirectoryUser(resource map[string]any) WorksmobileRemoteUse
return user
}
func normalizeWorksmobileAccountStatus(raw string, active bool, awaiting bool, pending bool, suspended bool, deleted bool) string {
status := strings.ToLower(strings.TrimSpace(raw))
status = strings.ReplaceAll(status, "-", "_")
status = strings.ReplaceAll(status, " ", "_")
switch status {
case "deleted", "delete", "removed":
return "deleted"
case "suspended", "suspend", "blocked", "disabled":
return "suspended"
case "invited", "invite", "awaiting", "pending", "waiting", "not_activated", "unactivated":
return "invited"
case "inactive", "deactivated", "false":
return "inactive"
case "active", "enabled", "true":
return "active"
}
if deleted {
return "deleted"
}
if suspended {
return "suspended"
}
if awaiting || pending {
return "invited"
}
if !active {
return "inactive"
}
return "active"
}
func parseWorksmobileDirectoryGroup(resource map[string]any) WorksmobileRemoteGroup {
email := firstStringFromMap(resource, "email", "mail", "groupEmail", "mailingList", "orgUnitEmail", "loginId", "userName")
return WorksmobileRemoteGroup{