diff --git a/internal/authz/authz.go b/internal/authz/authz.go index 53f4c3f42d..8f4d1dddc0 100644 --- a/internal/authz/authz.go +++ b/internal/authz/authz.go @@ -311,7 +311,7 @@ func (a *ClientWrapper) doDelete(ctx context.Context, user string, role string, // DeleteUser removes all tuples for the given user func (a *ClientWrapper) DeleteUser(ctx context.Context, user string) error { - for _, role := range AllRoles { + for role := range AllRoles { listresp, err := a.cli.ListObjects(ctx).Body(fgaclient.ClientListObjectsRequest{ Type: "project", Relation: role.String(), diff --git a/internal/authz/authz_test.go b/internal/authz/authz_test.go index c1f455bb35..f1f72ec0ae 100644 --- a/internal/authz/authz_test.go +++ b/internal/authz/authz_test.go @@ -54,7 +54,7 @@ func TestAllRolesExistInFGAModel(t *testing.T) { t.Logf("relations: %v", projectTypeDef.Relations) - for _, r := range authz.AllRoles { + for r := range authz.AllRoles { assert.Contains(t, *projectTypeDef.Relations, r.String(), "role %s not found in authz model", r) } } diff --git a/internal/authz/interface.go b/internal/authz/interface.go index 572ec8f7a3..1ee3e4a40d 100644 --- a/internal/authz/interface.go +++ b/internal/authz/interface.go @@ -44,12 +44,16 @@ const ( var ( // AllRoles is a list of all roles - AllRoles = []Role{ - AuthzRoleAdmin, - AuthzRoleEditor, - AuthzRoleViewer, - AuthzRolePolicyWriter, - AuthzRolePermissionsManager, + AllRoles = map[Role]string{ + AuthzRoleAdmin: "The admin role allows the user to perform all actions on the project and " + + "sub-projects.", + AuthzRoleEditor: "The editor role allows for more write and read actions on the project and " + + "sub-projects except for project administration.", + AuthzRoleViewer: "The viewer role allows for read actions on the project and sub-projects.", + AuthzRolePolicyWriter: "The policy_writer role allows for writing policies (rule types and " + + "profiles) on the project and sub-projects. This is handy for CI jobs.", + AuthzRolePermissionsManager: "The permissions_manager role allows for managing permissions " + + "on the project and sub-projects.", } ) diff --git a/internal/controlplane/handlers_authz.go b/internal/controlplane/handlers_authz.go index 475305645c..a0b73fa283 100644 --- a/internal/controlplane/handlers_authz.go +++ b/internal/controlplane/handlers_authz.go @@ -28,6 +28,7 @@ import ( "google.golang.org/grpc/status" "github.com/stacklok/minder/internal/auth" + "github.com/stacklok/minder/internal/authz" "github.com/stacklok/minder/internal/db" "github.com/stacklok/minder/internal/engine" "github.com/stacklok/minder/internal/logger" @@ -236,3 +237,40 @@ func requiresProjectAuthorization(opts *minder.RpcOptions) bool { return !opts.Anonymous && opts.GetAuthScope() != minder.ObjectOwner_OBJECT_OWNER_USER } + +// Permissions API +// ensure interface implementation +var _ minder.PermissionsServiceServer = (*Server)(nil) + +// ListRoles returns the list of available roles for the minder instance +func (*Server) ListRoles(_ context.Context, _ *minder.ListRolesRequest) (*minder.ListRolesResponse, error) { + resp := minder.ListRolesResponse{ + Roles: make([]*minder.Role, 0, len(authz.AllRoles)), + } + for role, desc := range authz.AllRoles { + resp.Roles = append(resp.Roles, &minder.Role{ + Name: role.String(), + Description: desc, + }) + } + + return &resp, nil +} + +// ListRoleAssignments returns the list of role assignments for the given project +func (*Server) ListRoleAssignments( + context.Context, + *minder.ListRoleAssignmentsRequest, +) (*minder.ListRoleAssignmentsResponse, error) { + return nil, nil +} + +// AssignRole assigns a role to a user on a project +func (*Server) AssignRole(context.Context, *minder.AssignRoleRequest) (*minder.AssignRoleResponse, error) { + return nil, nil +} + +// RemoveRole removes a role from a user on a project +func (*Server) RemoveRole(context.Context, *minder.RemoveRoleRequest) (*minder.RemoveRoleResponse, error) { + return nil, nil +} diff --git a/internal/controlplane/register_handlers.go b/internal/controlplane/register_handlers.go index 8437c2376c..52a9b068cb 100644 --- a/internal/controlplane/register_handlers.go +++ b/internal/controlplane/register_handlers.go @@ -56,6 +56,11 @@ func RegisterGatewayHTTPHandlers(ctx context.Context, gwmux *runtime.ServeMux, g if err := pb.RegisterArtifactServiceHandlerFromEndpoint(ctx, gwmux, grpcAddress, opts); err != nil { log.Fatal().Err(err).Msg("failed to register gateway") } + + // Register the Permissions service + if err := pb.RegisterPermissionsServiceHandlerFromEndpoint(ctx, gwmux, grpcAddress, opts); err != nil { + log.Fatal().Err(err).Msg("failed to register gateway") + } } // RegisterGRPCServices registers the GRPC services @@ -77,4 +82,7 @@ func RegisterGRPCServices(s *Server) { // Register the Artifact service pb.RegisterArtifactServiceServer(s.grpcServer, s) + + // Register the Permissions service + pb.RegisterPermissionsServiceServer(s.grpcServer, s) } diff --git a/internal/controlplane/server.go b/internal/controlplane/server.go index 0371308ac7..558c4880c0 100644 --- a/internal/controlplane/server.go +++ b/internal/controlplane/server.go @@ -66,24 +66,27 @@ var ( // Server represents the controlplane server type Server struct { - store db.Store - cfg *serverconfig.Config - evt *events.Eventer - mt *metrics - provMt provtelemetry.ProviderMetrics - grpcServer *grpc.Server - vldtr auth.JwtValidator + store db.Store + cfg *serverconfig.Config + evt *events.Eventer + mt *metrics + provMt provtelemetry.ProviderMetrics + grpcServer *grpc.Server + vldtr auth.JwtValidator + OAuth2 *oauth2.Config + ClientID string + ClientSecret string + authzClient authz.Client + cryptoEngine *crypto.Engine + + // Implementations for service registration pb.UnimplementedHealthServiceServer pb.UnimplementedOAuthServiceServer pb.UnimplementedUserServiceServer pb.UnimplementedRepositoryServiceServer pb.UnimplementedProfileServiceServer pb.UnimplementedArtifactServiceServer - OAuth2 *oauth2.Config - ClientID string - ClientSecret string - authzClient authz.Client - cryptoEngine *crypto.Engine + pb.UnimplementedPermissionsServiceServer } // ServerOption is a function that modifies a server