forked from baron/baron-sso
merge: integrate origin dev into dev
Includes Worksmobile SSOT sync comparison updates, UUID import conflict resolution, and Playwright route mock stabilization.
This commit is contained in:
@@ -778,7 +778,7 @@ type WorksmobileUserPatchPayload struct {
|
||||
DomainID int64 `json:"domainId"`
|
||||
Email string `json:"email,omitempty"`
|
||||
UserExternalKey string `json:"userExternalKey,omitempty"`
|
||||
UserName WorksmobileUserName `json:"userName,omitempty"`
|
||||
UserName WorksmobileUserName `json:"userName"`
|
||||
CellPhone string `json:"cellPhone,omitempty"`
|
||||
EmployeeNumber string `json:"employeeNumber,omitempty"`
|
||||
AliasEmails []string `json:"aliasEmails,omitempty"`
|
||||
@@ -797,23 +797,26 @@ 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"`
|
||||
OrgUnitManagers map[string]*bool `json:"orgUnitManagers,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"`
|
||||
CellPhone string `json:"cellPhone,omitempty"`
|
||||
EmployeeNumber string `json:"employeeNumber,omitempty"`
|
||||
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"`
|
||||
Organizations []WorksmobileUserOrganization `json:"organizations,omitempty"`
|
||||
Active bool `json:"active"`
|
||||
}
|
||||
|
||||
type WorksmobileRemoteGroup struct {
|
||||
@@ -935,10 +938,18 @@ func parseWorksmobileDirectoryUser(resource map[string]any) WorksmobileRemoteUse
|
||||
UserName: email,
|
||||
Email: email,
|
||||
DisplayName: parseWorksmobileDirectoryUserName(resource),
|
||||
LevelID: parseWorksmobileUserLevelID(resource),
|
||||
LevelName: parseWorksmobileUserLevelName(resource),
|
||||
Task: firstStringFromMap(resource, "task", "job", "jobDescription"),
|
||||
Active: true,
|
||||
CellPhone: firstStringFromMap(resource, "cellPhone", "phoneNumber", "phone", "mobile", "mobilePhone"),
|
||||
EmployeeNumber: firstStringFromMap(
|
||||
resource,
|
||||
"employeeNumber",
|
||||
"employeeNo",
|
||||
"employeeId",
|
||||
"employeeID",
|
||||
),
|
||||
LevelID: parseWorksmobileUserLevelID(resource),
|
||||
LevelName: parseWorksmobileUserLevelName(resource),
|
||||
Task: firstStringFromMap(resource, "task", "job", "jobDescription"),
|
||||
Active: true,
|
||||
}
|
||||
if active, ok := resource["active"].(bool); ok {
|
||||
user.Active = active
|
||||
@@ -950,6 +961,7 @@ func parseWorksmobileDirectoryUser(resource map[string]any) WorksmobileRemoteUse
|
||||
user.PrimaryOrgUnitPositionName = primaryOrgUnit.PositionName
|
||||
user.PrimaryOrgUnitIsManager = primaryOrgUnit.IsManager
|
||||
user.OrgUnitManagers = parseWorksmobileOrgUnitManagers(resource)
|
||||
user.Organizations = parseWorksmobileUserOrganizations(resource)
|
||||
return user
|
||||
}
|
||||
|
||||
@@ -1072,6 +1084,84 @@ func parseWorksmobilePrimaryOrgUnitDetail(resource map[string]any) worksmobileOr
|
||||
return worksmobileOrgUnitDetail{}
|
||||
}
|
||||
|
||||
func parseWorksmobileUserOrganizations(resource map[string]any) []WorksmobileUserOrganization {
|
||||
if organizations := parseWorksmobileUserOrganizationList(resource["organizations"]); len(organizations) > 0 {
|
||||
return organizations
|
||||
}
|
||||
for key, raw := range resource {
|
||||
if !strings.Contains(strings.ToLower(key), "works") {
|
||||
continue
|
||||
}
|
||||
if values, ok := raw.(map[string]any); ok {
|
||||
if organizations := parseWorksmobileUserOrganizationList(values["organizations"]); len(organizations) > 0 {
|
||||
return organizations
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseWorksmobileUserOrganizationList(raw any) []WorksmobileUserOrganization {
|
||||
values, ok := raw.([]any)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
organizations := make([]WorksmobileUserOrganization, 0, len(values))
|
||||
for _, item := range values {
|
||||
organization, ok := item.(map[string]any)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
orgUnits := parseWorksmobileUserOrgUnitList(organization["orgUnits"])
|
||||
if len(orgUnits) == 0 {
|
||||
continue
|
||||
}
|
||||
organizations = append(organizations, WorksmobileUserOrganization{
|
||||
DomainID: int64FromMap(organization, "domainId"),
|
||||
Email: firstStringFromMap(organization, "email"),
|
||||
Primary: boolFromMap(organization, "primary"),
|
||||
OrgUnits: orgUnits,
|
||||
})
|
||||
}
|
||||
return organizations
|
||||
}
|
||||
|
||||
func parseWorksmobileUserOrgUnitList(raw any) []WorksmobileUserOrgUnit {
|
||||
values, ok := raw.([]any)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
orgUnits := make([]WorksmobileUserOrgUnit, 0, len(values))
|
||||
for _, item := range values {
|
||||
orgUnit, ok := item.(map[string]any)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
id := firstStringFromMap(orgUnit, "orgUnitExternalKey", "externalKey")
|
||||
if id != "" {
|
||||
id = "externalKey:" + id
|
||||
} else {
|
||||
id = firstStringFromMap(orgUnit, "orgUnitId", "id", "value")
|
||||
}
|
||||
if id == "" {
|
||||
if nested := parseWorksmobileUserOrgUnitList(orgUnit["orgUnits"]); len(nested) > 0 {
|
||||
orgUnits = append(orgUnits, nested...)
|
||||
}
|
||||
continue
|
||||
}
|
||||
orgUnits = append(orgUnits, WorksmobileUserOrgUnit{
|
||||
OrgUnitID: id,
|
||||
Primary: boolFromMap(orgUnit, "primary"),
|
||||
PositionID: firstStringFromMap(orgUnit, "positionId"),
|
||||
IsManager: boolPointerFromMap(orgUnit, "isManager", "manager"),
|
||||
})
|
||||
if nested := parseWorksmobileUserOrgUnitList(orgUnit["orgUnits"]); len(nested) > 0 {
|
||||
orgUnits = append(orgUnits, nested...)
|
||||
}
|
||||
}
|
||||
return orgUnits
|
||||
}
|
||||
|
||||
func parseWorksmobileOrgUnitManagers(resource map[string]any) map[string]*bool {
|
||||
result := map[string]*bool{}
|
||||
collectWorksmobileOrgUnitManagers(resource["organizations"], result)
|
||||
@@ -1101,7 +1191,13 @@ func collectWorksmobileOrgUnitManagers(raw any, result map[string]*bool) {
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if id := firstStringFromMap(orgUnit, "orgUnitId", "id", "value"); id != "" {
|
||||
id := firstStringFromMap(orgUnit, "orgUnitExternalKey", "externalKey")
|
||||
if id != "" {
|
||||
id = "externalKey:" + id
|
||||
} else {
|
||||
id = firstStringFromMap(orgUnit, "orgUnitId", "id", "value")
|
||||
}
|
||||
if id != "" {
|
||||
result[id] = boolPointerFromMap(orgUnit, "isManager", "manager")
|
||||
}
|
||||
collectWorksmobileOrgUnitManagers(orgUnit["organizations"], result)
|
||||
@@ -1194,6 +1290,19 @@ func boolFromMap(values map[string]any, key string) bool {
|
||||
return value
|
||||
}
|
||||
|
||||
func int64FromMap(values map[string]any, key string) int64 {
|
||||
switch value := values[key].(type) {
|
||||
case int:
|
||||
return int64(value)
|
||||
case int64:
|
||||
return value
|
||||
case float64:
|
||||
return int64(value)
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func boolPointerFromMap(values map[string]any, keys ...string) *bool {
|
||||
for _, key := range keys {
|
||||
if value, ok := values[key].(bool); ok {
|
||||
|
||||
Reference in New Issue
Block a user