diff --git a/README.md b/README.md index 366527d5..5710b473 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,9 @@ GRANT SELECT ("id", "name") ON organizations TO baton; GRANT SELECT ("id", "name", "organizationId", "folderId", "photoUrl", "description", "deletedAt") ON pages TO baton; GRANT SELECT ("id", "name", "organizationId", "type", "displayName", "environmentId", "resourceFolderId") ON resources TO baton; GRANT SELECT ("id", "email", "firstName", "lastName", "profilePhotoUrl", "userName", "enabled", "lastLoggedIn", "organizationId") ON users TO baton; -GRANT SELECT, INSERT, UPDATE ("id", "userId", "groupId", "isAdmin", "updatedAt") ON user_groups TO baton; +GRANT SELECT, INSERT, UPDATE, DELETE ("id", "userId", "groupId", "isAdmin", "updatedAt") ON user_groups TO baton; GRANT USAGE, SELECT ON SEQUENCE user_groups_id_seq TO baton; +GRANT DELETE ON user_groups TO baton; ``` 3. Run the connector with the proper connection string. For example if you created a new `baton` user with the password `baton`, it may look like this: diff --git a/pkg/client/group.go b/pkg/client/group.go index 2c104ef5..f5ed4da2 100644 --- a/pkg/client/group.go +++ b/pkg/client/group.go @@ -331,3 +331,21 @@ func (c *Client) UpdateGroupMember(ctx context.Context, groupID, userID int64, i return c.GetGroupMember(ctx, groupID, userID) } + +func (c *Client) RemoveGroupMember(ctx context.Context, groupID, userID int64) error { + l := ctxzap.Extract(ctx) + l.Debug("remove user from group", zap.Int64("user_id", userID)) + + args := []interface{}{groupID, userID} + sb := &strings.Builder{} + _, err := sb.WriteString(`DELETE FROM user_groups WHERE "groupId"=$1 AND "userId"=$2`) + if err != nil { + return err + } + + if _, err := c.db.Exec(ctx, sb.String(), args...); err != nil { + return err + } + + return nil +} diff --git a/pkg/connector/groups.go b/pkg/connector/groups.go index 03dfc313..343784c6 100644 --- a/pkg/connector/groups.go +++ b/pkg/connector/groups.go @@ -210,6 +210,39 @@ func (o *groupSyncer) Grant(ctx context.Context, principial *v2.Resource, entitl } func (o *groupSyncer) Revoke(ctx context.Context, grant *v2.Grant) (annotations.Annotations, error) { + l := ctxzap.Extract(ctx) + + entitlement := grant.Entitlement + principial := grant.Principal + + if principial.Id.ResourceType != resourceTypeUser.Id { + l.Warn( + "only users can be added to the group", + zap.String("principal_id", principial.Id.Resource), + zap.String("principal_type", principial.Id.ResourceType), + ) + } + + groupID, err := parseObjectID(entitlement.Resource.Id.Resource) + if err != nil { + return nil, err + } + userID, err := parseObjectID(principial.Id.Resource) + if err != nil { + return nil, err + } + + err = o.client.RemoveGroupMember(ctx, groupID, userID) + if err != nil { + l.Error( + err.Error(), + zap.String("principal_id", principial.Id.Resource), + zap.String("principal_type", principial.Id.ResourceType), + ) + + return nil, err + } + return nil, nil }