Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

200 name handling #204

Merged
merged 19 commits into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion internal/google/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ func (c *client) GetUsers(query string) ([]*admin.User, error) {
u = append(u, users.Users...)
return nil
})
return u, err
} else {

// The Google api doesn't support multi-part queries, but we do so we need to split into an array of query strings
Expand All @@ -128,6 +127,16 @@ func (c *client) GetUsers(query string) ([]*admin.User, error) {
}
}

// some people prefer to go by a mononym
// Google directory will accept a 'zero width space' for an empty name but will not accept a 'space'
// but
// Identity Store will accept and a 'space' for an empty name but not a 'zero width space'
// So we need to replace any 'zero width space' strings with a single 'space' to allow comparison and sync
for _, user := range u {
user.Name.GivenName = strings.Replace(user.Name.GivenName, string('\u200B'), " ", -1)
user.Name.FamilyName = strings.Replace(user.Name.FamilyName, string('\u200B'), " ", -1)
}

// Check we've got some users otherwise something is wrong.
if len(u) == 0 {
return u, errors.New("google api returned 0 users?")
Expand Down
25 changes: 20 additions & 5 deletions internal/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@
if err != nil {
return err
}
log.WithField("googleGroups", googleGroups).Debug("Groups to sync")
log.WithField("googleUsers", googleUsers).Debug("Users to sync")

log.Info("get existing aws groups")
awsGroups, err := s.GetGroups()
Expand Down Expand Up @@ -352,7 +354,7 @@
&identitystore.DeleteUserInput{IdentityStoreId: &s.cfg.IdentityStoreID, UserId: &awsUserFull.ID},
)
if err != nil {
log.Error("error deleting user")
log.WithField("user", awsUser).Error("error deleting user")
return err
}
}
Expand All @@ -377,7 +379,7 @@
awsUser.Username,
awsUser.Active))
if err != nil {
log.Error("error updating user")
log.WithField("user", awsUser).Error("error updating user")
return err
}
}
Expand All @@ -391,12 +393,12 @@
log.Info("creating user")
_, err := s.aws.CreateUser(awsUser)
if err != nil {
errHttp := new(aws.ErrHttpNotOK)

Check failure on line 396 in internal/sync.go

View workflow job for this annotation

GitHub Actions / test

var errHttp should be errHTTP
if errors.As(err, &errHttp) && errHttp.StatusCode == 409 {
log.WithField("user", awsUser.Username).Warn("user already exists")
continue
}
log.Error("error creating user")
log.WithField("user", awsUser).Error("error creating user")
return err
}
}
Expand Down Expand Up @@ -531,6 +533,7 @@
return nil, nil, nil, err
}
for _, u := range googleUsers {
log.WithField("email", u).Debug("processing member of gUserDetailCache")
gUserDetailCache[u.PrimaryEmail] = u
}

Expand All @@ -552,7 +555,7 @@

