diff --git a/go.mod b/go.mod index a4b4f21e..159ffb8c 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/conductorone/baton-demo go 1.20 require ( - github.com/conductorone/baton-sdk v0.1.5 + github.com/conductorone/baton-sdk v0.1.6 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 go.uber.org/zap v1.24.0 ) diff --git a/go.sum b/go.sum index 5b382059..437bcf3d 100644 --- a/go.sum +++ b/go.sum @@ -89,8 +89,8 @@ 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.5 h1:53fmUiolrAWhRVXBwVAK42uRQiwZU0bVtAziS/HEkbk= -github.com/conductorone/baton-sdk v0.1.5/go.mod h1:lU1sLusR2oqts/k5BvYhoNKQ4Nl9qG8slJD/YEcKt9E= +github.com/conductorone/baton-sdk v0.1.6 h1:xGjVs5qrkEuhbEyi78Xv2d4fe4G8xECWuM5kQgadTcM= +github.com/conductorone/baton-sdk v0.1.6/go.mod h1:lU1sLusR2oqts/k5BvYhoNKQ4Nl9qG8slJD/YEcKt9E= github.com/cpuguy83/go-md2man/v2 v2.0.2/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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= diff --git a/pkg/client/data.go b/pkg/client/data.go index 75bb78d0..9d88e88f 100644 --- a/pkg/client/data.go +++ b/pkg/client/data.go @@ -46,8 +46,9 @@ func generateDB() *database { "2IC0Wo34fcTerFEgWmyffXmfrW8", // Carol }, Members: []string{ - "2IC0Wn5oRQqVVn3COFl1O1zSzV6", // Alice - "2IC0WoNfqUPT7mgO4FOaViIxBrR", // Bob + "2IC0Wn5oRQqVVn3COFl1O1zSzV6", // Alice + "2IC0WoNfqUPT7mgO4FOaViIxBrR", // Bob + "group:2VJleiE6zMPoTHbKDjLC1zJkUir", // Expanded Engineers Group }, }, { @@ -60,6 +61,15 @@ func generateDB() *database { "2IC0Wn7DaxV1xqDpdg7jJRiPtCp", // Dan }, }, + { + Id: "2VJleiE6zMPoTHbKDjLC1zJkUir", + Name: "Expanded Engineers", + Admins: []string{}, + Members: []string{ + "2IC0WoaHVvl2GIQppXQH0flK1yJ", // Frank + "2IC0Wn7DaxV1xqDpdg7jJRiPtCp", // Dan + }, + }, } db.Roles = []*Role{ diff --git a/pkg/connector/groups.go b/pkg/connector/groups.go index 77ddf38c..fbfad7c3 100644 --- a/pkg/connector/groups.go +++ b/pkg/connector/groups.go @@ -3,14 +3,16 @@ package connector import ( "context" "fmt" + "strings" - "github.com/conductorone/baton-demo/pkg/client" v2 "github.com/conductorone/baton-sdk/pb/c1/connector/v2" "github.com/conductorone/baton-sdk/pkg/annotations" "github.com/conductorone/baton-sdk/pkg/pagination" sdkEntitlement "github.com/conductorone/baton-sdk/pkg/types/entitlement" sdkGrant "github.com/conductorone/baton-sdk/pkg/types/grant" sdkResource "github.com/conductorone/baton-sdk/pkg/types/resource" + + "github.com/conductorone/baton-demo/pkg/client" ) var ( @@ -56,8 +58,7 @@ func (o *groupBuilder) List(ctx context.Context, parentResourceID *v2.ResourceId return ret, "", nil, nil } -// Entitlements returns a membership and admin entitlement. -func (o *groupBuilder) Entitlements(ctx context.Context, resource *v2.Resource, _ *pagination.Token) ([]*v2.Entitlement, string, annotations.Annotations, error) { +func (o *groupBuilder) entitlements(ctx context.Context, resource *v2.Resource) (*v2.Entitlement, *v2.Entitlement) { // This entitlement represents being a member of the group, and it can be granted to Users. member := sdkEntitlement.NewAssignmentEntitlement(resource, groupMemberEntitlement, sdkEntitlement.WithGrantableTo(userResourceType)) member.Description = fmt.Sprintf("Is a member of the %s group", resource.DisplayName) @@ -65,6 +66,13 @@ func (o *groupBuilder) Entitlements(ctx context.Context, resource *v2.Resource, admin := sdkEntitlement.NewPermissionEntitlement(resource, groupAdminEntitlement, sdkEntitlement.WithGrantableTo(userResourceType)) admin.Description = fmt.Sprintf("Is an admin of the %s group", resource.DisplayName) + return member, admin +} + +// Entitlements returns a membership and admin entitlement. +func (o *groupBuilder) Entitlements(ctx context.Context, resource *v2.Resource, _ *pagination.Token) ([]*v2.Entitlement, string, annotations.Annotations, error) { + // This entitlement represents being a member of the group, and it can be granted to Users. + member, admin := o.entitlements(ctx, resource) return []*v2.Entitlement{member, admin}, "", nil, nil } @@ -89,12 +97,35 @@ func (o *groupBuilder) Grants(ctx context.Context, resource *v2.Resource, pToken } for _, memberID := range grp.Members { - pID, err := sdkResource.NewResourceID(userResourceType, memberID) - if err != nil { - return nil, "", nil, err + var pID *v2.ResourceId + if strings.HasPrefix(memberID, "group:") { + memberID = strings.TrimPrefix(memberID, "group:") + pID, err = sdkResource.NewResourceID(groupResourceType, memberID) + if err != nil { + return nil, "", nil, err + } + + g := sdkGrant.NewGrant(resource, groupMemberEntitlement, pID) + + // FIXME(morgabra): Make a helper/refactor this: + member, admin := o.entitlements(ctx, &v2.Resource{Id: &v2.ResourceId{ + ResourceType: groupResourceType.Id, + Resource: memberID, + }}) + annos := annotations.Annotations(g.Annotations) + annos.Append(&v2.GrantExpandable{ + EntitlementIds: []string{member.Id, admin.Id}, + }) + g.Annotations = annos + ret = append(ret, g) + } else { + pID, err = sdkResource.NewResourceID(userResourceType, memberID) + if err != nil { + return nil, "", nil, err + } + ret = append(ret, sdkGrant.NewGrant(resource, groupMemberEntitlement, pID)) } - ret = append(ret, sdkGrant.NewGrant(resource, groupMemberEntitlement, pID)) } return ret, "", nil, nil diff --git a/pkg/connector/projects.go b/pkg/connector/projects.go index ccc1eefe..aa9c8f1b 100644 --- a/pkg/connector/projects.go +++ b/pkg/connector/projects.go @@ -3,14 +3,16 @@ package connector import ( "context" "fmt" + "strings" - "github.com/conductorone/baton-demo/pkg/client" v2 "github.com/conductorone/baton-sdk/pb/c1/connector/v2" "github.com/conductorone/baton-sdk/pkg/annotations" "github.com/conductorone/baton-sdk/pkg/pagination" sdkEntitlement "github.com/conductorone/baton-sdk/pkg/types/entitlement" sdkGrant "github.com/conductorone/baton-sdk/pkg/types/grant" sdkResource "github.com/conductorone/baton-sdk/pkg/types/resource" + + "github.com/conductorone/baton-demo/pkg/client" ) var ( @@ -94,6 +96,10 @@ func (o *projectBuilder) Grants(ctx context.Context, resource *v2.Resource, pTok } for _, userID := range append(grp.Admins, grp.Members...) { + // FIXME(morgabra): What should we do here? + if strings.HasPrefix(userID, "group:") { + continue + } pID, err := sdkResource.NewResourceID(userResourceType, userID) if err != nil { return nil, "", nil, err diff --git a/pkg/connector/roles.go b/pkg/connector/roles.go index 59ab2f22..1529f557 100644 --- a/pkg/connector/roles.go +++ b/pkg/connector/roles.go @@ -4,13 +4,14 @@ import ( "context" "fmt" - "github.com/conductorone/baton-demo/pkg/client" v2 "github.com/conductorone/baton-sdk/pb/c1/connector/v2" "github.com/conductorone/baton-sdk/pkg/annotations" "github.com/conductorone/baton-sdk/pkg/pagination" sdkEntitlement "github.com/conductorone/baton-sdk/pkg/types/entitlement" sdkGrant "github.com/conductorone/baton-sdk/pkg/types/grant" sdkResource "github.com/conductorone/baton-sdk/pkg/types/resource" + + "github.com/conductorone/baton-demo/pkg/client" ) var ( @@ -81,23 +82,15 @@ func (o *roleBuilder) Grants(ctx context.Context, resource *v2.Resource, pToken return nil, "", nil, err } - ret = append(ret, sdkGrant.NewGrant(resource, roleAssignmentEntitlement, pID)) - - // Look up group and iterate its members - grp, err := o.client.GetGroup(ctx, grpID) - if err != nil { - return nil, "", nil, err + expandAnno := &v2.GrantExpandable{ + EntitlementIds: []string{ + fmt.Sprintf("group:%s:member", grpID), + fmt.Sprintf("group:%s:admin", grpID), + }, + Shallow: true, } - // Grant all admins and members the assignment entitlement - for _, userID := range append(grp.Admins, grp.Members...) { - pID, err := sdkResource.NewResourceID(userResourceType, userID) - if err != nil { - return nil, "", nil, err - } - - ret = append(ret, sdkGrant.NewGrant(resource, roleAssignmentEntitlement, pID)) - } + ret = append(ret, sdkGrant.NewGrant(resource, roleAssignmentEntitlement, pID, sdkGrant.WithAnnotation(expandAnno))) } return ret, "", nil, nil diff --git a/vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/annotation_grant.pb.go b/vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/annotation_grant.pb.go index 58e83873..79578697 100644 --- a/vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/annotation_grant.pb.go +++ b/vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/annotation_grant.pb.go @@ -68,6 +68,69 @@ func (x *GrantMetadata) GetMetadata() *structpb.Struct { return nil } +type GrantExpandable struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + EntitlementIds []string `protobuf:"bytes,1,rep,name=entitlement_ids,json=entitlementIds,proto3" json:"entitlement_ids,omitempty"` + Shallow bool `protobuf:"varint,2,opt,name=shallow,proto3" json:"shallow,omitempty"` + ResourceTypeIds []string `protobuf:"bytes,3,rep,name=resource_type_ids,json=resourceTypeIds,proto3" json:"resource_type_ids,omitempty"` +} + +func (x *GrantExpandable) Reset() { + *x = GrantExpandable{} + if protoimpl.UnsafeEnabled { + mi := &file_c1_connector_v2_annotation_grant_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GrantExpandable) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GrantExpandable) ProtoMessage() {} + +func (x *GrantExpandable) ProtoReflect() protoreflect.Message { + mi := &file_c1_connector_v2_annotation_grant_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GrantExpandable.ProtoReflect.Descriptor instead. +func (*GrantExpandable) Descriptor() ([]byte, []int) { + return file_c1_connector_v2_annotation_grant_proto_rawDescGZIP(), []int{1} +} + +func (x *GrantExpandable) GetEntitlementIds() []string { + if x != nil { + return x.EntitlementIds + } + return nil +} + +func (x *GrantExpandable) GetShallow() bool { + if x != nil { + return x.Shallow + } + return false +} + +func (x *GrantExpandable) GetResourceTypeIds() []string { + if x != nil { + return x.ResourceTypeIds + } + return nil +} + var File_c1_connector_v2_annotation_grant_proto protoreflect.FileDescriptor var file_c1_connector_v2_annotation_grant_proto_rawDesc = []byte{ @@ -80,11 +143,19 @@ var file_c1_connector_v2_annotation_grant_proto_rawDesc = []byte{ 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, - 0x75, 0x63, 0x74, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 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, + 0x75, 0x63, 0x74, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x80, 0x01, + 0x0a, 0x0f, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x45, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x61, 0x62, 0x6c, + 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x68, + 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x68, 0x61, + 0x6c, 0x6c, 0x6f, 0x77, 0x12, 0x2a, 0x0a, 0x11, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x49, 0x64, 0x73, + 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 ( @@ -99,13 +170,14 @@ func file_c1_connector_v2_annotation_grant_proto_rawDescGZIP() []byte { return file_c1_connector_v2_annotation_grant_proto_rawDescData } -var file_c1_connector_v2_annotation_grant_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_c1_connector_v2_annotation_grant_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_c1_connector_v2_annotation_grant_proto_goTypes = []interface{}{ (*GrantMetadata)(nil), // 0: c1.connector.v2.GrantMetadata - (*structpb.Struct)(nil), // 1: google.protobuf.Struct + (*GrantExpandable)(nil), // 1: c1.connector.v2.GrantExpandable + (*structpb.Struct)(nil), // 2: google.protobuf.Struct } var file_c1_connector_v2_annotation_grant_proto_depIdxs = []int32{ - 1, // 0: c1.connector.v2.GrantMetadata.metadata:type_name -> google.protobuf.Struct + 2, // 0: c1.connector.v2.GrantMetadata.metadata:type_name -> google.protobuf.Struct 1, // [1:1] is the sub-list for method output_type 1, // [1:1] is the sub-list for method input_type 1, // [1:1] is the sub-list for extension type_name @@ -131,6 +203,18 @@ func file_c1_connector_v2_annotation_grant_proto_init() { return nil } } + file_c1_connector_v2_annotation_grant_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GrantExpandable); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -138,7 +222,7 @@ func file_c1_connector_v2_annotation_grant_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_c1_connector_v2_annotation_grant_proto_rawDesc, NumEnums: 0, - NumMessages: 1, + NumMessages: 2, NumExtensions: 0, NumServices: 0, }, diff --git a/vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/annotation_grant.pb.validate.go b/vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/annotation_grant.pb.validate.go index d296634b..05d3ff2d 100644 --- a/vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/annotation_grant.pb.validate.go +++ b/vendor/github.com/conductorone/baton-sdk/pb/c1/connector/v2/annotation_grant.pb.validate.go @@ -163,3 +163,105 @@ var _ interface { Cause() error ErrorName() string } = GrantMetadataValidationError{} + +// Validate checks the field values on GrantExpandable with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *GrantExpandable) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GrantExpandable with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// GrantExpandableMultiError, or nil if none found. +func (m *GrantExpandable) ValidateAll() error { + return m.validate(true) +} + +func (m *GrantExpandable) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Shallow + + if len(errors) > 0 { + return GrantExpandableMultiError(errors) + } + + return nil +} + +// GrantExpandableMultiError is an error wrapping multiple validation errors +// returned by GrantExpandable.ValidateAll() if the designated constraints +// aren't met. +type GrantExpandableMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GrantExpandableMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GrantExpandableMultiError) AllErrors() []error { return m } + +// GrantExpandableValidationError is the validation error returned by +// GrantExpandable.Validate if the designated constraints aren't met. +type GrantExpandableValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GrantExpandableValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GrantExpandableValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GrantExpandableValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GrantExpandableValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GrantExpandableValidationError) ErrorName() string { return "GrantExpandableValidationError" } + +// Error satisfies the builtin error interface +func (e GrantExpandableValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sGrantExpandable.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GrantExpandableValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GrantExpandableValidationError{} 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 09e5e6e1..60625d76 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 @@ -22,21 +22,69 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type GrantSources struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Sources map[string]*GrantSources_GrantSource `protobuf:"bytes,1,rep,name=sources,proto3" json:"sources,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *GrantSources) Reset() { + *x = GrantSources{} + if protoimpl.UnsafeEnabled { + mi := &file_c1_connector_v2_grant_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GrantSources) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GrantSources) ProtoMessage() {} + +func (x *GrantSources) ProtoReflect() protoreflect.Message { + mi := &file_c1_connector_v2_grant_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GrantSources.ProtoReflect.Descriptor instead. +func (*GrantSources) Descriptor() ([]byte, []int) { + return file_c1_connector_v2_grant_proto_rawDescGZIP(), []int{0} +} + +func (x *GrantSources) GetSources() map[string]*GrantSources_GrantSource { + if x != nil { + return x.Sources + } + return nil +} + type Grant struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Entitlement *Entitlement `protobuf:"bytes,1,opt,name=entitlement,proto3" json:"entitlement,omitempty"` - Principal *Resource `protobuf:"bytes,2,opt,name=principal,proto3" json:"principal,omitempty"` - Id string `protobuf:"bytes,3,opt,name=id,proto3" json:"id,omitempty"` - Annotations []*anypb.Any `protobuf:"bytes,4,rep,name=annotations,proto3" json:"annotations,omitempty"` + Entitlement *Entitlement `protobuf:"bytes,1,opt,name=entitlement,proto3" json:"entitlement,omitempty"` + Principal *Resource `protobuf:"bytes,2,opt,name=principal,proto3" json:"principal,omitempty"` + Id string `protobuf:"bytes,3,opt,name=id,proto3" json:"id,omitempty"` + Sources *GrantSources `protobuf:"bytes,5,opt,name=sources,proto3" json:"sources,omitempty"` + Annotations []*anypb.Any `protobuf:"bytes,4,rep,name=annotations,proto3" json:"annotations,omitempty"` } func (x *Grant) Reset() { *x = Grant{} if protoimpl.UnsafeEnabled { - mi := &file_c1_connector_v2_grant_proto_msgTypes[0] + mi := &file_c1_connector_v2_grant_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -49,7 +97,7 @@ func (x *Grant) String() string { func (*Grant) ProtoMessage() {} func (x *Grant) ProtoReflect() protoreflect.Message { - mi := &file_c1_connector_v2_grant_proto_msgTypes[0] + mi := &file_c1_connector_v2_grant_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -62,7 +110,7 @@ func (x *Grant) ProtoReflect() protoreflect.Message { // Deprecated: Use Grant.ProtoReflect.Descriptor instead. func (*Grant) Descriptor() ([]byte, []int) { - return file_c1_connector_v2_grant_proto_rawDescGZIP(), []int{0} + return file_c1_connector_v2_grant_proto_rawDescGZIP(), []int{1} } func (x *Grant) GetEntitlement() *Entitlement { @@ -86,6 +134,13 @@ func (x *Grant) GetId() string { return "" } +func (x *Grant) GetSources() *GrantSources { + if x != nil { + return x.Sources + } + return nil +} + func (x *Grant) GetAnnotations() []*anypb.Any { if x != nil { return x.Annotations @@ -107,7 +162,7 @@ type GrantsServiceListGrantsRequest struct { func (x *GrantsServiceListGrantsRequest) Reset() { *x = GrantsServiceListGrantsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_c1_connector_v2_grant_proto_msgTypes[1] + mi := &file_c1_connector_v2_grant_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -120,7 +175,7 @@ func (x *GrantsServiceListGrantsRequest) String() string { func (*GrantsServiceListGrantsRequest) ProtoMessage() {} func (x *GrantsServiceListGrantsRequest) ProtoReflect() protoreflect.Message { - mi := &file_c1_connector_v2_grant_proto_msgTypes[1] + mi := &file_c1_connector_v2_grant_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -133,7 +188,7 @@ func (x *GrantsServiceListGrantsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GrantsServiceListGrantsRequest.ProtoReflect.Descriptor instead. func (*GrantsServiceListGrantsRequest) Descriptor() ([]byte, []int) { - return file_c1_connector_v2_grant_proto_rawDescGZIP(), []int{1} + return file_c1_connector_v2_grant_proto_rawDescGZIP(), []int{2} } func (x *GrantsServiceListGrantsRequest) GetResource() *Resource { @@ -177,7 +232,7 @@ type GrantsServiceListGrantsResponse struct { func (x *GrantsServiceListGrantsResponse) Reset() { *x = GrantsServiceListGrantsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_c1_connector_v2_grant_proto_msgTypes[2] + mi := &file_c1_connector_v2_grant_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -190,7 +245,7 @@ func (x *GrantsServiceListGrantsResponse) String() string { func (*GrantsServiceListGrantsResponse) ProtoMessage() {} func (x *GrantsServiceListGrantsResponse) ProtoReflect() protoreflect.Message { - mi := &file_c1_connector_v2_grant_proto_msgTypes[2] + mi := &file_c1_connector_v2_grant_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -203,7 +258,7 @@ func (x *GrantsServiceListGrantsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GrantsServiceListGrantsResponse.ProtoReflect.Descriptor instead. func (*GrantsServiceListGrantsResponse) Descriptor() ([]byte, []int) { - return file_c1_connector_v2_grant_proto_rawDescGZIP(), []int{2} + return file_c1_connector_v2_grant_proto_rawDescGZIP(), []int{3} } func (x *GrantsServiceListGrantsResponse) GetList() []*Grant { @@ -240,7 +295,7 @@ type GrantManagerServiceGrantRequest struct { func (x *GrantManagerServiceGrantRequest) Reset() { *x = GrantManagerServiceGrantRequest{} if protoimpl.UnsafeEnabled { - mi := &file_c1_connector_v2_grant_proto_msgTypes[3] + mi := &file_c1_connector_v2_grant_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -253,7 +308,7 @@ func (x *GrantManagerServiceGrantRequest) String() string { func (*GrantManagerServiceGrantRequest) ProtoMessage() {} func (x *GrantManagerServiceGrantRequest) ProtoReflect() protoreflect.Message { - mi := &file_c1_connector_v2_grant_proto_msgTypes[3] + mi := &file_c1_connector_v2_grant_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -266,7 +321,7 @@ func (x *GrantManagerServiceGrantRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GrantManagerServiceGrantRequest.ProtoReflect.Descriptor instead. func (*GrantManagerServiceGrantRequest) Descriptor() ([]byte, []int) { - return file_c1_connector_v2_grant_proto_rawDescGZIP(), []int{3} + return file_c1_connector_v2_grant_proto_rawDescGZIP(), []int{4} } func (x *GrantManagerServiceGrantRequest) GetEntitlement() *Entitlement { @@ -301,7 +356,7 @@ type GrantManagerServiceGrantResponse struct { func (x *GrantManagerServiceGrantResponse) Reset() { *x = GrantManagerServiceGrantResponse{} if protoimpl.UnsafeEnabled { - mi := &file_c1_connector_v2_grant_proto_msgTypes[4] + mi := &file_c1_connector_v2_grant_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -314,7 +369,7 @@ func (x *GrantManagerServiceGrantResponse) String() string { func (*GrantManagerServiceGrantResponse) ProtoMessage() {} func (x *GrantManagerServiceGrantResponse) ProtoReflect() protoreflect.Message { - mi := &file_c1_connector_v2_grant_proto_msgTypes[4] + mi := &file_c1_connector_v2_grant_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -327,7 +382,7 @@ func (x *GrantManagerServiceGrantResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GrantManagerServiceGrantResponse.ProtoReflect.Descriptor instead. func (*GrantManagerServiceGrantResponse) Descriptor() ([]byte, []int) { - return file_c1_connector_v2_grant_proto_rawDescGZIP(), []int{4} + return file_c1_connector_v2_grant_proto_rawDescGZIP(), []int{5} } func (x *GrantManagerServiceGrantResponse) GetAnnotations() []*anypb.Any { @@ -349,7 +404,7 @@ type GrantManagerServiceRevokeRequest struct { func (x *GrantManagerServiceRevokeRequest) Reset() { *x = GrantManagerServiceRevokeRequest{} if protoimpl.UnsafeEnabled { - mi := &file_c1_connector_v2_grant_proto_msgTypes[5] + mi := &file_c1_connector_v2_grant_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -362,7 +417,7 @@ func (x *GrantManagerServiceRevokeRequest) String() string { func (*GrantManagerServiceRevokeRequest) ProtoMessage() {} func (x *GrantManagerServiceRevokeRequest) ProtoReflect() protoreflect.Message { - mi := &file_c1_connector_v2_grant_proto_msgTypes[5] + mi := &file_c1_connector_v2_grant_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -375,7 +430,7 @@ func (x *GrantManagerServiceRevokeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GrantManagerServiceRevokeRequest.ProtoReflect.Descriptor instead. func (*GrantManagerServiceRevokeRequest) Descriptor() ([]byte, []int) { - return file_c1_connector_v2_grant_proto_rawDescGZIP(), []int{5} + return file_c1_connector_v2_grant_proto_rawDescGZIP(), []int{6} } func (x *GrantManagerServiceRevokeRequest) GetGrant() *Grant { @@ -403,7 +458,7 @@ type GrantManagerServiceRevokeResponse struct { func (x *GrantManagerServiceRevokeResponse) Reset() { *x = GrantManagerServiceRevokeResponse{} if protoimpl.UnsafeEnabled { - mi := &file_c1_connector_v2_grant_proto_msgTypes[6] + mi := &file_c1_connector_v2_grant_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -416,7 +471,7 @@ func (x *GrantManagerServiceRevokeResponse) String() string { func (*GrantManagerServiceRevokeResponse) ProtoMessage() {} func (x *GrantManagerServiceRevokeResponse) ProtoReflect() protoreflect.Message { - mi := &file_c1_connector_v2_grant_proto_msgTypes[6] + mi := &file_c1_connector_v2_grant_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -429,7 +484,7 @@ func (x *GrantManagerServiceRevokeResponse) ProtoReflect() protoreflect.Message // Deprecated: Use GrantManagerServiceRevokeResponse.ProtoReflect.Descriptor instead. func (*GrantManagerServiceRevokeResponse) Descriptor() ([]byte, []int) { - return file_c1_connector_v2_grant_proto_rawDescGZIP(), []int{6} + return file_c1_connector_v2_grant_proto_rawDescGZIP(), []int{7} } func (x *GrantManagerServiceRevokeResponse) GetAnnotations() []*anypb.Any { @@ -439,6 +494,44 @@ func (x *GrantManagerServiceRevokeResponse) GetAnnotations() []*anypb.Any { return nil } +type GrantSources_GrantSource struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GrantSources_GrantSource) Reset() { + *x = GrantSources_GrantSource{} + if protoimpl.UnsafeEnabled { + mi := &file_c1_connector_v2_grant_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GrantSources_GrantSource) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GrantSources_GrantSource) ProtoMessage() {} + +func (x *GrantSources_GrantSource) ProtoReflect() protoreflect.Message { + mi := &file_c1_connector_v2_grant_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GrantSources_GrantSource.ProtoReflect.Descriptor instead. +func (*GrantSources_GrantSource) Descriptor() ([]byte, []int) { + return file_c1_connector_v2_grant_proto_rawDescGZIP(), []int{0, 0} +} + var File_c1_connector_v2_grant_proto protoreflect.FileDescriptor var file_c1_connector_v2_grant_proto_rawDesc = []byte{ @@ -452,18 +545,35 @@ var file_c1_connector_v2_grant_proto_rawDesc = []byte{ 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe8, 0x01, 0x0a, 0x05, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x12, - 0x48, 0x0a, 0x0b, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0b, 0x65, 0x6e, - 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x41, 0x0a, 0x09, 0x70, 0x72, 0x69, - 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, - 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, - 0x01, 0x52, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x12, 0x1a, 0x0a, 0x02, - 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xfa, 0x42, 0x07, 0x72, 0x05, 0x20, - 0x01, 0x28, 0x80, 0x08, 0x52, 0x02, 0x69, 0x64, 0x12, 0x36, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xca, 0x01, 0x0a, 0x0c, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x53, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x44, 0x0a, 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63, 0x31, 0x2e, 0x63, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x53, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x1a, 0x0d, 0x0a, 0x0b, + 0x47, 0x72, 0x61, 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x1a, 0x65, 0x0a, 0x0c, 0x53, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3f, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, + 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x47, + 0x72, 0x61, 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x47, 0x72, 0x61, 0x6e, + 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, + 0x38, 0x01, 0x22, 0xab, 0x02, 0x0a, 0x05, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x48, 0x0a, 0x0b, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, + 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0b, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x41, 0x0a, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, + 0x70, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x31, 0x2e, 0x63, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x09, + 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x12, 0x1a, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xfa, 0x42, 0x07, 0x72, 0x05, 0x20, 0x01, 0x28, 0x80, + 0x08, 0x52, 0x02, 0x69, 0x64, 0x12, 0x41, 0x0a, 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x63, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x53, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x00, 0x52, + 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x36, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 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, @@ -572,45 +682,51 @@ func file_c1_connector_v2_grant_proto_rawDescGZIP() []byte { return file_c1_connector_v2_grant_proto_rawDescData } -var file_c1_connector_v2_grant_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_c1_connector_v2_grant_proto_msgTypes = make([]protoimpl.MessageInfo, 10) var file_c1_connector_v2_grant_proto_goTypes = []interface{}{ - (*Grant)(nil), // 0: c1.connector.v2.Grant - (*GrantsServiceListGrantsRequest)(nil), // 1: c1.connector.v2.GrantsServiceListGrantsRequest - (*GrantsServiceListGrantsResponse)(nil), // 2: c1.connector.v2.GrantsServiceListGrantsResponse - (*GrantManagerServiceGrantRequest)(nil), // 3: c1.connector.v2.GrantManagerServiceGrantRequest - (*GrantManagerServiceGrantResponse)(nil), // 4: c1.connector.v2.GrantManagerServiceGrantResponse - (*GrantManagerServiceRevokeRequest)(nil), // 5: c1.connector.v2.GrantManagerServiceRevokeRequest - (*GrantManagerServiceRevokeResponse)(nil), // 6: c1.connector.v2.GrantManagerServiceRevokeResponse - (*Entitlement)(nil), // 7: c1.connector.v2.Entitlement - (*Resource)(nil), // 8: c1.connector.v2.Resource - (*anypb.Any)(nil), // 9: google.protobuf.Any + (*GrantSources)(nil), // 0: c1.connector.v2.GrantSources + (*Grant)(nil), // 1: c1.connector.v2.Grant + (*GrantsServiceListGrantsRequest)(nil), // 2: c1.connector.v2.GrantsServiceListGrantsRequest + (*GrantsServiceListGrantsResponse)(nil), // 3: c1.connector.v2.GrantsServiceListGrantsResponse + (*GrantManagerServiceGrantRequest)(nil), // 4: c1.connector.v2.GrantManagerServiceGrantRequest + (*GrantManagerServiceGrantResponse)(nil), // 5: c1.connector.v2.GrantManagerServiceGrantResponse + (*GrantManagerServiceRevokeRequest)(nil), // 6: c1.connector.v2.GrantManagerServiceRevokeRequest + (*GrantManagerServiceRevokeResponse)(nil), // 7: c1.connector.v2.GrantManagerServiceRevokeResponse + (*GrantSources_GrantSource)(nil), // 8: c1.connector.v2.GrantSources.GrantSource + nil, // 9: c1.connector.v2.GrantSources.SourcesEntry + (*Entitlement)(nil), // 10: c1.connector.v2.Entitlement + (*Resource)(nil), // 11: c1.connector.v2.Resource + (*anypb.Any)(nil), // 12: google.protobuf.Any } var file_c1_connector_v2_grant_proto_depIdxs = []int32{ - 7, // 0: c1.connector.v2.Grant.entitlement:type_name -> c1.connector.v2.Entitlement - 8, // 1: c1.connector.v2.Grant.principal:type_name -> c1.connector.v2.Resource - 9, // 2: c1.connector.v2.Grant.annotations:type_name -> google.protobuf.Any - 8, // 3: c1.connector.v2.GrantsServiceListGrantsRequest.resource:type_name -> c1.connector.v2.Resource - 9, // 4: c1.connector.v2.GrantsServiceListGrantsRequest.annotations:type_name -> google.protobuf.Any - 0, // 5: c1.connector.v2.GrantsServiceListGrantsResponse.list:type_name -> c1.connector.v2.Grant - 9, // 6: c1.connector.v2.GrantsServiceListGrantsResponse.annotations:type_name -> google.protobuf.Any - 7, // 7: c1.connector.v2.GrantManagerServiceGrantRequest.entitlement:type_name -> c1.connector.v2.Entitlement - 8, // 8: c1.connector.v2.GrantManagerServiceGrantRequest.principal:type_name -> c1.connector.v2.Resource - 9, // 9: c1.connector.v2.GrantManagerServiceGrantRequest.annotations:type_name -> google.protobuf.Any - 9, // 10: c1.connector.v2.GrantManagerServiceGrantResponse.annotations:type_name -> google.protobuf.Any - 0, // 11: c1.connector.v2.GrantManagerServiceRevokeRequest.grant:type_name -> c1.connector.v2.Grant - 9, // 12: c1.connector.v2.GrantManagerServiceRevokeRequest.annotations:type_name -> google.protobuf.Any - 9, // 13: c1.connector.v2.GrantManagerServiceRevokeResponse.annotations:type_name -> google.protobuf.Any - 1, // 14: c1.connector.v2.GrantsService.ListGrants:input_type -> c1.connector.v2.GrantsServiceListGrantsRequest - 3, // 15: c1.connector.v2.GrantManagerService.Grant:input_type -> c1.connector.v2.GrantManagerServiceGrantRequest - 5, // 16: c1.connector.v2.GrantManagerService.Revoke:input_type -> c1.connector.v2.GrantManagerServiceRevokeRequest - 2, // 17: c1.connector.v2.GrantsService.ListGrants:output_type -> c1.connector.v2.GrantsServiceListGrantsResponse - 4, // 18: c1.connector.v2.GrantManagerService.Grant:output_type -> c1.connector.v2.GrantManagerServiceGrantResponse - 6, // 19: c1.connector.v2.GrantManagerService.Revoke:output_type -> c1.connector.v2.GrantManagerServiceRevokeResponse - 17, // [17:20] is the sub-list for method output_type - 14, // [14:17] is the sub-list for method input_type - 14, // [14:14] is the sub-list for extension type_name - 14, // [14:14] is the sub-list for extension extendee - 0, // [0:14] is the sub-list for field type_name + 9, // 0: c1.connector.v2.GrantSources.sources:type_name -> c1.connector.v2.GrantSources.SourcesEntry + 10, // 1: c1.connector.v2.Grant.entitlement:type_name -> c1.connector.v2.Entitlement + 11, // 2: c1.connector.v2.Grant.principal:type_name -> c1.connector.v2.Resource + 0, // 3: c1.connector.v2.Grant.sources:type_name -> c1.connector.v2.GrantSources + 12, // 4: c1.connector.v2.Grant.annotations:type_name -> google.protobuf.Any + 11, // 5: c1.connector.v2.GrantsServiceListGrantsRequest.resource:type_name -> c1.connector.v2.Resource + 12, // 6: c1.connector.v2.GrantsServiceListGrantsRequest.annotations:type_name -> google.protobuf.Any + 1, // 7: c1.connector.v2.GrantsServiceListGrantsResponse.list:type_name -> c1.connector.v2.Grant + 12, // 8: c1.connector.v2.GrantsServiceListGrantsResponse.annotations:type_name -> google.protobuf.Any + 10, // 9: c1.connector.v2.GrantManagerServiceGrantRequest.entitlement:type_name -> c1.connector.v2.Entitlement + 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 } func init() { file_c1_connector_v2_grant_proto_init() } @@ -622,7 +738,7 @@ func file_c1_connector_v2_grant_proto_init() { file_c1_connector_v2_resource_proto_init() if !protoimpl.UnsafeEnabled { file_c1_connector_v2_grant_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Grant); i { + switch v := v.(*GrantSources); i { case 0: return &v.state case 1: @@ -634,7 +750,7 @@ func file_c1_connector_v2_grant_proto_init() { } } file_c1_connector_v2_grant_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GrantsServiceListGrantsRequest); i { + switch v := v.(*Grant); i { case 0: return &v.state case 1: @@ -646,7 +762,7 @@ func file_c1_connector_v2_grant_proto_init() { } } file_c1_connector_v2_grant_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GrantsServiceListGrantsResponse); i { + switch v := v.(*GrantsServiceListGrantsRequest); i { case 0: return &v.state case 1: @@ -658,7 +774,7 @@ func file_c1_connector_v2_grant_proto_init() { } } file_c1_connector_v2_grant_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GrantManagerServiceGrantRequest); i { + switch v := v.(*GrantsServiceListGrantsResponse); i { case 0: return &v.state case 1: @@ -670,7 +786,7 @@ func file_c1_connector_v2_grant_proto_init() { } } file_c1_connector_v2_grant_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GrantManagerServiceGrantResponse); i { + switch v := v.(*GrantManagerServiceGrantRequest); i { case 0: return &v.state case 1: @@ -682,7 +798,7 @@ func file_c1_connector_v2_grant_proto_init() { } } file_c1_connector_v2_grant_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GrantManagerServiceRevokeRequest); i { + switch v := v.(*GrantManagerServiceGrantResponse); i { case 0: return &v.state case 1: @@ -694,6 +810,18 @@ func file_c1_connector_v2_grant_proto_init() { } } file_c1_connector_v2_grant_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GrantManagerServiceRevokeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_c1_connector_v2_grant_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GrantManagerServiceRevokeResponse); i { case 0: return &v.state @@ -705,6 +833,18 @@ func file_c1_connector_v2_grant_proto_init() { return nil } } + file_c1_connector_v2_grant_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GrantSources_GrantSource); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -712,7 +852,7 @@ func file_c1_connector_v2_grant_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_c1_connector_v2_grant_proto_rawDesc, NumEnums: 0, - NumMessages: 7, + NumMessages: 10, NumExtensions: 0, NumServices: 2, }, 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 3b3fd63e..5f5437f6 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 @@ -35,6 +35,151 @@ var ( _ = sort.Sort ) +// Validate checks the field values on GrantSources with the rules defined in +// the proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *GrantSources) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GrantSources with the rules defined +// in the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in GrantSourcesMultiError, or +// nil if none found. +func (m *GrantSources) ValidateAll() error { + return m.validate(true) +} + +func (m *GrantSources) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + { + sorted_keys := make([]string, len(m.GetSources())) + i := 0 + for key := range m.GetSources() { + sorted_keys[i] = key + i++ + } + sort.Slice(sorted_keys, func(i, j int) bool { return sorted_keys[i] < sorted_keys[j] }) + for _, key := range sorted_keys { + val := m.GetSources()[key] + _ = val + + // no validation rules for Sources[key] + + if all { + switch v := interface{}(val).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, GrantSourcesValidationError{ + field: fmt.Sprintf("Sources[%v]", key), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, GrantSourcesValidationError{ + field: fmt.Sprintf("Sources[%v]", key), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(val).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return GrantSourcesValidationError{ + field: fmt.Sprintf("Sources[%v]", key), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + } + + if len(errors) > 0 { + return GrantSourcesMultiError(errors) + } + + return nil +} + +// GrantSourcesMultiError is an error wrapping multiple validation errors +// returned by GrantSources.ValidateAll() if the designated constraints aren't met. +type GrantSourcesMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GrantSourcesMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GrantSourcesMultiError) AllErrors() []error { return m } + +// GrantSourcesValidationError is the validation error returned by +// GrantSources.Validate if the designated constraints aren't met. +type GrantSourcesValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GrantSourcesValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GrantSourcesValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GrantSourcesValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GrantSourcesValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GrantSourcesValidationError) ErrorName() string { return "GrantSourcesValidationError" } + +// Error satisfies the builtin error interface +func (e GrantSourcesValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sGrantSources.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GrantSourcesValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GrantSourcesValidationError{} + // Validate checks the field values on Grant with the rules defined in the // proto definition for this message. If any rules are violated, the first // error encountered is returned, or nil if there are no violations. @@ -147,6 +292,35 @@ func (m *Grant) validate(all bool) error { errors = append(errors, err) } + if all { + switch v := interface{}(m.GetSources()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, GrantValidationError{ + field: "Sources", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, GrantValidationError{ + field: "Sources", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetSources()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return GrantValidationError{ + field: "Sources", + reason: "embedded message failed validation", + cause: err, + } + } + } + for idx, item := range m.GetAnnotations() { _, _ = idx, item @@ -1324,3 +1498,105 @@ var _ interface { Cause() error ErrorName() string } = GrantManagerServiceRevokeResponseValidationError{} + +// Validate checks the field values on GrantSources_GrantSource with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *GrantSources_GrantSource) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GrantSources_GrantSource with the +// rules defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// GrantSources_GrantSourceMultiError, or nil if none found. +func (m *GrantSources_GrantSource) ValidateAll() error { + return m.validate(true) +} + +func (m *GrantSources_GrantSource) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if len(errors) > 0 { + return GrantSources_GrantSourceMultiError(errors) + } + + return nil +} + +// GrantSources_GrantSourceMultiError is an error wrapping multiple validation +// errors returned by GrantSources_GrantSource.ValidateAll() if the designated +// constraints aren't met. +type GrantSources_GrantSourceMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GrantSources_GrantSourceMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GrantSources_GrantSourceMultiError) AllErrors() []error { return m } + +// GrantSources_GrantSourceValidationError is the validation error returned by +// GrantSources_GrantSource.Validate if the designated constraints aren't met. +type GrantSources_GrantSourceValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GrantSources_GrantSourceValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GrantSources_GrantSourceValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GrantSources_GrantSourceValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GrantSources_GrantSourceValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GrantSources_GrantSourceValidationError) ErrorName() string { + return "GrantSources_GrantSourceValidationError" +} + +// Error satisfies the builtin error interface +func (e GrantSources_GrantSourceValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sGrantSources_GrantSource.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GrantSources_GrantSourceValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GrantSources_GrantSourceValidationError{} diff --git a/vendor/github.com/conductorone/baton-sdk/pb/c1/reader/v2/grant.pb.go b/vendor/github.com/conductorone/baton-sdk/pb/c1/reader/v2/grant.pb.go index bcca484d..9d558ff4 100644 --- a/vendor/github.com/conductorone/baton-sdk/pb/c1/reader/v2/grant.pb.go +++ b/vendor/github.com/conductorone/baton-sdk/pb/c1/reader/v2/grant.pb.go @@ -123,6 +123,7 @@ type GrantsReaderServiceListGrantsForEntitlementRequest struct { unknownFields protoimpl.UnknownFields Entitlement *v2.Entitlement `protobuf:"bytes,1,opt,name=entitlement,proto3" json:"entitlement,omitempty"` + PrincipalId *v2.ResourceId `protobuf:"bytes,5,opt,name=principal_id,json=principalId,proto3" json:"principal_id,omitempty"` PageSize uint32 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` PageToken string `protobuf:"bytes,3,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` Annotations []*anypb.Any `protobuf:"bytes,4,rep,name=annotations,proto3" json:"annotations,omitempty"` @@ -167,6 +168,13 @@ func (x *GrantsReaderServiceListGrantsForEntitlementRequest) GetEntitlement() *v return nil } +func (x *GrantsReaderServiceListGrantsForEntitlementRequest) GetPrincipalId() *v2.ResourceId { + if x != nil { + return x.PrincipalId + } + return nil +} + func (x *GrantsReaderServiceListGrantsForEntitlementRequest) GetPageSize() uint32 { if x != nil { return x.PageSize @@ -378,7 +386,9 @@ var file_c1_reader_v2_grant_proto_rawDesc = []byte{ 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x63, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x63, 0x31, 0x2f, 0x63, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4b, 0x0a, 0x22, @@ -391,7 +401,7 @@ var file_c1_reader_v2_grant_proto_rawDesc = []byte{ 0x47, 0x65, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 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, 0x52, 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x22, 0x8d, + 0x32, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x22, 0xd7, 0x02, 0x0a, 0x32, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, @@ -400,84 +410,88 @@ var file_c1_reader_v2_grant_proto_rawDesc = []byte{ 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0b, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, - 0x27, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0d, 0x42, 0x0a, 0xfa, 0x42, 0x07, 0x2a, 0x05, 0x18, 0xfa, 0x01, 0x40, 0x01, 0x52, 0x08, - 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x2c, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, - 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0d, 0xfa, 0x42, - 0x0a, 0x72, 0x08, 0x20, 0x01, 0x28, 0x80, 0x10, 0xd0, 0x01, 0x01, 0x52, 0x09, 0x70, 0x61, 0x67, - 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x36, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 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, 0x98, - 0x01, 0x0a, 0x33, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, - 0x46, 0x6f, 0x72, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, - 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, 0x04, 0x6c, 0x69, - 0x73, 0x74, 0x12, 0x35, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0d, 0xfa, 0x42, 0x0a, - 0x72, 0x08, 0x20, 0x01, 0x28, 0x80, 0x10, 0xd0, 0x01, 0x01, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, - 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xfd, 0x01, 0x0a, 0x33, 0x47, 0x72, - 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x37, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0d, 0xfa, 0x42, 0x0a, - 0x72, 0x08, 0x20, 0x01, 0x28, 0x80, 0x10, 0xd0, 0x01, 0x01, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x09, 0x70, 0x61, - 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x0a, 0xfa, - 0x42, 0x07, 0x2a, 0x05, 0x18, 0xfa, 0x01, 0x40, 0x01, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, - 0x69, 0x7a, 0x65, 0x12, 0x2c, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0d, 0xfa, 0x42, 0x0a, 0x72, 0x08, 0x20, 0x01, - 0x28, 0x80, 0x10, 0xd0, 0x01, 0x01, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x12, 0x36, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x18, 0x04, 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, 0x99, 0x01, 0x0a, 0x34, 0x47, 0x72, - 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 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, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x35, - 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0d, 0xfa, 0x42, 0x0a, 0x72, 0x08, 0x20, 0x01, - 0x28, 0x80, 0x10, 0xd0, 0x01, 0x01, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x32, 0xcd, 0x03, 0x0a, 0x13, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, - 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6f, 0x0a, - 0x08, 0x47, 0x65, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x30, 0x2e, 0x63, 0x31, 0x2e, 0x72, - 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, - 0x65, 0x61, 0x64, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x47, 0x65, 0x74, 0x47, - 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x31, - 0x2e, 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, - 0x73, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x47, 0x65, - 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x9f, - 0x01, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x46, 0x6f, 0x72, - 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x40, 0x2e, 0x63, 0x31, - 0x2e, 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, - 0x73, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, - 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x45, 0x6e, 0x74, 0x69, 0x74, - 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x41, 0x2e, - 0x63, 0x31, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x72, 0x61, + 0x48, 0x0a, 0x0c, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x49, 0x64, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x00, 0x52, 0x0b, 0x70, 0x72, + 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x09, 0x70, 0x61, 0x67, + 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x0a, 0xfa, 0x42, + 0x07, 0x2a, 0x05, 0x18, 0xfa, 0x01, 0x40, 0x01, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, + 0x7a, 0x65, 0x12, 0x2c, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0d, 0xfa, 0x42, 0x0a, 0x72, 0x08, 0x20, 0x01, 0x28, + 0x80, 0x10, 0xd0, 0x01, 0x01, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x12, 0x36, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x04, 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, 0x98, 0x01, 0x0a, 0x33, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0xa2, 0x01, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x46, - 0x6f, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x41, - 0x2e, 0x63, 0x31, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x72, - 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x42, 0x2e, 0x63, 0x31, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x32, - 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x46, 0x6f, - 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x33, 0x5a, 0x31, 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, 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x12, 0x2a, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 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, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x35, 0x0a, 0x0f, + 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0d, 0xfa, 0x42, 0x0a, 0x72, 0x08, 0x20, 0x01, 0x28, 0x80, + 0x10, 0xd0, 0x01, 0x01, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x22, 0xfd, 0x01, 0x0a, 0x33, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x47, + 0x72, 0x61, 0x6e, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x10, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0d, 0xfa, 0x42, 0x0a, 0x72, 0x08, 0x20, 0x01, 0x28, 0x80, + 0x10, 0xd0, 0x01, 0x01, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x0a, 0xfa, 0x42, 0x07, 0x2a, 0x05, 0x18, 0xfa, + 0x01, 0x40, 0x01, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x2c, 0x0a, + 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x0d, 0xfa, 0x42, 0x0a, 0x72, 0x08, 0x20, 0x01, 0x28, 0x80, 0x10, 0xd0, 0x01, 0x01, + 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x36, 0x0a, 0x0b, 0x61, + 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 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, 0x99, 0x01, 0x0a, 0x34, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x47, + 0x72, 0x61, 0x6e, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x04, + 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 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, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x35, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, + 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x0d, 0xfa, 0x42, 0x0a, 0x72, 0x08, 0x20, 0x01, 0x28, 0x80, 0x10, 0xd0, 0x01, 0x01, + 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x32, + 0xcd, 0x03, 0x0a, 0x13, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6f, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x47, 0x72, + 0x61, 0x6e, 0x74, 0x12, 0x30, 0x2e, 0x63, 0x31, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, + 0x76, 0x32, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x47, 0x65, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x31, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x47, 0x65, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x9f, 0x01, 0x0a, 0x18, 0x4c, 0x69, 0x73, + 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x40, 0x2e, 0x63, 0x31, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, + 0x74, 0x73, 0x46, 0x6f, 0x72, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x41, 0x2e, 0x63, 0x31, 0x2e, 0x72, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, + 0x61, 0x6e, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0xa2, 0x01, 0x0a, 0x19, 0x4c, + 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x41, 0x2e, 0x63, 0x31, 0x2e, 0x72, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x47, + 0x72, 0x61, 0x6e, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x42, 0x2e, 0x63, 0x31, + 0x2e, 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, + 0x73, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, + 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, + 0x33, 0x5a, 0x31, 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, 0x72, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x2f, 0x76, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -502,26 +516,28 @@ var file_c1_reader_v2_grant_proto_goTypes = []interface{}{ (*GrantsReaderServiceListGrantsForResourceTypeResponse)(nil), // 5: c1.reader.v2.GrantsReaderServiceListGrantsForResourceTypeResponse (*v2.Grant)(nil), // 6: c1.connector.v2.Grant (*v2.Entitlement)(nil), // 7: c1.connector.v2.Entitlement - (*anypb.Any)(nil), // 8: google.protobuf.Any + (*v2.ResourceId)(nil), // 8: c1.connector.v2.ResourceId + (*anypb.Any)(nil), // 9: google.protobuf.Any } var file_c1_reader_v2_grant_proto_depIdxs = []int32{ - 6, // 0: c1.reader.v2.GrantsReaderServiceGetGrantResponse.grant:type_name -> c1.connector.v2.Grant - 7, // 1: c1.reader.v2.GrantsReaderServiceListGrantsForEntitlementRequest.entitlement:type_name -> c1.connector.v2.Entitlement - 8, // 2: c1.reader.v2.GrantsReaderServiceListGrantsForEntitlementRequest.annotations:type_name -> google.protobuf.Any - 6, // 3: c1.reader.v2.GrantsReaderServiceListGrantsForEntitlementResponse.list:type_name -> c1.connector.v2.Grant - 8, // 4: c1.reader.v2.GrantsReaderServiceListGrantsForResourceTypeRequest.annotations:type_name -> google.protobuf.Any - 6, // 5: c1.reader.v2.GrantsReaderServiceListGrantsForResourceTypeResponse.list:type_name -> c1.connector.v2.Grant - 0, // 6: c1.reader.v2.GrantsReaderService.GetGrant:input_type -> c1.reader.v2.GrantsReaderServiceGetGrantRequest - 2, // 7: c1.reader.v2.GrantsReaderService.ListGrantsForEntitlement:input_type -> c1.reader.v2.GrantsReaderServiceListGrantsForEntitlementRequest - 4, // 8: c1.reader.v2.GrantsReaderService.ListGrantsForResourceType:input_type -> c1.reader.v2.GrantsReaderServiceListGrantsForResourceTypeRequest - 1, // 9: c1.reader.v2.GrantsReaderService.GetGrant:output_type -> c1.reader.v2.GrantsReaderServiceGetGrantResponse - 3, // 10: c1.reader.v2.GrantsReaderService.ListGrantsForEntitlement:output_type -> c1.reader.v2.GrantsReaderServiceListGrantsForEntitlementResponse - 5, // 11: c1.reader.v2.GrantsReaderService.ListGrantsForResourceType:output_type -> c1.reader.v2.GrantsReaderServiceListGrantsForResourceTypeResponse - 9, // [9:12] is the sub-list for method output_type - 6, // [6:9] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name + 6, // 0: c1.reader.v2.GrantsReaderServiceGetGrantResponse.grant:type_name -> c1.connector.v2.Grant + 7, // 1: c1.reader.v2.GrantsReaderServiceListGrantsForEntitlementRequest.entitlement:type_name -> c1.connector.v2.Entitlement + 8, // 2: c1.reader.v2.GrantsReaderServiceListGrantsForEntitlementRequest.principal_id:type_name -> c1.connector.v2.ResourceId + 9, // 3: c1.reader.v2.GrantsReaderServiceListGrantsForEntitlementRequest.annotations:type_name -> google.protobuf.Any + 6, // 4: c1.reader.v2.GrantsReaderServiceListGrantsForEntitlementResponse.list:type_name -> c1.connector.v2.Grant + 9, // 5: c1.reader.v2.GrantsReaderServiceListGrantsForResourceTypeRequest.annotations:type_name -> google.protobuf.Any + 6, // 6: c1.reader.v2.GrantsReaderServiceListGrantsForResourceTypeResponse.list:type_name -> c1.connector.v2.Grant + 0, // 7: c1.reader.v2.GrantsReaderService.GetGrant:input_type -> c1.reader.v2.GrantsReaderServiceGetGrantRequest + 2, // 8: c1.reader.v2.GrantsReaderService.ListGrantsForEntitlement:input_type -> c1.reader.v2.GrantsReaderServiceListGrantsForEntitlementRequest + 4, // 9: c1.reader.v2.GrantsReaderService.ListGrantsForResourceType:input_type -> c1.reader.v2.GrantsReaderServiceListGrantsForResourceTypeRequest + 1, // 10: c1.reader.v2.GrantsReaderService.GetGrant:output_type -> c1.reader.v2.GrantsReaderServiceGetGrantResponse + 3, // 11: c1.reader.v2.GrantsReaderService.ListGrantsForEntitlement:output_type -> c1.reader.v2.GrantsReaderServiceListGrantsForEntitlementResponse + 5, // 12: c1.reader.v2.GrantsReaderService.ListGrantsForResourceType:output_type -> c1.reader.v2.GrantsReaderServiceListGrantsForResourceTypeResponse + 10, // [10:13] is the sub-list for method output_type + 7, // [7:10] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name } func init() { file_c1_reader_v2_grant_proto_init() } diff --git a/vendor/github.com/conductorone/baton-sdk/pb/c1/reader/v2/grant.pb.validate.go b/vendor/github.com/conductorone/baton-sdk/pb/c1/reader/v2/grant.pb.validate.go index 0d32c6f3..b6250a99 100644 --- a/vendor/github.com/conductorone/baton-sdk/pb/c1/reader/v2/grant.pb.validate.go +++ b/vendor/github.com/conductorone/baton-sdk/pb/c1/reader/v2/grant.pb.validate.go @@ -350,6 +350,35 @@ func (m *GrantsReaderServiceListGrantsForEntitlementRequest) validate(all bool) } } + if all { + switch v := interface{}(m.GetPrincipalId()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, GrantsReaderServiceListGrantsForEntitlementRequestValidationError{ + field: "PrincipalId", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, GrantsReaderServiceListGrantsForEntitlementRequestValidationError{ + field: "PrincipalId", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetPrincipalId()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return GrantsReaderServiceListGrantsForEntitlementRequestValidationError{ + field: "PrincipalId", + reason: "embedded message failed validation", + cause: err, + } + } + } + if m.GetPageSize() != 0 { if m.GetPageSize() > 250 { diff --git a/vendor/github.com/conductorone/baton-sdk/pkg/connectorrunner/runner.go b/vendor/github.com/conductorone/baton-sdk/pkg/connectorrunner/runner.go index 75d1a0ae..8a5a1805 100644 --- a/vendor/github.com/conductorone/baton-sdk/pkg/connectorrunner/runner.go +++ b/vendor/github.com/conductorone/baton-sdk/pkg/connectorrunner/runner.go @@ -211,6 +211,7 @@ type runnerConfig struct { provisioningEnabled bool grantConfig *grantConfig revokeConfig *revokeConfig + expandGrants bool } // WithRateLimiterConfig sets the RateLimiterConfig for a runner. @@ -335,6 +336,13 @@ func WithProvisioningEnabled() Option { } } +func WithExpandGrants() Option { + return func(ctx context.Context, cfg *runnerConfig) error { + cfg.expandGrants = true + return nil + } +} + // NewConnectorRunner creates a new connector runner. func NewConnectorRunner(ctx context.Context, c types.ConnectorServer, opts ...Option) (*connectorRunner, error) { runner := &connectorRunner{} @@ -385,7 +393,7 @@ func NewConnectorRunner(ctx context.Context, c types.ConnectorServer, opts ...Op tm = local.NewRevoker(ctx, cfg.c1zPath, cfg.revokeConfig.grantID) default: - tm, err = local.NewSyncer(ctx, cfg.c1zPath) + tm, err = local.NewSyncer(ctx, cfg.c1zPath, cfg.expandGrants) if err != nil { return nil, err } diff --git a/vendor/github.com/conductorone/baton-sdk/pkg/dotc1z/grants.go b/vendor/github.com/conductorone/baton-sdk/pkg/dotc1z/grants.go index 279fd5cc..1f82d58b 100644 --- a/vendor/github.com/conductorone/baton-sdk/pkg/dotc1z/grants.go +++ b/vendor/github.com/conductorone/baton-sdk/pkg/dotc1z/grants.go @@ -69,12 +69,12 @@ func (c *C1File) ListGrants(ctx context.Context, request *v2.GrantsServiceListGr ret := make([]*v2.Grant, 0, len(objs)) for _, o := range objs { - en := &v2.Grant{} - err = proto.Unmarshal(o, en) + g := &v2.Grant{} + err = proto.Unmarshal(o, g) if err != nil { return nil, err } - ret = append(ret, en) + ret = append(ret, g) } return &v2.GrantsServiceListGrantsResponse{ @@ -125,6 +125,33 @@ func (c *C1File) ListGrantsForEntitlement( }, nil } +func (c *C1File) ListGrantsForPrincipal( + ctx context.Context, + request *reader_v2.GrantsReaderServiceListGrantsForEntitlementRequest, +) (*reader_v2.GrantsReaderServiceListGrantsForEntitlementResponse, error) { + ctxzap.Extract(ctx).Debug("listing grants for entitlement") + + objs, nextPageToken, err := c.listConnectorObjects(ctx, grants.Name(), request) + if err != nil { + return nil, err + } + + ret := make([]*v2.Grant, 0, len(objs)) + for _, o := range objs { + en := &v2.Grant{} + err = proto.Unmarshal(o, en) + if err != nil { + return nil, err + } + ret = append(ret, en) + } + + return &reader_v2.GrantsReaderServiceListGrantsForEntitlementResponse{ + List: ret, + NextPageToken: nextPageToken, + }, nil +} + func (c *C1File) ListGrantsForResourceType( ctx context.Context, request *reader_v2.GrantsReaderServiceListGrantsForResourceTypeRequest, diff --git a/vendor/github.com/conductorone/baton-sdk/pkg/dotc1z/sql_helpers.go b/vendor/github.com/conductorone/baton-sdk/pkg/dotc1z/sql_helpers.go index 77a47062..b40ce01f 100644 --- a/vendor/github.com/conductorone/baton-sdk/pkg/dotc1z/sql_helpers.go +++ b/vendor/github.com/conductorone/baton-sdk/pkg/dotc1z/sql_helpers.go @@ -6,12 +6,13 @@ import ( "strconv" "time" - c1zpb "github.com/conductorone/baton-sdk/pb/c1/c1z/v1" - "github.com/conductorone/baton-sdk/pkg/annotations" "github.com/doug-martin/goqu/v9" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/anypb" + c1zpb "github.com/conductorone/baton-sdk/pb/c1/c1z/v1" + "github.com/conductorone/baton-sdk/pkg/annotations" + v2 "github.com/conductorone/baton-sdk/pb/c1/connector/v2" ) @@ -59,6 +60,11 @@ type hasEntitlementListRequest interface { GetEntitlement() *v2.Entitlement } +type hasPrincipalIdListRequest interface { + listRequest + GetPrincipalId() *v2.ResourceId +} + type protoHasID interface { proto.Message GetId() string @@ -114,25 +120,39 @@ func (c *C1File) listConnectorObjects(ctx context.Context, tableName string, req if rt != "" { q = q.Where(goqu.C("resource_type_id").Eq(rt)) } - } else if resourceIdReq, ok := req.(hasResourceIdListRequest); ok { + } + + if resourceIdReq, ok := req.(hasResourceIdListRequest); ok { r := resourceIdReq.GetResourceId() if r != nil && r.Resource != "" { q = q.Where(goqu.C("resource_id").Eq(r.Resource)) q = q.Where(goqu.C("resource_type_id").Eq(r.ResourceType)) } - } else if resourceReq, ok := req.(hasResourceListRequest); ok { + } + + if resourceReq, ok := req.(hasResourceListRequest); ok { r := resourceReq.GetResource() if r != nil { q = q.Where(goqu.C("resource_id").Eq(r.Id.Resource)) q = q.Where(goqu.C("resource_type_id").Eq(r.Id.ResourceType)) } - } else if entitlementReq, ok := req.(hasEntitlementListRequest); ok { + } + + if entitlementReq, ok := req.(hasEntitlementListRequest); ok { e := entitlementReq.GetEntitlement() if e != nil { q = q.Where(goqu.C("entitlement_id").Eq(e.Id)) } } + if principalIdReq, ok := req.(hasPrincipalIdListRequest); ok { + p := principalIdReq.GetPrincipalId() + if p != nil { + q = q.Where(goqu.C("principal_resource_id").Eq(p.Resource)) + q = q.Where(goqu.C("principal_resource_type_id").Eq(p.ResourceType)) + } + } + // If a sync is running, be sure we only select from the current values switch { case reqSyncID != "": diff --git a/vendor/github.com/conductorone/baton-sdk/pkg/sync/expand.go b/vendor/github.com/conductorone/baton-sdk/pkg/sync/expand.go new file mode 100644 index 00000000..2c569a72 --- /dev/null +++ b/vendor/github.com/conductorone/baton-sdk/pkg/sync/expand.go @@ -0,0 +1,209 @@ +package sync + +import ( + "context" + "errors" + "reflect" + + v2 "github.com/conductorone/baton-sdk/pb/c1/connector/v2" +) + +var ( + ErrNoEntitlement = errors.New("no entitlement found") +) + +type EntitlementGraphAction struct { + SourceEntitlementID string `json:"source_entitlement_id"` + DescendantEntitlementID string `json:"descendant_entitlement_id"` + Shallow bool `json:"shallow"` + ResourceTypeIDs []string `json:"resource_types_ids"` + PageToken string `json:"page_token"` +} + +type edgeInfo struct { + Expanded bool `json:"expanded"` + Shallow bool `json:"shallow"` + ResourceTypeIDs []string `json:"resource_type_ids"` +} + +type EntitlementGraph struct { + Entitlements map[string]bool `json:"entitlements"` + Edges map[string]map[string]*edgeInfo `json:"edges"` + Loaded bool `json:"loaded"` + Depth int `json:"depth"` + Actions []EntitlementGraphAction `json:"actions"` +} + +func NewEntitlementGraph(ctx context.Context) *EntitlementGraph { + return &EntitlementGraph{ + Entitlements: make(map[string]bool), + Edges: make(map[string]map[string]*edgeInfo), + } +} + +// IsExpanded returns true if all entitlements in the graph have been expanded. +func (d *EntitlementGraph) IsExpanded() bool { + for entilementID := range d.Entitlements { + if !d.IsEntitlementExpanded(entilementID) { + return false + } + } + return true +} + +// IsEntitlementExpanded returns true if all the outgoing edges for the given entitlement have been expanded. +func (d *EntitlementGraph) IsEntitlementExpanded(entitlementID string) bool { + for _, edgeInfo := range d.Edges[entitlementID] { + if !edgeInfo.Expanded { + return false + } + } + return true +} + +// HasUnexpandedAncestors returns true if the given entitlement has ancestors that have not been expanded yet. +func (d *EntitlementGraph) HasUnexpandedAncestors(entitlementID string) bool { + for _, ancestorID := range d.GetAncestors(entitlementID) { + if !d.Entitlements[ancestorID] { + return true + } + } + return false +} + +// Find the direct ancestors of the given entitlement. The 'all' flag returns all ancestors regardless of 'done' state. +func (d *EntitlementGraph) GetAncestors(entitlementID string) []string { + _, ok := d.Entitlements[entitlementID] + if !ok { + return nil + } + + ancestors := make([]string, 0) + for src, dst := range d.Edges { + if _, ok := dst[entitlementID]; ok { + ancestors = append(ancestors, src) + } + } + return ancestors +} + +// Find the direct ancestors of the given entitlement. The 'all' flag returns all ancestors regardless of 'done' state. +func (d *EntitlementGraph) GetCycles() ([][]string, bool) { + rv := make([][]string, 0) + for entitlementID := range d.Entitlements { + if len(d.GetDescendants(entitlementID)) == 0 { + continue + } + cycle, isCycle := d.getCycle([]string{entitlementID}) + if isCycle && !isInCycle(cycle, rv) { + rv = append(rv, cycle) + } + } + + return rv, len(rv) > 0 +} + +func isInCycle(newCycle []string, cycles [][]string) bool { + for _, cycle := range cycles { + if len(cycle) > 0 && reflect.DeepEqual(cycle, newCycle) { + return true + } + } + return false +} + +func shift(arr []string, n int) []string { + for i := 0; i < n; i++ { + arr = append(arr[1:], arr[0]) + } + return arr +} + +func (d *EntitlementGraph) getCycle(visits []string) ([]string, bool) { + entitlementID := visits[len(visits)-1] + for descendantID := range d.GetDescendants(entitlementID) { + tempVisits := make([]string, len(visits)) + copy(tempVisits, visits) + if descendantID == visits[0] { + // shift array so that the smallest element is first + smallestIndex := 0 + for i := range tempVisits { + if tempVisits[i] < tempVisits[smallestIndex] { + smallestIndex = i + } + } + tempVisits = shift(tempVisits, smallestIndex) + return tempVisits, true + } + for _, visit := range visits { + if visit == descendantID { + return nil, false + } + } + + tempVisits = append(tempVisits, descendantID) + return d.getCycle(tempVisits) + } + return nil, false +} + +func (d *EntitlementGraph) GetDescendants(entitlementID string) map[string]*edgeInfo { + return d.Edges[entitlementID] +} + +func (d *EntitlementGraph) HasEntitlement(entitlementID string) bool { + _, ok := d.Entitlements[entitlementID] + return ok +} + +func (d *EntitlementGraph) AddEntitlement(entitlement *v2.Entitlement) { + if _, ok := d.Entitlements[entitlement.Id]; !ok { + d.Entitlements[entitlement.Id] = false + } +} + +func (d *EntitlementGraph) MarkEdgeExpanded(sourceEntitlementID string, descendantEntitlementID string) { + _, ok := d.Edges[sourceEntitlementID] + if !ok { + return + } + _, ok = d.Edges[sourceEntitlementID][descendantEntitlementID] + if !ok { + return + } + + d.Edges[sourceEntitlementID][descendantEntitlementID].Expanded = true + + // If all edges are expanded, mark the source entitlement as expanded. + // We shouldn't care about this value but we'll set it for consistency. + allExpanded := true + for _, edgeInfo := range d.Edges[sourceEntitlementID] { + if !edgeInfo.Expanded { + allExpanded = false + break + } + } + if allExpanded { + d.Entitlements[sourceEntitlementID] = true + } +} + +func (d *EntitlementGraph) AddEdge(srcEntitlementID string, dstEntitlementID string, shallow bool, resourceTypeIDs []string) error { + if _, ok := d.Entitlements[srcEntitlementID]; !ok { + return ErrNoEntitlement + } + if _, ok := d.Entitlements[dstEntitlementID]; !ok { + return ErrNoEntitlement + } + + _, ok := d.Edges[srcEntitlementID] + if !ok { + d.Edges[srcEntitlementID] = make(map[string]*edgeInfo) + } + d.Edges[srcEntitlementID][dstEntitlementID] = &edgeInfo{ + Expanded: false, + Shallow: shallow, + ResourceTypeIDs: resourceTypeIDs, + } + return nil +} diff --git a/vendor/github.com/conductorone/baton-sdk/pkg/sync/state.go b/vendor/github.com/conductorone/baton-sdk/pkg/sync/state.go index 98eb5be7..60674f18 100644 --- a/vendor/github.com/conductorone/baton-sdk/pkg/sync/state.go +++ b/vendor/github.com/conductorone/baton-sdk/pkg/sync/state.go @@ -16,12 +16,15 @@ type State interface { NextPage(ctx context.Context, pageToken string) error ResourceTypeID(ctx context.Context) string ResourceID(ctx context.Context) string + EntitlementGraph(ctx context.Context) *EntitlementGraph ParentResourceID(ctx context.Context) string ParentResourceTypeID(ctx context.Context) string PageToken(ctx context.Context) string Current() *Action Marshal() (string, error) Unmarshal(input string) error + NeedsExpansion() bool + SetNeedsExpansion() } // ActionOp represents a sync operation. @@ -42,6 +45,8 @@ func (s ActionOp) String() string { return "list-grants" case SyncAssetsOp: return "fetch-assets" + case SyncGrantExpansionOp: + return "grant-expansion" default: return "unknown" } @@ -79,6 +84,8 @@ func newActionOp(str string) ActionOp { return SyncGrantsOp case SyncAssetsOp.String(): return SyncAssetsOp + case SyncGrantExpansionOp.String(): + return SyncGrantExpansionOp default: return UnknownOp } @@ -93,6 +100,7 @@ const ( ListResourcesForEntitlementsOp SyncGrantsOp SyncAssetsOp + SyncGrantExpansionOp ) // Action stores the current operation, page token, and optional fields for which resource is being worked with. @@ -107,16 +115,20 @@ type Action struct { // state is an object used for tracking the current status of a connector sync. It operates like a stack. type state struct { - mtx sync.RWMutex - actions []Action - currentAction *Action + mtx sync.RWMutex + actions []Action + currentAction *Action + entitlementGraph *EntitlementGraph + needsExpansion bool } // serializedToken is used to serialize the token to JSON. This separate object is used to avoid having exported fields // on the object used externally. We should interface this, probably. type serializedToken struct { - Actions []Action `json:"actions"` - CurrentAction *Action `json:"current_action"` + Actions []Action `json:"actions"` + CurrentAction *Action `json:"current_action"` + NeedsExpansion bool `json:"needs_expansion"` + EntitlementGraph *EntitlementGraph `json:"entitlement_graph"` } // push adds a new action to the stack. If there is no current state, the action is directly set to current, else @@ -179,13 +191,15 @@ func (st *state) Unmarshal(input string) error { if input != "" { err := json.Unmarshal([]byte(input), &token) if err != nil { - return fmt.Errorf("syncer token corrust: %w", err) + return fmt.Errorf("syncer token corrupt: %w", err) } st.actions = token.Actions st.currentAction = token.CurrentAction + st.needsExpansion = token.NeedsExpansion } else { st.actions = nil + st.entitlementGraph = nil st.currentAction = &Action{Op: InitOp} } @@ -198,8 +212,10 @@ func (st *state) Marshal() (string, error) { defer st.mtx.RUnlock() data, err := json.Marshal(serializedToken{ - Actions: st.actions, - CurrentAction: st.currentAction, + Actions: st.actions, + CurrentAction: st.currentAction, + NeedsExpansion: st.needsExpansion, + EntitlementGraph: st.entitlementGraph, }) if err != nil { return "", err @@ -236,6 +252,14 @@ func (st *state) NextPage(ctx context.Context, pageToken string) error { return nil } +func (st *state) NeedsExpansion() bool { + return st.needsExpansion +} + +func (st *state) SetNeedsExpansion() { + st.needsExpansion = true +} + // PageToken returns the page token for the current action. func (st *state) PageToken(ctx context.Context) string { c := st.Current() @@ -266,6 +290,18 @@ func (st *state) ResourceID(ctx context.Context) string { return c.ResourceID } +// EntitlementGraph returns the entitlement graph for the current action. +func (st *state) EntitlementGraph(ctx context.Context) *EntitlementGraph { + c := st.Current() + if c == nil { + panic("no current state") + } + if st.entitlementGraph == nil { + st.entitlementGraph = NewEntitlementGraph(ctx) + } + return st.entitlementGraph +} + func (st *state) ParentResourceID(ctx context.Context) string { c := st.Current() if c == nil { diff --git a/vendor/github.com/conductorone/baton-sdk/pkg/sync/syncer.go b/vendor/github.com/conductorone/baton-sdk/pkg/sync/syncer.go index 8f6ed263..58dcce75 100644 --- a/vendor/github.com/conductorone/baton-sdk/pkg/sync/syncer.go +++ b/vendor/github.com/conductorone/baton-sdk/pkg/sync/syncer.go @@ -9,11 +9,11 @@ import ( "io" "time" - c1zpb "github.com/conductorone/baton-sdk/pb/c1/c1z/v1" "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap" "go.uber.org/zap" "google.golang.org/protobuf/proto" + c1zpb "github.com/conductorone/baton-sdk/pb/c1/c1z/v1" v2 "github.com/conductorone/baton-sdk/pb/c1/connector/v2" reader_v2 "github.com/conductorone/baton-sdk/pb/c1/reader/v2" "github.com/conductorone/baton-sdk/pkg/annotations" @@ -131,7 +131,7 @@ func (s *syncer) Sync(ctx context.Context) error { err = context.Cause(runCtx) switch { case errors.Is(err, context.DeadlineExceeded): - l.Info("sync run duration has expired, exiting sync early", zap.String("sync_id", syncID)) + l.Debug("sync run duration has expired, exiting sync early", zap.String("sync_id", syncID)) return ErrSyncNotComplete default: l.Error("sync context cancelled", zap.String("sync_id", syncID), zap.Error(err)) @@ -147,6 +147,7 @@ func (s *syncer) Sync(ctx context.Context) error { s.state.FinishAction(ctx) // FIXME(jirwin): Disabling syncing assets for now // s.state.PushAction(ctx, Action{Op: SyncAssetsOp}) + s.state.PushAction(ctx, Action{Op: SyncGrantExpansionOp}) s.state.PushAction(ctx, Action{Op: SyncGrantsOp}) s.state.PushAction(ctx, Action{Op: SyncEntitlementsOp}) s.state.PushAction(ctx, Action{Op: SyncResourcesOp}) @@ -193,6 +194,18 @@ func (s *syncer) Sync(ctx context.Context) error { } continue + case SyncGrantExpansionOp: + if !s.state.NeedsExpansion() { + l.Debug("skipping grant expansion, no grants to expand") + s.state.FinishAction(ctx) + continue + } + + err = s.SyncGrantExpansion(ctx) + if err != nil { + return err + } + continue default: return fmt.Errorf("unexpected sync step") } @@ -281,11 +294,13 @@ func (s *syncer) getSubResources(ctx context.Context, parent *v2.Resource) error // resource, we gather any child resource types it may emit, and traverse the resource tree. func (s *syncer) SyncResources(ctx context.Context) error { if s.state.Current().ResourceTypeID == "" { - ctxzap.Extract(ctx).Info("Syncing resources...") - s.handleInitialActionForStep(ctx, *s.state.Current()) - pageToken := s.state.PageToken(ctx) + if pageToken == "" { + ctxzap.Extract(ctx).Info("Syncing resources...") + s.handleInitialActionForStep(ctx, *s.state.Current()) + } + resp, err := s.store.ListResourceTypes(ctx, &v2.ResourceTypesServiceListResourceTypesRequest{PageToken: pageToken}) if err != nil { return err @@ -437,11 +452,13 @@ func (s *syncer) shouldSkipEntitlementsAndGrants(ctx context.Context, r *v2.Reso // and pushes an action to fetch the entitelments for each resource. func (s *syncer) SyncEntitlements(ctx context.Context) error { if s.state.ResourceTypeID(ctx) == "" && s.state.ResourceID(ctx) == "" { - ctxzap.Extract(ctx).Info("Syncing entitlements...") - s.handleInitialActionForStep(ctx, *s.state.Current()) - pageToken := s.state.PageToken(ctx) + if pageToken == "" { + ctxzap.Extract(ctx).Info("Syncing entitlements...") + s.handleInitialActionForStep(ctx, *s.state.Current()) + } + resp, err := s.store.ListResources(ctx, &v2.ResourcesServiceListResourcesRequest{PageToken: pageToken}) if err != nil { return err @@ -629,11 +646,13 @@ func (s *syncer) syncAssetsForResource(ctx context.Context, resourceID *v2.Resou // SyncAssets iterates each resource in the data store, and adds an action to fetch all of the assets for that resource. func (s *syncer) SyncAssets(ctx context.Context) error { if s.state.ResourceTypeID(ctx) == "" && s.state.ResourceID(ctx) == "" { - ctxzap.Extract(ctx).Info("Syncing assets...") - s.handleInitialActionForStep(ctx, *s.state.Current()) - pageToken := s.state.PageToken(ctx) + if pageToken == "" { + ctxzap.Extract(ctx).Info("Syncing assets...") + s.handleInitialActionForStep(ctx, *s.state.Current()) + } + resp, err := s.store.ListResources(ctx, &v2.ResourcesServiceListResourcesRequest{PageToken: pageToken}) if err != nil { return err @@ -668,15 +687,127 @@ func (s *syncer) SyncAssets(ctx context.Context) error { return nil } +// SyncGrantExpansion +// TODO(morgabra) Docs +func (s *syncer) SyncGrantExpansion(ctx context.Context) error { + l := ctxzap.Extract(ctx) + entitlementGraph := s.state.EntitlementGraph(ctx) + if !entitlementGraph.Loaded { + pageToken := s.state.PageToken(ctx) + + if pageToken == "" { + ctxzap.Extract(ctx).Info("Expanding grants...") + s.handleInitialActionForStep(ctx, *s.state.Current()) + } + + resp, err := s.store.ListGrants(ctx, &v2.GrantsServiceListGrantsRequest{PageToken: pageToken}) + if err != nil { + return err + } + + // We want to take action on the next page before we push any new actions + if resp.NextPageToken != "" { + err = s.state.NextPage(ctx, resp.NextPageToken) + if err != nil { + return err + } + } else { + entitlementGraph.Loaded = true + } + + for _, grant := range resp.List { + annos := annotations.Annotations(grant.Annotations) + expandable := &v2.GrantExpandable{} + _, err := annos.Pick(expandable) + if err != nil { + return err + } + if len(expandable.GetEntitlementIds()) == 0 { + continue + } + + principalID := grant.GetPrincipal().GetId() + if principalID == nil { + return fmt.Errorf("principal id was nil") + } + + // FIXME(morgabra) Log and skip some of the error paths here? + for _, srcEntitlementID := range expandable.EntitlementIds { + ctxzap.Extract(ctx).Debug( + "Expandable entitlement found", + zap.String("src_entitlement_id", srcEntitlementID), + zap.String("dst_entitlement_id", grant.GetEntitlement().GetId()), + ) + + srcEntitlement, err := s.store.GetEntitlement(ctx, &reader_v2.EntitlementsReaderServiceGetEntitlementRequest{ + EntitlementId: srcEntitlementID, + }) + if err != nil { + return err + } + + // The expand annotation points at entitlements by id. Those entitlements' resource should match + // the current grant's principal, so we don't allow expanding arbitrary entitlements. + sourceEntitlementResourceID := srcEntitlement.GetEntitlement().GetResource().GetId() + if sourceEntitlementResourceID == nil { + return fmt.Errorf("source entitlement resource id was nil") + } + if principalID.ResourceType != sourceEntitlementResourceID.ResourceType || + principalID.Resource != sourceEntitlementResourceID.Resource { + l.Error( + "source entitlement resource id did not match grant principal id", + zap.String("grant_principal_id", principalID.String()), + zap.String("source_entitlement_resource_id", sourceEntitlementResourceID.String())) + + return fmt.Errorf("source entitlement resource id did not match grant principal id") + } + + entitlementGraph.AddEntitlement(grant.Entitlement) + entitlementGraph.AddEntitlement(srcEntitlement.GetEntitlement()) + err = entitlementGraph.AddEdge( + srcEntitlement.GetEntitlement().GetId(), + grant.GetEntitlement().GetId(), + expandable.Shallow, + expandable.ResourceTypeIds, + ) + if err != nil { + return fmt.Errorf("error adding edge to graph: %w", err) + } + } + } + return nil + } + + // Once we've loaded the graph, we can check for cycles + // TODO(mstanbCO): we should eventually add logic to handle cycles + if entitlementGraph.Loaded { + cycles, hasCycles := entitlementGraph.GetCycles() + if hasCycles { + s.state.FinishAction(ctx) + l.Error("cycles detected in entitlement graph", zap.Any("cycles", cycles)) + return fmt.Errorf("SyncGrantExpansion: %d cycle(s) detected in entitlement graph", len(cycles)) + } + } + + err := s.expandGrantsForEntitlements(ctx) + if err != nil { + return err + } + + return nil +} + // SyncGrants fetches the grants for each resource from the connector. It iterates each resource // from the datastore, and pushes a new action to sync the grants for each individual resource. func (s *syncer) SyncGrants(ctx context.Context) error { if s.state.ResourceTypeID(ctx) == "" && s.state.ResourceID(ctx) == "" { - ctxzap.Extract(ctx).Info("Syncing grants...") - s.handleInitialActionForStep(ctx, *s.state.Current()) - pageToken := s.state.PageToken(ctx) + if pageToken == "" { + ctxzap.Extract(ctx).Info("Syncing grants...") + s.handleInitialActionForStep(ctx, *s.state.Current()) + } + resp, err := s.store.ListResources(ctx, &v2.ResourcesServiceListResourcesRequest{PageToken: pageToken}) if err != nil { return err @@ -880,6 +1011,11 @@ func (s *syncer) syncGrantsForResource(ctx context.Context, resourceID *v2.Resou grants = append(grants, resp.List...) for _, grant := range grants { + grantAnnos := annotations.Annotations(grant.GetAnnotations()) + if grantAnnos.Contains(&v2.GrantExpandable{}) { + s.state.SetNeedsExpansion() + } + err = s.store.PutGrant(ctx, grant) if err != nil { return err @@ -928,6 +1064,248 @@ func (s *syncer) syncGrantsForResource(ctx context.Context, resourceID *v2.Resou return nil } +func (s *syncer) runGrantExpandActions(ctx context.Context) (bool, error) { + l := ctxzap.Extract(ctx) + + graph := s.state.EntitlementGraph(ctx) + l = l.With(zap.Int("depth", graph.Depth)) + l.Debug("runGrantExpandActions: start", zap.Any("graph", graph)) + + // Peek the next action on the stack + if len(graph.Actions) == 0 { + return true, nil + } + action := graph.Actions[0] + + l = l.With(zap.String("source_entitlement_id", action.SourceEntitlementID), zap.String("descendant_entitlement_id", action.DescendantEntitlementID)) + + // Fetch source and descendant entitlement + sourceEntitlement, err := s.store.GetEntitlement(ctx, &reader_v2.EntitlementsReaderServiceGetEntitlementRequest{ + EntitlementId: action.SourceEntitlementID, + }) + if err != nil { + l.Error("runGrantExpandActions: error fetching source entitlement", zap.Error(err)) + return false, fmt.Errorf("runGrantExpandActions: error fetching source entitlement: %w", err) + } + + descendantEntitlement, err := s.store.GetEntitlement(ctx, &reader_v2.EntitlementsReaderServiceGetEntitlementRequest{ + EntitlementId: action.DescendantEntitlementID, + }) + if err != nil { + l.Error("runGrantExpandActions: error fetching descendant entitlement", zap.Error(err)) + return false, fmt.Errorf("runGrantExpandActions: error fetching descendant entitlement: %w", err) + } + + // Fetch a page of source grants + sourceGrants, err := s.store.ListGrantsForEntitlement(ctx, &reader_v2.GrantsReaderServiceListGrantsForEntitlementRequest{ + Entitlement: sourceEntitlement.GetEntitlement(), + PageSize: 1000, + PageToken: action.PageToken, + }) + if err != nil { + l.Error("runGrantExpandActions: error fetching source grants", zap.Error(err)) + return false, fmt.Errorf("runGrantExpandActions: error fetching source grants: %w", err) + } + + for _, sourceGrant := range sourceGrants.List { + // Skip this grant if it is not for a resource type we care about + if len(action.ResourceTypeIDs) > 0 { + relevantResourceType := false + for _, resourceTypeID := range action.ResourceTypeIDs { + if sourceGrant.GetPrincipal().Id.ResourceType == resourceTypeID { + relevantResourceType = true + break + } + } + + if !relevantResourceType { + continue + } + } + + // If this is a shallow action, then we only want to expand grants that have no sources which indicates that it was directly assigned. + if action.Shallow { + // If we have no sources, this is a direct grant + foundDirectGrant := len(sourceGrant.GetSources().GetSources()) == 0 + // If the source grant has sources, then we need to see if any of them are the source entitlement itself + for src := range sourceGrant.GetSources().GetSources() { + if src == sourceEntitlement.GetEntitlement().GetId() { + foundDirectGrant = true + break + } + } + + // This is not a direct grant, so skip it since we are a shallow action + if !foundDirectGrant { + continue + } + } + + // Unroll all grants for the principal on the descendant entitlement. This should, on average, be... 1. + descendantGrants := make([]*v2.Grant, 0, 1) + pageToken := "" + for { + req := &reader_v2.GrantsReaderServiceListGrantsForEntitlementRequest{ + Entitlement: descendantEntitlement.GetEntitlement(), + PrincipalId: sourceGrant.GetPrincipal().GetId(), + PageSize: 1000, + PageToken: pageToken, + Annotations: nil, + } + + resp, err := s.store.ListGrantsForEntitlement(ctx, req) + if err != nil { + l.Error("runGrantExpandActions: error fetching descendant grants", zap.Error(err)) + return false, fmt.Errorf("runGrantExpandActions: error fetching descendant grants: %w", err) + } + + descendantGrants = append(descendantGrants, resp.List...) + pageToken = resp.NextPageToken + if pageToken == "" { + break + } + } + + // If we have no grants for the principal in the descendant entitlement, make one. + directGrant := true + if len(descendantGrants) == 0 { + directGrant = false + // TODO(morgabra): This is kinda gnarly, grant ID won't have any special meaning. + // FIXME(morgabra): We should probably conflict check with grant id? + descendantGrant, err := s.newExpandedGrant(ctx, descendantEntitlement.Entitlement, sourceGrant.GetPrincipal()) + if err != nil { + l.Error("runGrantExpandActions: error creating new grant", zap.Error(err)) + return false, fmt.Errorf("runGrantExpandActions: error creating new grant: %w", err) + } + descendantGrants = append(descendantGrants, descendantGrant) + l.Debug( + "runGrantExpandActions: created new grant for expansion", + zap.String("grant_id", descendantGrant.GetId()), + ) + } + + // Add the source entitlement as a source to all descendant grants. + for _, descendantGrant := range descendantGrants { + sources := descendantGrant.GetSources() + if sources == nil { + sources = &v2.GrantSources{} + descendantGrant.Sources = sources + } + sourcesMap := sources.GetSources() + if sourcesMap == nil { + sourcesMap = make(map[string]*v2.GrantSources_GrantSource) + sources.Sources = sourcesMap + } + + if directGrant && len(sources.Sources) == 0 { + // If we are already granted this entitlement, make sure to add ourselves as a source. + sourcesMap[descendantGrant.GetEntitlement().GetId()] = &v2.GrantSources_GrantSource{} + } + // Include the source grant as a source. + sourcesMap[sourceGrant.GetEntitlement().GetId()] = &v2.GrantSources_GrantSource{} + + l.Debug( + "runGrantExpandActions: updating sources for descendant grant", + zap.String("grant_id", descendantGrant.GetId()), + zap.Any("sources", sources), + ) + + err = s.store.PutGrant(ctx, descendantGrant) + if err != nil { + l.Error("runGrantExpandActions: error updating descendant grant", zap.Error(err)) + return false, fmt.Errorf("runGrantExpandActions: error updating descendant grant: %w", err) + } + } + } + + // If we have no more pages of work, pop the action off the stack and mark this edge in the graph as done + action.PageToken = sourceGrants.NextPageToken + if action.PageToken == "" { + graph.MarkEdgeExpanded(action.SourceEntitlementID, action.DescendantEntitlementID) + graph.Actions = graph.Actions[1:] + } + return false, nil +} + +func (s *syncer) newExpandedGrant(ctx context.Context, descEntitlement *v2.Entitlement, principal *v2.Resource) (*v2.Grant, error) { + enResource := descEntitlement.GetResource() + if enResource == nil { + return nil, fmt.Errorf("newExpandedGrant: entitlement has no resource") + } + + if principal == nil { + return nil, fmt.Errorf("newExpandedGrant: principal is nil") + } + + grant := &v2.Grant{ + Id: fmt.Sprintf("%s:%s:%s", descEntitlement.Id, principal.Id.ResourceType, principal.Id.Resource), + Entitlement: descEntitlement, + Principal: principal, + } + + return grant, nil +} + +// expandGrantsForEntitlements expands grants for the given entitlement. +func (s *syncer) expandGrantsForEntitlements(ctx context.Context) error { + l := ctxzap.Extract(ctx) + + graph := s.state.EntitlementGraph(ctx) + l = l.With(zap.Int("depth", graph.Depth)) + l.Debug("expandGrantsForEntitlements: start", zap.Any("graph", graph)) + + actionsDone, err := s.runGrantExpandActions(ctx) + if err != nil { + l.Error("expandGrantsForEntitlements: error running graph actions", zap.Error(err)) + return fmt.Errorf("expandGrantsForEntitlements: error running graph actions: %w", err) + } + if !actionsDone { + return nil + } + + if graph.Depth > 8 { + l.Error("expandGrantsForEntitlements: exceeded max depth", zap.Any("graph", graph)) + s.state.FinishAction(ctx) + return fmt.Errorf("exceeded max depth") + } + graph.Depth++ + + // TOOD(morgabra) Yield here after some amount of work? + for sourceEntitlementID := range graph.Entitlements { + // We've already expanded this entitlement, so skip it. + if graph.IsEntitlementExpanded(sourceEntitlementID) { + continue + } + + // We have ancestors who have not been expanded yet, so we can't expand ourselves. + if graph.HasUnexpandedAncestors(sourceEntitlementID) { + continue + } + + for descendantEntitlementID, edgeInfo := range graph.GetDescendants(sourceEntitlementID) { + if edgeInfo.Expanded { + continue + } + graph.Actions = append(graph.Actions, EntitlementGraphAction{ + SourceEntitlementID: sourceEntitlementID, + DescendantEntitlementID: descendantEntitlementID, + PageToken: "", + Shallow: edgeInfo.Shallow, + ResourceTypeIDs: edgeInfo.ResourceTypeIDs, + }) + } + } + + if graph.IsExpanded() { + l.Debug("expandGrantsForEntitlements: graph is expanded", zap.Any("graph", graph)) + s.state.FinishAction(ctx) + return nil + } + + l.Debug("expandGrantsForEntitlements: graph is not expanded", zap.Any("graph", graph)) + return nil +} + func (s *syncer) loadStore(ctx context.Context) error { if s.store != nil { return nil diff --git a/vendor/github.com/conductorone/baton-sdk/pkg/tasks/local/syncer.go b/vendor/github.com/conductorone/baton-sdk/pkg/tasks/local/syncer.go index 4699faed..e6402d28 100644 --- a/vendor/github.com/conductorone/baton-sdk/pkg/tasks/local/syncer.go +++ b/vendor/github.com/conductorone/baton-sdk/pkg/tasks/local/syncer.go @@ -12,8 +12,9 @@ import ( ) type localSyncer struct { - dbPath string - o sync.Once + dbPath string + o sync.Once + expandGrants bool } func (m *localSyncer) Next(ctx context.Context) (*v1.Task, time.Duration, error) { @@ -46,9 +47,10 @@ func (m *localSyncer) Process(ctx context.Context, task *v1.Task, cc types.Conne } // NewSyncer returns a task manager that queues a sync task. -func NewSyncer(ctx context.Context, dbPath string) (tasks.Manager, error) { +func NewSyncer(ctx context.Context, dbPath string, expandGrants bool) (tasks.Manager, error) { nm := &localSyncer{ - dbPath: dbPath, + dbPath: dbPath, + expandGrants: expandGrants, } return nm, nil diff --git a/vendor/modules.txt b/vendor/modules.txt index 541569f8..9b2745fa 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -118,7 +118,7 @@ github.com/aws/smithy-go/time github.com/aws/smithy-go/transport/http github.com/aws/smithy-go/transport/http/internal/io github.com/aws/smithy-go/waiter -# github.com/conductorone/baton-sdk v0.1.5 +# github.com/conductorone/baton-sdk v0.1.6 ## explicit; go 1.20 github.com/conductorone/baton-sdk/internal/connector github.com/conductorone/baton-sdk/pb/c1/c1z/v1