syntax = "proto3";

package nominal.authorization.roles.v1;

import "buf/validate/validate.proto";
import "google/api/annotations.proto";
import "nominal/protos/gen/v1/alias.proto";

enum Role {
  // Default value, should not be used.
  ROLE_UNSPECIFIED = 0;
  ROLE_OWNER = 1;
}

message RoleAssignmentRequest {
  Role role = 1 [(buf.validate.field).enum.defined_only = true];
  // The identity, eg a user, to which the role is assigned.
  oneof assignee {
    option (buf.validate.oneof).required = true;
    string user_rid = 2 [(nominal.gen.v1.alias) = {java_name: "io.nominal.authentication.api.UserRid"}];
  }
}

message RoleAssignmentResponse {
  Role role = 1 [(buf.validate.field).enum.defined_only = true];
  // The identity, eg a user, to which the role is assigned.
  oneof assignee {
    option (buf.validate.oneof).required = true;
    string user_rid = 2 [(nominal.gen.v1.alias) = {java_name: "io.nominal.authentication.api.UserRid"}];
  }
}

message UpdateResourceRolesRequest {
  string resource = 1 [(nominal.gen.v1.alias) = {java_name: "com.palantir.ri.ResourceIdentifier"}];
  repeated RoleAssignmentRequest assignments_to_add = 2;
  repeated RoleAssignmentRequest assignments_to_remove = 3;
}
message UpdateResourceRolesResponse {
  // Intentionally empty.
}

message GetResourceRolesRequest {
  string resource = 1 [(nominal.gen.v1.alias) = {java_name: "com.palantir.ri.ResourceIdentifier"}];
}
message GetResourceRolesResponse {
  repeated RoleAssignmentResponse role_assignments = 1;
}

message BatchGetResourceRolesRequest {
  repeated string resources = 1 [(nominal.gen.v1.alias) = {java_name: "com.palantir.ri.ResourceIdentifier"}];
}
message BatchGetResourceRolesResponse {
  map<string, RoleAssignmentWrapper> role_assignments_by_resource = 1 [(nominal.gen.v1.alias) = {key_java_name: "com.palantir.ri.ResourceIdentifier"}];

  message RoleAssignmentWrapper {
    repeated RoleAssignmentResponse role_assignments = 1;
  }
}

// RoleService provides methods for managing roles within Nominal.
service RoleService {
  // Atomically adds and removes role assignments for a resource.
  // Throws if the same role assignment is both added and removed in the same request.
  rpc UpdateResourceRoles(UpdateResourceRolesRequest) returns (UpdateResourceRolesResponse) {
    option (google.api.http) = {
      post: "/authorization/roles/v1/resource/{resource}/roles"
      body: "*"
      response_body: "*"
    };
  }
  // Gets the role assignments for a resource.
  rpc GetResourceRoles(GetResourceRolesRequest) returns (GetResourceRolesResponse) {
    option (google.api.http) = {
      get: "/authorization/roles/v1/resource/{resource}/roles"
      response_body: "*"
    };
  }
  // Gets the role assignments for multiple resources.
  rpc BatchGetResourceRoles(BatchGetResourceRolesRequest) returns (BatchGetResourceRolesResponse) {
    option (google.api.http) = {
      post: "/authorization/roles/v1/batch-get-resource-roles"
      body: "*"
      response_body: "*"
    };
  }
}
