Skip to content

Commit

Permalink
clients/v1: add Roles service with RegisterRoleResources RPC (#69)
Browse files Browse the repository at this point in the history
Adds the RPC to register resources with SAMS to the clients API. These
resources must have a valid `ResourceType` defined in the `roles`
package. These resources will be used by SAMS to generate assets for
Entitle grants.

Registering resources requires a client to have the
`sams::roles.resources::write` scope

Closes CORE-397
## Test plan
CI

---------

Co-authored-by: Joe Chen <jc@unknwon.io>
  • Loading branch information
jac and unknwon authored Nov 7, 2024
1 parent 91a40dd commit dce665e
Show file tree
Hide file tree
Showing 7 changed files with 650 additions and 104 deletions.
597 changes: 505 additions & 92 deletions clients/v1/clients.pb.go

Large diffs are not rendered by default.

40 changes: 40 additions & 0 deletions clients/v1/clients.proto
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,43 @@ message IntrospectTokenResponse {
// ExpiresAt indicates when the token expires.
google.protobuf.Timestamp expires_at = 4;
}

service RolesService {
rpc RegisterRoleResources (stream RegisterRoleResourcesRequest) returns (RegisterRoleResourcesResponse) {
option (sams_required_scopes) = "sams::roles.resources::write";
};
}
message RegisterRoleResourcesRequestMetadata {
// Client-provided revision identifier.
// Upon completing the streaming request, any `resource_type` resources with a different revision will be removed.
string revision = 1;
// The type of resources being registered.
// Should be a valid resource type as defined in the `roles` package:
// https://github.com/sourcegraph/sourcegraph-accounts-sdk-go/blob/main/roles/
string resource_type = 2;
}
message RegisterRoleResourcesRequest {
message Resources {
repeated RoleResource resources = 1;
}
oneof payload {
// Metadata about the resources being registered.
// It is expected that a metadata payload is sent only once per request and before any resources are sent.
RegisterRoleResourcesRequestMetadata metadata = 1;
// Batch of resources to register in a single request. Clients should aim to
// batch a large number of resources into a series of smaller requests in the
// RegisterRoleResources stream.
Resources resources = 2;
}
}

message RegisterRoleResourcesResponse {
uint64 resource_count = 1;
}

message RoleResource {
// A unique identifier for the resource
string resource_id = 1;
// A human readable name for the resource
string display_name = 2;
}
93 changes: 84 additions & 9 deletions clients/v1/clientsv1connect/clients.connect.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 11 additions & 2 deletions roles/roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ func (r ResourceType) IsService() bool {
return r == Service
}

// Display returns the display name of the resource type.
func (r ResourceType) Display() string {
// DisplayName returns the display name of the resource type.
func (r ResourceType) DisplayName() string {
s := strings.ReplaceAll(string(r), "_", " ")
return cases.Title(language.English).String(s)
}
Expand Down Expand Up @@ -173,3 +173,12 @@ func ServiceRolesByService() map[services.Service][]Role {
}
return byService
}

// ResourceTypes returns all allowed resource types.
func ResourceTypes() []ResourceType {
var resourceTypes []ResourceType
for _, role := range registeredRoles {
resourceTypes = append(resourceTypes, role.resourceType)
}
return resourceTypes
}
2 changes: 1 addition & 1 deletion roles/roles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ func TestDisplay(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
got := test.resource.Display()
got := test.resource.DisplayName()
assert.Equal(t, test.want, got)
})
}
Expand Down
3 changes: 3 additions & 0 deletions scopes/scopes.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ var (
"user.metadata.dotcom",

"session",

"roles",
"roles.resources",
}
telemetryGatewayPermissions = []Permission{
"events",
Expand Down
6 changes: 6 additions & 0 deletions scopes/scopes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ func TestAllowedGoldenList(t *testing.T) {
Scope("sams::session::read"),
Scope("sams::session::write"),
Scope("sams::session::delete"),
Scope("sams::roles::read"),
Scope("sams::roles::write"),
Scope("sams::roles::delete"),
Scope("sams::roles.resources::read"),
Scope("sams::roles.resources::write"),
Scope("sams::roles.resources::delete"),
Scope("telemetry_gateway::events::read"),
Scope("telemetry_gateway::events::write"),
Scope("telemetry_gateway::events::delete"),
Expand Down

0 comments on commit dce665e

Please sign in to comment.