diff --git a/pkg/connector/sso_group.go b/pkg/connector/sso_group.go index a1f2603e..593dee35 100644 --- a/pkg/connector/sso_group.go +++ b/pkg/connector/sso_group.go @@ -211,7 +211,7 @@ func (g *ssoGroupResourceType) createOrGetMembership( userID string, ) ( *GroupMembershipOutput, - *annotations.Annotations, + annotations.Annotations, error, ) { logger := ctxzap.Extract(ctx).With( @@ -222,6 +222,7 @@ func (g *ssoGroupResourceType) createOrGetMembership( awsSdk.ToString(g.identityInstance.IdentityStoreId), ), ) + outputAnnotations := annotations.New() groupIdString := awsSdk.String(groupID) memberId := awsIdentityStoreTypes.MemberIdMemberUserId{Value: userID} createInput := &awsIdentityStore.CreateGroupMembershipInput{ @@ -234,7 +235,7 @@ func (g *ssoGroupResourceType) createOrGetMembership( return &GroupMembershipOutput{ MembershipId: createdMembership.MembershipId, ResultMetadata: createdMembership.ResultMetadata, - }, nil, nil + }, outputAnnotations, nil } // Forward along the error if it is an unknown type. @@ -243,6 +244,8 @@ func (g *ssoGroupResourceType) createOrGetMembership( return nil, nil, err } + outputAnnotations.Append(&v2.GrantAlreadyExists{}) + logger.Info("ConflictException when creating group, falling back to GET") getInput := awsIdentityStore.GetGroupMembershipIdInput{ @@ -257,16 +260,15 @@ func (g *ssoGroupResourceType) createOrGetMembership( var accessDeniedException *awsIdentityStoreTypes.AccessDeniedException if errors.As(err, &accessDeniedException) { logger.Info("Not authorized to perform `GetGroupMembershipId`, falling back to empty membership") - // TODO(marcos): Create an annotation that marks this grant as "already exists". - return nil, nil, nil + return nil, outputAnnotations, nil } - return nil, nil, err + return nil, outputAnnotations, err } return &GroupMembershipOutput{ MembershipId: foundMembership.MembershipId, - }, nil, nil + }, outputAnnotations, nil } func (g *ssoGroupResourceType) Grant( @@ -298,35 +300,41 @@ func (g *ssoGroupResourceType) Grant( zap.String("identity_store_id", awsSdk.ToString(g.identityInstance.IdentityStoreId)), ) - // TODO(marcos): If we get a nil membership and an annotation, return that annotation. - membership, _, err := g.createOrGetMembership(ctx, groupID, userID) + annos := annotations.New() + outputGrants := make([]*v2.Grant, 0) + + membership, annotationsFromGet, err := g.createOrGetMembership(ctx, groupID, userID) if err != nil { l.Error("aws-connector: Failed to create group membership", zap.Error(err)) return nil, nil, fmt.Errorf("baton-aws: error adding sso user to sso group: %w", err) } - annos := annotations.New() - if membership == nil { - return []*v2.Grant{}, annos, nil - } + annos.Merge(annotationsFromGet...) - grant, err := createUserSSOGroupMembershipGrant( - g.region, - awsSdk.ToString(g.identityInstance.IdentityStoreId), - userID, - membership.MembershipId, - entitlement.Resource, - ) - if err != nil { - l.Error("aws-connector: Failed to create grant", zap.Error(err), zap.String("membership_id", awsSdk.ToString(membership.MembershipId))) - return nil, nil, err - } + if membership != nil { + grant, err := createUserSSOGroupMembershipGrant( + g.region, + awsSdk.ToString(g.identityInstance.IdentityStoreId), + userID, + membership.MembershipId, + entitlement.Resource, + ) + if err != nil { + l.Error( + "aws-connector: Failed to create grant", + zap.Error(err), + zap.String("membership_id", awsSdk.ToString(membership.MembershipId)), + ) + return nil, nil, err + } - if reqId := extractRequestID(&membership.ResultMetadata); reqId != nil { - annos.Append(reqId) + if reqId := extractRequestID(&membership.ResultMetadata); reqId != nil { + annos.Append(reqId) + } + outputGrants = append(outputGrants, grant) } - return []*v2.Grant{grant}, annos, nil + return outputGrants, annos, nil } func (g *ssoGroupResourceType) Revoke(ctx context.Context, grant *v2.Grant) (annotations.Annotations, error) { if grant.Principal.Id.ResourceType != resourceTypeSSOUser.Id {