forked from baron/baron-sso
feat: update worksmobile sync and restore planning
This commit is contained in:
@@ -30,6 +30,8 @@ type WorksmobileDirectoryClient interface {
|
||||
DeleteOrgUnit(ctx context.Context, orgUnitID string) error
|
||||
CreateUser(ctx context.Context, payload WorksmobileUserPayload) error
|
||||
UpsertUser(ctx context.Context, payload WorksmobileUserPayload) error
|
||||
AddUserAliasEmail(ctx context.Context, userID string, email string) error
|
||||
ResetUserPassword(ctx context.Context, userID string, password string) error
|
||||
DeleteUser(ctx context.Context, userID string) error
|
||||
SetUserActive(ctx context.Context, userID string, active bool) error
|
||||
ListUsers(ctx context.Context) ([]WorksmobileRemoteUser, error)
|
||||
@@ -283,6 +285,45 @@ func (c *WorksmobileHTTPClient) UpsertUser(ctx context.Context, payload Worksmob
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *WorksmobileHTTPClient) AddUserAliasEmail(ctx context.Context, userID string, email string) error {
|
||||
userID = strings.TrimSpace(userID)
|
||||
email = strings.TrimSpace(email)
|
||||
if userID == "" {
|
||||
return fmt.Errorf("worksmobile user id is required")
|
||||
}
|
||||
if email == "" {
|
||||
return fmt.Errorf("worksmobile alias email is required")
|
||||
}
|
||||
err := c.sendDirectoryJSON(
|
||||
ctx,
|
||||
http.MethodPost,
|
||||
"/v1.0/users/"+url.PathEscape(userID)+"/alias-emails/"+url.PathEscape(email),
|
||||
nil,
|
||||
)
|
||||
if apiErr, ok := err.(WorksmobileHTTPError); ok && apiErr.StatusCode == http.StatusConflict {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *WorksmobileHTTPClient) ResetUserPassword(ctx context.Context, userID string, password string) error {
|
||||
userID = strings.TrimSpace(userID)
|
||||
password = strings.TrimSpace(password)
|
||||
if userID == "" {
|
||||
return fmt.Errorf("worksmobile user id is required")
|
||||
}
|
||||
if password == "" {
|
||||
return fmt.Errorf("worksmobile password is required")
|
||||
}
|
||||
payload := map[string]any{
|
||||
"passwordConfig": WorksmobilePasswordConfig{
|
||||
PasswordCreationType: "ADMIN",
|
||||
Password: password,
|
||||
},
|
||||
}
|
||||
return c.sendDirectoryJSON(ctx, http.MethodPatch, "/v1.0/users/"+url.PathEscape(userID), payload)
|
||||
}
|
||||
|
||||
func (c *WorksmobileHTTPClient) PatchUser(ctx context.Context, identifier string, payload WorksmobileUserPatchPayload) error {
|
||||
identifier = strings.TrimSpace(identifier)
|
||||
if identifier == "" {
|
||||
@@ -756,22 +797,23 @@ type WorksmobileOrgUnitPatchPayload struct {
|
||||
}
|
||||
|
||||
type WorksmobileRemoteUser struct {
|
||||
ID string `json:"id"`
|
||||
ExternalID string `json:"externalId"`
|
||||
UserName string `json:"userName"`
|
||||
Email string `json:"email"`
|
||||
DisplayName string `json:"displayName"`
|
||||
LevelID string `json:"levelId"`
|
||||
LevelName string `json:"levelName"`
|
||||
Task string `json:"task"`
|
||||
DomainID int64 `json:"domainId"`
|
||||
DomainName string `json:"domainName"`
|
||||
PrimaryOrgUnitID string `json:"primaryOrgUnitId"`
|
||||
PrimaryOrgUnitName string `json:"primaryOrgUnitName"`
|
||||
PrimaryOrgUnitPositionID string `json:"primaryOrgUnitPositionId"`
|
||||
PrimaryOrgUnitPositionName string `json:"primaryOrgUnitPositionName"`
|
||||
PrimaryOrgUnitIsManager *bool `json:"primaryOrgUnitIsManager,omitempty"`
|
||||
Active bool `json:"active"`
|
||||
ID string `json:"id"`
|
||||
ExternalID string `json:"externalId"`
|
||||
UserName string `json:"userName"`
|
||||
Email string `json:"email"`
|
||||
DisplayName string `json:"displayName"`
|
||||
LevelID string `json:"levelId"`
|
||||
LevelName string `json:"levelName"`
|
||||
Task string `json:"task"`
|
||||
DomainID int64 `json:"domainId"`
|
||||
DomainName string `json:"domainName"`
|
||||
PrimaryOrgUnitID string `json:"primaryOrgUnitId"`
|
||||
PrimaryOrgUnitName string `json:"primaryOrgUnitName"`
|
||||
PrimaryOrgUnitPositionID string `json:"primaryOrgUnitPositionId"`
|
||||
PrimaryOrgUnitPositionName string `json:"primaryOrgUnitPositionName"`
|
||||
PrimaryOrgUnitIsManager *bool `json:"primaryOrgUnitIsManager,omitempty"`
|
||||
OrgUnitManagers map[string]*bool `json:"orgUnitManagers,omitempty"`
|
||||
Active bool `json:"active"`
|
||||
}
|
||||
|
||||
type WorksmobileRemoteGroup struct {
|
||||
@@ -907,6 +949,7 @@ func parseWorksmobileDirectoryUser(resource map[string]any) WorksmobileRemoteUse
|
||||
user.PrimaryOrgUnitPositionID = primaryOrgUnit.PositionID
|
||||
user.PrimaryOrgUnitPositionName = primaryOrgUnit.PositionName
|
||||
user.PrimaryOrgUnitIsManager = primaryOrgUnit.IsManager
|
||||
user.OrgUnitManagers = parseWorksmobileOrgUnitManagers(resource)
|
||||
return user
|
||||
}
|
||||
|
||||
@@ -1029,6 +1072,43 @@ func parseWorksmobilePrimaryOrgUnitDetail(resource map[string]any) worksmobileOr
|
||||
return worksmobileOrgUnitDetail{}
|
||||
}
|
||||
|
||||
func parseWorksmobileOrgUnitManagers(resource map[string]any) map[string]*bool {
|
||||
result := map[string]*bool{}
|
||||
collectWorksmobileOrgUnitManagers(resource["organizations"], result)
|
||||
collectWorksmobileOrgUnitManagers(resource["orgUnits"], result)
|
||||
for key, raw := range resource {
|
||||
if !strings.Contains(strings.ToLower(key), "works") {
|
||||
continue
|
||||
}
|
||||
if values, ok := raw.(map[string]any); ok {
|
||||
collectWorksmobileOrgUnitManagers(values["organizations"], result)
|
||||
collectWorksmobileOrgUnitManagers(values["orgUnits"], result)
|
||||
}
|
||||
}
|
||||
if len(result) == 0 {
|
||||
return nil
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func collectWorksmobileOrgUnitManagers(raw any, result map[string]*bool) {
|
||||
values, ok := raw.([]any)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
for _, item := range values {
|
||||
orgUnit, ok := item.(map[string]any)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if id := firstStringFromMap(orgUnit, "orgUnitId", "id", "value"); id != "" {
|
||||
result[id] = boolPointerFromMap(orgUnit, "isManager", "manager")
|
||||
}
|
||||
collectWorksmobileOrgUnitManagers(orgUnit["organizations"], result)
|
||||
collectWorksmobileOrgUnitManagers(orgUnit["orgUnits"], result)
|
||||
}
|
||||
}
|
||||
|
||||
func parseWorksmobileParentOrgUnit(resource map[string]any) (string, string) {
|
||||
id := firstStringFromMap(resource, "parentOrgUnitId", "parentId")
|
||||
name := firstStringFromMap(resource, "parentOrgUnitName", "parentName")
|
||||
|
||||
Reference in New Issue
Block a user