syntax = "proto3";

package authz.v1;

import "google/api/annotations.proto";
import "protoc-gen-openapiv2/options/annotations.proto";

service AuthzService {
  rpc Check(CheckRequest) returns (CheckResponse) {
    option (google.api.http) = {
      post: "/v1/namespace/{namespace}/check"
      body: "*"
    };

    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
      summary: "Check access for subject on resource given its parent folder"
      tags: ["Check"]
      operation_id: "Check"
      description: "This API checks if a subject is allowed to perform a given action on a specific resource."
    };
  }

  rpc List(ListRequest) returns (ListResponse) {
    option (google.api.http) = {
      post: "/v1/namespace/{namespace}/list"
      body: "*"
    };

    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
      summary: "List a subject accesses on resources"
      tags: ["List"]
      operation_id: "List"
      description: "This API lists the resources a subject can perform a given action on."
    };
  }

  rpc BatchCheck(BatchCheckRequest) returns (BatchCheckResponse) {
    option (google.api.http) = {
      post: "/v1/namespace/{namespace}/batchcheck"
      body: "*"
    };

    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
      summary: "Batch check access for subject on multiple resources"
      tags: ["BatchCheck"]
      operation_id: "BatchCheck"
      description: "This API checks if a subject is allowed to perform actions on multiple resources in a single request. Maximum 50 checks per request."
    };
  }
}

message CheckRequest {
  string subject = 1;
  string verb = 2;
  string group = 3;
  string resource = 4;
  string namespace = 5;
  string name = 6;
  string subresource = 7;
  string path = 8;
  string folder = 9;
  bool skipcache = 10;
  // teams contains the team identifiers for the subject.
  repeated string teams = 11;
}

message CheckResponse {
  bool allowed = 1;
  Zookie zookie = 2;
}

message ListRequest {
  string subject = 1;
  string group = 2;
  string verb = 3;
  string resource = 4;
  string namespace = 5;
  string subresource = 6;
  ListRequestOptions options = 7;
  // teams contains the team identifiers for the subject.
  repeated string teams = 8;
}

message ListRequestOptions {
  bool skipcache = 1;
}

message Zookie {
  int64 timestamp = 1;
}

message ListResponse {
  bool all = 1;
  repeated string folders = 2;
  repeated string items = 3;
  Zookie zookie = 4;
}

// BatchCheckRequest contains multiple checks to be performed at once.
// Maximum of 50 checks per request.
message BatchCheckRequest {
  string subject = 1;
  repeated BatchCheckItem checks = 2;
  BatchCheckOptions options = 3;
  string namespace = 4;
  // teams contains the team identifiers for the subject.
  repeated string teams = 5;
}

// BatchCheckItem represents a single check in a batch request.
message BatchCheckItem {
  // correlation_id is a unique identifier to correlate this check with its result.
  // Must be a non-empty string unique within the batch request.
  string correlation_id = 1;
  string verb = 2;
  string group = 3;
  string resource = 4;
  string name = 5;
  string subresource = 6;
  string path = 7;
  string folder = 8;
  // freshness_timestamp is the timestamp (in milliseconds) when the resource was last modified.
  // If provided, the server should skip cache for this item if the cached result
  // is older than this timestamp.
  int64 freshness_timestamp = 9;
}

message BatchCheckOptions {
  bool skipcache = 1;
}

// BatchCheckResponse contains results for all checks in a batch request.
message BatchCheckResponse {
  // results maps each correlation_id to its check result.
  map<string, BatchCheckResult> results = 1;
}

// BatchCheckResult represents the result of a single check in a batch.
message BatchCheckResult {
  bool allowed = 1;
  string error = 2;
}
