diff --git a/go.mod b/go.mod index a654ab42..d775477b 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/organizations v1.22.3 github.com/aws/aws-sdk-go-v2/service/ssoadmin v1.22.1 github.com/aws/aws-sdk-go-v2/service/sts v1.25.4 - github.com/conductorone/baton-sdk v0.1.11 + github.com/conductorone/baton-sdk v0.1.13 github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 github.com/spf13/cobra v1.8.0 go.uber.org/zap v1.26.0 diff --git a/go.sum b/go.sum index 9cd4e6ad..8373c5e9 100644 --- a/go.sum +++ b/go.sum @@ -97,8 +97,10 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/conductorone/baton-sdk v0.1.11 h1:DO24e1WahpZ/Llqz01Vn1qQj3YYoj7+haGh7Ulz7hNs= -github.com/conductorone/baton-sdk v0.1.11/go.mod h1:mxMxyna5UNmh9T+uQL4UApk0Ers0unkL1SGGnwjoCoc= +github.com/conductorone/baton-sdk v0.1.13-0.20231129230901-6a4866e4e0ec h1:kslx2qju4psh9Em6TUhZaJXxpc9aLqzaL9ScwqgmnVA= +github.com/conductorone/baton-sdk v0.1.13-0.20231129230901-6a4866e4e0ec/go.mod h1:mxMxyna5UNmh9T+uQL4UApk0Ers0unkL1SGGnwjoCoc= +github.com/conductorone/baton-sdk v0.1.13 h1:FO+HzH32TSH+CragU5R/dG+07nEescHatbc+D5Sol8Y= +github.com/conductorone/baton-sdk v0.1.13/go.mod h1:mxMxyna5UNmh9T+uQL4UApk0Ers0unkL1SGGnwjoCoc= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/pkg/connector/sso_group.go b/pkg/connector/sso_group.go index f340b9b8..57b0af2a 100644 --- a/pkg/connector/sso_group.go +++ b/pkg/connector/sso_group.go @@ -103,6 +103,28 @@ func (o *ssoGroupResourceType) Entitlements(_ context.Context, resource *v2.Reso return []*v2.Entitlement{member}, "", nil, nil } +func createUserSSOGroupMembershipGrant(region string, identityStoreID string, memberID string, membershipID *string, groupResource *v2.Resource) (*v2.Grant, error) { + userARN := ssoUserToARN(region, identityStoreID, memberID) + uID, err := resourceSdk.NewResourceID(resourceTypeSSOUser, userARN) + if err != nil { + return nil, err + } + grant := grantSdk.NewGrant(groupResource, groupMemberEntitlement, uID, + grantSdk.WithAnnotation( + &v2.V1Identifier{ + Id: V1GrantID(V1MembershipEntitlementID(groupResource.Id), userARN), + }, + ), + ) + + // MembershipID should always be not-nil here but let's guard ourselves + // Just use the MembershipID as the grant ID so that we can easily revoke it later + if membershipID != nil { + grant.Id = *membershipID + } + return grant, nil +} + func (o *ssoGroupResourceType) Grants(ctx context.Context, resource *v2.Resource, pt *pagination.Token) ([]*v2.Grant, string, annotations.Annotations, error) { bag := &pagination.Bag{} err := bag.Unmarshal(pt.Token) @@ -133,24 +155,16 @@ func (o *ssoGroupResourceType) Grants(ctx context.Context, resource *v2.Resource if !ok { continue } - userARN := ssoUserToARN(o.region, awsSdk.ToString(o.identityInstance.IdentityStoreId), member.Value) - uID, err := resourceSdk.NewResourceID(resourceTypeSSOUser, userARN) + grant, err := createUserSSOGroupMembershipGrant( + o.region, + awsSdk.ToString(o.identityInstance.IdentityStoreId), + member.Value, + user.MembershipId, + resource, + ) if err != nil { return nil, "", nil, err } - grant := grantSdk.NewGrant(resource, groupMemberEntitlement, uID, - grantSdk.WithAnnotation( - &v2.V1Identifier{ - Id: V1GrantID(V1MembershipEntitlementID(resource.Id), userARN), - }, - ), - ) - - // MembershipID should always be not-nil here but let's guard ourselves - // Just use the MembershipID as the grant ID so that we can easily revoke it later - if user.MembershipId != nil { - grant.Id = *user.MembershipId - } rv = append(rv, grant) } nextPage, err := bag.Marshal() @@ -170,19 +184,19 @@ func ssoGroupBuilder(region string, ssoClient *awsSsoAdmin.Client, identityStore } } -func (g *ssoGroupResourceType) Grant(ctx context.Context, principal *v2.Resource, entitlement *v2.Entitlement) (annotations.Annotations, error) { +func (g *ssoGroupResourceType) Grant(ctx context.Context, principal *v2.Resource, entitlement *v2.Entitlement) ([]*v2.Grant, annotations.Annotations, error) { if principal.Id.ResourceType != resourceTypeSSOUser.Id { - return nil, errors.New("baton-aws: only sso users can be added to a sso group") + return nil, nil, errors.New("baton-aws: only sso users can be added to a sso group") } groupID, err := ssoGroupIdFromARN(entitlement.Resource.Id.Resource) if err != nil { - return nil, err + return nil, nil, err } userID, err := ssoUserIdFromARN(principal.Id.Resource) if err != nil { - return nil, err + return nil, nil, err } input := &awsIdentityStore.CreateGroupMembershipInput{ @@ -191,11 +205,22 @@ func (g *ssoGroupResourceType) Grant(ctx context.Context, principal *v2.Resource MemberId: &awsIdentityStoreTypes.MemberIdMemberUserId{Value: userID}, } - if _, err := g.identityStoreClient.CreateGroupMembership(ctx, input); err != nil { - return nil, fmt.Errorf("baton-aws: error adding sso user to sso group: %w", err) + membership, err := g.identityStoreClient.CreateGroupMembership(ctx, input) + if err != nil { + return nil, nil, fmt.Errorf("baton-aws: error adding sso user to sso group: %w", err) } - return nil, nil + grant, err := createUserSSOGroupMembershipGrant( + g.region, + awsSdk.ToString(g.identityInstance.IdentityStoreId), + userID, + membership.MembershipId, + entitlement.Resource, + ) + if err != nil { + return nil, nil, err + } + return []*v2.Grant{grant}, nil, nil } func (g *ssoGroupResourceType) Revoke(ctx context.Context, grant *v2.Grant) (annotations.Annotations, error) { if grant.Principal.Id.ResourceType != resourceTypeSSOUser.Id { diff --git a/vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/grant.pb.go b/vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/grant.pb.go index 60625d76..bd316c69 100644 --- a/vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/grant.pb.go +++ b/vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/grant.pb.go @@ -351,6 +351,7 @@ type GrantManagerServiceGrantResponse struct { unknownFields protoimpl.UnknownFields Annotations []*anypb.Any `protobuf:"bytes,1,rep,name=annotations,proto3" json:"annotations,omitempty"` + Grants []*Grant `protobuf:"bytes,2,rep,name=grants,proto3" json:"grants,omitempty"` } func (x *GrantManagerServiceGrantResponse) Reset() { @@ -392,6 +393,13 @@ func (x *GrantManagerServiceGrantResponse) GetAnnotations() []*anypb.Any { return nil } +func (x *GrantManagerServiceGrantResponse) GetGrants() []*Grant { + if x != nil { + return x.Grants + } + return nil +} + type GrantManagerServiceRevokeRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -618,56 +626,59 @@ var file_c1_connector_v2_grant_proto_rawDesc = []byte{ 0x70, 0x61, 0x6c, 0x12, 0x36, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x0b, - 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x5a, 0x0a, 0x20, 0x47, - 0x72, 0x61, 0x6e, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x36, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x92, 0x01, 0x0a, 0x20, 0x47, 0x72, 0x61, 0x6e, - 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, - 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x36, 0x0a, 0x05, - 0x67, 0x72, 0x61, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x31, - 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x72, - 0x61, 0x6e, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x05, 0x67, - 0x72, 0x61, 0x6e, 0x74, 0x12, 0x36, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, - 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x5b, 0x0a, 0x21, + 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x8a, 0x01, 0x0a, 0x20, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x36, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x0b, 0x61, 0x6e, - 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x32, 0x80, 0x01, 0x0a, 0x0d, 0x47, 0x72, - 0x61, 0x6e, 0x74, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6f, 0x0a, 0x0a, 0x4c, - 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x2f, 0x2e, 0x63, 0x31, 0x2e, 0x63, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x72, 0x61, 0x6e, - 0x74, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, - 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x63, 0x31, 0x2e, + 0x69, 0x63, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x36, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2e, 0x0a, 0x06, 0x67, 0x72, 0x61, 0x6e, + 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x31, 0x2e, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, + 0x52, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x22, 0x92, 0x01, 0x0a, 0x20, 0x47, 0x72, 0x61, + 0x6e, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x36, 0x0a, + 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, + 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x47, + 0x72, 0x61, 0x6e, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x05, + 0x67, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x36, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, + 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x5b, 0x0a, + 0x21, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x36, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x0b, 0x61, + 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x32, 0x80, 0x01, 0x0a, 0x0d, 0x47, + 0x72, 0x61, 0x6e, 0x74, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6f, 0x0a, 0x0a, + 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x2f, 0x2e, 0x63, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, - 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xf4, 0x01, 0x0a, - 0x13, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x12, 0x6c, 0x0a, 0x05, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x30, 0x2e, + 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x63, 0x31, + 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x72, + 0x61, 0x6e, 0x74, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x47, + 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xf4, 0x01, + 0x0a, 0x13, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6c, 0x0a, 0x05, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x30, + 0x2e, 0x63, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x32, + 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x31, 0x2e, 0x63, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, + 0x76, 0x32, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x06, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x12, 0x31, 0x2e, 0x63, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x31, 0x2e, 0x63, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x76, - 0x32, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x06, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x12, 0x31, 0x2e, 0x63, - 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x47, - 0x72, 0x61, 0x6e, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x32, 0x2e, 0x63, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x76, - 0x32, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x64, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x6f, 0x6e, 0x65, 0x2f, 0x62, - 0x61, 0x74, 0x6f, 0x6e, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x70, 0x62, 0x2f, 0x63, 0x31, 0x2f, 0x63, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2f, 0x76, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x69, 0x63, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x32, 0x2e, 0x63, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, + 0x76, 0x32, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x64, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x6f, 0x6e, 0x65, 0x2f, + 0x62, 0x61, 0x74, 0x6f, 0x6e, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x70, 0x62, 0x2f, 0x63, 0x31, 0x2f, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2f, 0x76, 0x32, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -712,21 +723,22 @@ var file_c1_connector_v2_grant_proto_depIdxs = []int32{ 11, // 10: c1.connector.v2.GrantManagerServiceGrantRequest.principal:type_name -> c1.connector.v2.Resource 12, // 11: c1.connector.v2.GrantManagerServiceGrantRequest.annotations:type_name -> google.protobuf.Any 12, // 12: c1.connector.v2.GrantManagerServiceGrantResponse.annotations:type_name -> google.protobuf.Any - 1, // 13: c1.connector.v2.GrantManagerServiceRevokeRequest.grant:type_name -> c1.connector.v2.Grant - 12, // 14: c1.connector.v2.GrantManagerServiceRevokeRequest.annotations:type_name -> google.protobuf.Any - 12, // 15: c1.connector.v2.GrantManagerServiceRevokeResponse.annotations:type_name -> google.protobuf.Any - 8, // 16: c1.connector.v2.GrantSources.SourcesEntry.value:type_name -> c1.connector.v2.GrantSources.GrantSource - 2, // 17: c1.connector.v2.GrantsService.ListGrants:input_type -> c1.connector.v2.GrantsServiceListGrantsRequest - 4, // 18: c1.connector.v2.GrantManagerService.Grant:input_type -> c1.connector.v2.GrantManagerServiceGrantRequest - 6, // 19: c1.connector.v2.GrantManagerService.Revoke:input_type -> c1.connector.v2.GrantManagerServiceRevokeRequest - 3, // 20: c1.connector.v2.GrantsService.ListGrants:output_type -> c1.connector.v2.GrantsServiceListGrantsResponse - 5, // 21: c1.connector.v2.GrantManagerService.Grant:output_type -> c1.connector.v2.GrantManagerServiceGrantResponse - 7, // 22: c1.connector.v2.GrantManagerService.Revoke:output_type -> c1.connector.v2.GrantManagerServiceRevokeResponse - 20, // [20:23] is the sub-list for method output_type - 17, // [17:20] is the sub-list for method input_type - 17, // [17:17] is the sub-list for extension type_name - 17, // [17:17] is the sub-list for extension extendee - 0, // [0:17] is the sub-list for field type_name + 1, // 13: c1.connector.v2.GrantManagerServiceGrantResponse.grants:type_name -> c1.connector.v2.Grant + 1, // 14: c1.connector.v2.GrantManagerServiceRevokeRequest.grant:type_name -> c1.connector.v2.Grant + 12, // 15: c1.connector.v2.GrantManagerServiceRevokeRequest.annotations:type_name -> google.protobuf.Any + 12, // 16: c1.connector.v2.GrantManagerServiceRevokeResponse.annotations:type_name -> google.protobuf.Any + 8, // 17: c1.connector.v2.GrantSources.SourcesEntry.value:type_name -> c1.connector.v2.GrantSources.GrantSource + 2, // 18: c1.connector.v2.GrantsService.ListGrants:input_type -> c1.connector.v2.GrantsServiceListGrantsRequest + 4, // 19: c1.connector.v2.GrantManagerService.Grant:input_type -> c1.connector.v2.GrantManagerServiceGrantRequest + 6, // 20: c1.connector.v2.GrantManagerService.Revoke:input_type -> c1.connector.v2.GrantManagerServiceRevokeRequest + 3, // 21: c1.connector.v2.GrantsService.ListGrants:output_type -> c1.connector.v2.GrantsServiceListGrantsResponse + 5, // 22: c1.connector.v2.GrantManagerService.Grant:output_type -> c1.connector.v2.GrantManagerServiceGrantResponse + 7, // 23: c1.connector.v2.GrantManagerService.Revoke:output_type -> c1.connector.v2.GrantManagerServiceRevokeResponse + 21, // [21:24] is the sub-list for method output_type + 18, // [18:21] is the sub-list for method input_type + 18, // [18:18] is the sub-list for extension type_name + 18, // [18:18] is the sub-list for extension extendee + 0, // [0:18] is the sub-list for field type_name } func init() { file_c1_connector_v2_grant_proto_init() } diff --git a/vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/grant.pb.validate.go b/vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/grant.pb.validate.go index 5f5437f6..02b76497 100644 --- a/vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/grant.pb.validate.go +++ b/vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/grant.pb.validate.go @@ -1099,6 +1099,40 @@ func (m *GrantManagerServiceGrantResponse) validate(all bool) error { } + for idx, item := range m.GetGrants() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, GrantManagerServiceGrantResponseValidationError{ + field: fmt.Sprintf("Grants[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, GrantManagerServiceGrantResponseValidationError{ + field: fmt.Sprintf("Grants[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return GrantManagerServiceGrantResponseValidationError{ + field: fmt.Sprintf("Grants[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + if len(errors) > 0 { return GrantManagerServiceGrantResponseMultiError(errors) } diff --git a/vendor/github.com/conductorone/baton-sdk/pkg/connectorbuilder/connectorbuilder.go b/vendor/github.com/conductorone/baton-sdk/pkg/connectorbuilder/connectorbuilder.go index cb2f4672..fdd43ac3 100644 --- a/vendor/github.com/conductorone/baton-sdk/pkg/connectorbuilder/connectorbuilder.go +++ b/vendor/github.com/conductorone/baton-sdk/pkg/connectorbuilder/connectorbuilder.go @@ -4,12 +4,13 @@ import ( "context" "fmt" + "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap" + "go.uber.org/zap" + v2 "github.com/conductorone/baton-sdk/pb/c1/connector/v2" "github.com/conductorone/baton-sdk/pkg/annotations" "github.com/conductorone/baton-sdk/pkg/pagination" "github.com/conductorone/baton-sdk/pkg/types" - "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap" - "go.uber.org/zap" ) type ResourceSyncer interface { @@ -25,6 +26,12 @@ type ResourceProvisioner interface { Revoke(ctx context.Context, grant *v2.Grant) (annotations.Annotations, error) } +type ResourceProvisionerV2 interface { + ResourceType(ctx context.Context) *v2.ResourceType + Grant(ctx context.Context, resource *v2.Resource, entitlement *v2.Entitlement) ([]*v2.Grant, annotations.Annotations, error) + Revoke(ctx context.Context, grant *v2.Grant) (annotations.Annotations, error) +} + type ConnectorBuilder interface { Metadata(ctx context.Context) (*v2.ConnectorMetadata, error) Validate(ctx context.Context) (annotations.Annotations, error) @@ -32,9 +39,10 @@ type ConnectorBuilder interface { } type builderImpl struct { - resourceBuilders map[string]ResourceSyncer - resourceProvisioners map[string]ResourceProvisioner - cb ConnectorBuilder + resourceBuilders map[string]ResourceSyncer + resourceProvisioners map[string]ResourceProvisioner + resourceProvisionersV2 map[string]ResourceProvisionerV2 + cb ConnectorBuilder } // NewConnector creates a new ConnectorServer for a new resource. @@ -42,9 +50,10 @@ func NewConnector(ctx context.Context, in interface{}) (types.ConnectorServer, e switch c := in.(type) { case ConnectorBuilder: ret := &builderImpl{ - resourceBuilders: make(map[string]ResourceSyncer), - resourceProvisioners: make(map[string]ResourceProvisioner), - cb: c, + resourceBuilders: make(map[string]ResourceSyncer), + resourceProvisioners: make(map[string]ResourceProvisioner), + resourceProvisionersV2: make(map[string]ResourceProvisionerV2), + cb: c, } for _, rb := range c.ResourceSyncers(ctx) { @@ -53,12 +62,23 @@ func NewConnector(ctx context.Context, in interface{}) (types.ConnectorServer, e return nil, fmt.Errorf("error: duplicate resource type found %s", rType.Id) } ret.resourceBuilders[rType.Id] = rb + + if err := validateProvisionerVersion(ctx, rb); err != nil { + return nil, err + } + if provisioner, ok := rb.(ResourceProvisioner); ok { if _, ok := ret.resourceProvisioners[rType.Id]; ok { return nil, fmt.Errorf("error: duplicate resource type found %s", rType.Id) } ret.resourceProvisioners[rType.Id] = provisioner } + if provisioner, ok := rb.(ResourceProvisionerV2); ok { + if _, ok := ret.resourceProvisionersV2[rType.Id]; ok { + return nil, fmt.Errorf("error: duplicate resource type found %s", rType.Id) + } + ret.resourceProvisionersV2[rType.Id] = provisioner + } } return ret, nil @@ -70,6 +90,16 @@ func NewConnector(ctx context.Context, in interface{}) (types.ConnectorServer, e } } +func validateProvisionerVersion(ctx context.Context, p ResourceSyncer) error { + _, ok := p.(ResourceProvisioner) + _, okV2 := p.(ResourceProvisionerV2) + + if ok && okV2 { + return fmt.Errorf("error: resource type %s implements both ResourceProvisioner and ResourceProvisionerV2", p.ResourceType(ctx).Id) + } + return nil +} + // ListResourceTypes lists all available resource types. func (b *builderImpl) ListResourceTypes( ctx context.Context, @@ -194,18 +224,29 @@ func (b *builderImpl) Grant(ctx context.Context, request *v2.GrantManagerService rt := request.Entitlement.Resource.Id.ResourceType provisioner, ok := b.resourceProvisioners[rt] - if !ok { - l.Error("error: resource type does not have provisioner configured", zap.String("resource_type", rt)) - return nil, fmt.Errorf("error: resource type does not have provisioner configured") + if ok { + annos, err := provisioner.Grant(ctx, request.Principal, request.Entitlement) + if err != nil { + l.Error("error: grant failed", zap.Error(err)) + return nil, fmt.Errorf("error: grant failed: %w", err) + } + + return &v2.GrantManagerServiceGrantResponse{Annotations: annos}, nil } - annos, err := provisioner.Grant(ctx, request.Principal, request.Entitlement) - if err != nil { - l.Error("error: grant failed", zap.Error(err)) - return nil, fmt.Errorf("error: grant failed: %w", err) + provisionerV2, ok := b.resourceProvisionersV2[rt] + if ok { + grants, annos, err := provisionerV2.Grant(ctx, request.Principal, request.Entitlement) + if err != nil { + l.Error("error: grant failed", zap.Error(err)) + return nil, fmt.Errorf("error: grant failed: %w", err) + } + + return &v2.GrantManagerServiceGrantResponse{Annotations: annos, Grants: grants}, nil } - return &v2.GrantManagerServiceGrantResponse{Annotations: annos}, nil + l.Error("error: resource type does not have provisioner configured", zap.String("resource_type", rt)) + return nil, fmt.Errorf("error: resource type does not have provisioner configured") } func (b *builderImpl) Revoke(ctx context.Context, request *v2.GrantManagerServiceRevokeRequest) (*v2.GrantManagerServiceRevokeResponse, error) { @@ -213,18 +254,27 @@ func (b *builderImpl) Revoke(ctx context.Context, request *v2.GrantManagerServic rt := request.Grant.Entitlement.Resource.Id.ResourceType provisioner, ok := b.resourceProvisioners[rt] - if !ok { - l.Error("error: resource type does not have provisioner configured", zap.String("resource_type", rt)) - return nil, fmt.Errorf("error: resource type does not have provisioner configured") + if ok { + annos, err := provisioner.Revoke(ctx, request.Grant) + if err != nil { + l.Error("error: revoke failed", zap.Error(err)) + return nil, fmt.Errorf("error: revoke failed: %w", err) + } + return &v2.GrantManagerServiceRevokeResponse{Annotations: annos}, nil } - annos, err := provisioner.Revoke(ctx, request.Grant) - if err != nil { - l.Error("error: revoke failed", zap.Error(err)) - return nil, fmt.Errorf("error: revoke failed: %w", err) + provisionerV2, ok := b.resourceProvisionersV2[rt] + if ok { + annos, err := provisionerV2.Revoke(ctx, request.Grant) + if err != nil { + l.Error("error: revoke failed", zap.Error(err)) + return nil, fmt.Errorf("error: revoke failed: %w", err) + } + return &v2.GrantManagerServiceRevokeResponse{Annotations: annos}, nil } - return &v2.GrantManagerServiceRevokeResponse{Annotations: annos}, nil + l.Error("error: resource type does not have provisioner configured", zap.String("resource_type", rt)) + return nil, fmt.Errorf("error: resource type does not have provisioner configured") } // GetAsset streams the asset to the client. diff --git a/vendor/modules.txt b/vendor/modules.txt index 95acf414..8e8f553b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -150,7 +150,7 @@ github.com/aws/smithy-go/waiter # github.com/benbjohnson/clock v1.3.5 ## explicit; go 1.15 github.com/benbjohnson/clock -# github.com/conductorone/baton-sdk v0.1.11 +# github.com/conductorone/baton-sdk v0.1.13 ## explicit; go 1.20 github.com/conductorone/baton-sdk/internal/connector github.com/conductorone/baton-sdk/pb/c1/c1z/v1