syntax = "proto3";

package coda.admin.v1;

option java_package = "coda.admin.v1";
option java_outer_classname = "PolicyProto";

import "google/protobuf/timestamp.proto";
import "coda/admin/v1/access_types.proto";
import "coda/admin/v1/types.proto";
import "coda/common/v1/types.proto";

service PolicyService {
  // ─── Permission overrides ────────────────────────────────────────

  // Grant a specific permission to a user, bypassing role assignment.
  rpc GrantPermission(GrantPermissionRequest) returns (GrantPermissionResponse);

  // Deny a specific permission to a user, overriding any role grants.
  rpc DenyPermission(DenyPermissionRequest) returns (DenyPermissionResponse);

  // Remove a previously set grant or deny override.
  rpc RevokeOverride(RevokeOverrideRequest) returns (RevokeOverrideResponse);

  // List all permission overrides for a user in a tenant.
  rpc ListUserOverrides(ListUserOverridesRequest) returns (ListUserOverridesResponse);

  // ─── Policy conditions ───────────────────────────────────────────

  // Set conditions on a permission (replaces existing conditions).
  rpc SetPolicyConditions(SetPolicyConditionsRequest) returns (SetPolicyConditionsResponse);

  // List conditions attached to a permission.
  rpc ListPolicyConditions(ListPolicyConditionsRequest) returns (ListPolicyConditionsResponse);
}

// ─── Permission overrides ────────────────────────────────────────────

message GrantPermissionRequest {
  string tenant_id = 1;
  string user_id = 2;
  string permission_name = 3;
  string reason = 4;
  // Empty means no expiry
  optional google.protobuf.Timestamp expires_at = 5;
}

message GrantPermissionResponse {
  UserPermissionInfo override = 1;
}

message DenyPermissionRequest {
  string tenant_id = 1;
  string user_id = 2;
  string permission_name = 3;
  string reason = 4;
  // Empty means no expiry
  optional google.protobuf.Timestamp expires_at = 5;
}

message DenyPermissionResponse {
  UserPermissionInfo override = 1;
}

message RevokeOverrideRequest {
  string tenant_id = 1;
  string override_id = 2;
}

message RevokeOverrideResponse {}

message ListUserOverridesRequest {
  string tenant_id = 1;
  string user_id = 2;
  coda.common.v1.PageRequest page = 3;
}

message ListUserOverridesResponse {
  repeated UserPermissionInfo overrides = 1;
  coda.common.v1.PageInfo page = 2;
}

// ─── Policy conditions ───────────────────────────────────────────────

message PolicyCondition {
  ConditionType type = 1;
  // JSON-encoded condition parameters
  string config_json = 2;
}

message SetPolicyConditionsRequest {
  string tenant_id = 1;
  string permission_name = 2;
  // Full replacement of the permission's conditions
  repeated PolicyCondition conditions = 3;
}

message SetPolicyConditionsResponse {
  repeated PolicyCondition conditions = 1;
}

message ListPolicyConditionsRequest {
  string tenant_id = 1;
  string permission_name = 2;
}

message ListPolicyConditionsResponse {
  repeated PolicyCondition conditions = 1;
}