log.Debug("process users from google, filtering as required")
for _, u := range googleUsers {
log.WithField("email", u.PrimaryEmail).Debug("processing member")
log.WithField("email", u).Debug("processing userMatch")

// Remove any users that should be ignored
if s.ignoreUser(u.PrimaryEmail) {
Expand Down Expand Up @@ -627,6 +630,7 @@
// getGroupOperations returns the groups of AWS that must be added, deleted and are equals
func getGroupOperations(awsGroups []*aws.Group, googleGroups []*admin.Group) (add []*aws.Group, delete []*aws.Group, equals []*aws.Group) {

log.Debug("getGroupOperations()")
awsMap := make(map[string]*aws.Group)
googleMap := make(map[string]struct{})

Expand All @@ -640,16 +644,19 @@

// AWS Groups found and not found in google
for _, gGroup := range googleGroups {
if _, found := awsMap[gGroup.Name]; found {
if _, found := awsMap[gGroup.Name]; found {
log.WithField("gGroup", gGroup).Debug("equals")
equals = append(equals, awsMap[gGroup.Name])
} else {
log.WithField("gGroup", gGroup).Debug("add")
add = append(add, aws.NewGroup(gGroup.Name))
}
}

// Google Groups founds and not in aws
for _, awsGroup := range awsGroups {
if _, found := googleMap[awsGroup.DisplayName]; !found {
log.WithField("awsGroup", awsGroup).Debug("delete")
delete = append(delete, aws.NewGroup(awsGroup.DisplayName))
}
}
Expand All @@ -660,6 +667,7 @@
// getUserOperations returns the users of AWS that must be added, deleted, updated and are equals
func getUserOperations(awsUsers []*aws.User, googleUsers []*admin.User) (add []*aws.User, delete []*aws.User, update []*aws.User, equals []*aws.User) {

log.Debug("getUserOperations()")
awsMap := make(map[string]*aws.User)
googleMap := make(map[string]struct{})

Expand All @@ -677,18 +685,24 @@
if awsUser.Active == gUser.Suspended ||
awsUser.Name.GivenName != gUser.Name.GivenName ||
awsUser.Name.FamilyName != gUser.Name.FamilyName {
log.WithField("gUser", gUser).Debug("update")
log.WithField("awsUser", awsUser).Debug("update")
update = append(update, aws.NewUser(gUser.Name.GivenName, gUser.Name.FamilyName, gUser.PrimaryEmail, !gUser.Suspended))

} else {
log.WithField("awsUser", awsUser).Debug("equals")
equals = append(equals, awsUser)
}
} else {
log.WithField("gUser", gUser).Debug("add")
add = append(add, aws.NewUser(gUser.Name.GivenName, gUser.Name.FamilyName, gUser.PrimaryEmail, !gUser.Suspended))
}
}

// Google Users founds and not in aws
for _, awsUser := range awsUsers {
if _, found := googleMap[awsUser.Username]; !found {
log.WithField("awsUser", awsUser).Debug("delete")
delete = append(delete, aws.NewUser(awsUser.Name.GivenName, awsUser.Name.FamilyName, awsUser.Username, awsUser.Active))
}
}
Expand All @@ -699,6 +713,7 @@
// groupUsersOperations returns the groups and its users of AWS that must be delete from these groups and what are equals
func getGroupUsersOperations(gGroupsUsers map[string][]*admin.User, awsGroupsUsers map[string][]*aws.User) (delete map[string][]*aws.User, equals map[string][]*aws.User) {

log.Debug("getGroupUsersOperations()")
mbG := make(map[string]map[string]struct{})

// get user in google groups that are in aws groups and
Expand Down Expand Up @@ -790,7 +805,7 @@
if err != nil {
log.WithField("error", err).Warn("Problem performing test query against Identity Store")
return err
} else {

Check failure on line 808 in internal/sync.go

View workflow job for this annotation

GitHub Actions / test

if block ends with a return statement, so drop this else and outdent its block
log.WithField("Groups", response).Info("Test call for groups successful")

}
Expand Down Expand Up @@ -869,7 +884,7 @@
return awsGroups, nil
}

func ListGroupsPagesCallbackFn(page *identitystore.ListGroupsOutput, lastPage bool) bool {

Check failure on line 887 in internal/sync.go

View workflow job for this annotation

GitHub Actions / test

exported function ListGroupsPagesCallbackFn should have comment or be unexported
// Loop through each Group returned
for _, group := range page.Groups {
// Convert to native Group object
Expand Down Expand Up @@ -901,7 +916,7 @@
return awsUsers, nil
}

func ListUsersPagesCallbackFn(page *identitystore.ListUsersOutput, lastPage bool) bool {

Check failure on line 919 in internal/sync.go

View workflow job for this annotation

GitHub Actions / test

exported function ListUsersPagesCallbackFn should have comment or be unexported
// Loop through each User in ListUsersOutput and convert to native User object
for _, user := range page.Users {
awsUsers = append(awsUsers, ConvertSdkUserObjToNative(user))
Expand All @@ -909,7 +924,7 @@
return !lastPage
}

func ConvertSdkUserObjToNative(user *identitystore.User) *aws.User {

Check failure on line 927 in internal/sync.go

View workflow job for this annotation

GitHub Actions / test

exported function ConvertSdkUserObjToNative should have comment or be unexported
// Convert emails into native Email object
userEmails := make([]aws.UserEmail, 0)

Expand Down Expand Up @@ -953,7 +968,7 @@
}
}

func CreateUserIDtoUserObjMap(awsUsers []*aws.User) map[string]*aws.User {

Check failure on line 971 in internal/sync.go

View workflow job for this annotation

GitHub Actions / test

exported function CreateUserIDtoUserObjMap should have comment or be unexported
awsUsersMap := make(map[string]*aws.User)

for _, awsUser := range awsUsers {
Expand All @@ -963,7 +978,7 @@
return awsUsersMap
}

var ListGroupMembershipPagesCallbackFn func(page *identitystore.ListGroupMembershipsOutput, lastPage bool) bool

Check failure on line 981 in internal/sync.go

View workflow job for this annotation

GitHub Actions / test

exported var ListGroupMembershipPagesCallbackFn should have comment or be unexported

func (s *syncGSuite) GetGroupMembershipsLists(awsGroups []*aws.Group, awsUsersMap map[string]*aws.User) (map[string][]*aws.User, error) {
awsGroupsUsers := make(map[string][]*aws.User)
Expand Down
Loading