syntax = "proto3";

import "google/protobuf/timestamp.proto";
import "google/protobuf/wrappers.proto";
package code.justin.tv.beefcake;
option go_package = "beefcake";

service Beefcake {
  // GetRoles gets all role
  rpc GetRoles(GetRolesRequest) returns (GetRolesResponse);
  // CreateRole creates a role
  rpc CreateRole(CreateRoleRequest) returns (CreateRoleResponse);
  // GetRole gets a role
  rpc GetRole(GetRoleRequest) returns (Role);
  // UpdateRole updates an existing role
  rpc UpdateRole(UpdateRoleRequest) returns (UpdateRoleResponse);
  // OverrideRole overrides all permissions for a role
  rpc OverrideRole(OverrideRoleRequest) returns (OverrideRoleResponse);
  // DeleteRole deletes a role
  rpc DeleteRole(DeleteRoleRequest) returns (DeleteRoleResponse);

  // AddRolePermission adds a permission for a role
  rpc AddRolePermission(AddRolePermissionRequest) returns (AddRolePermissionResponse);
  // RemoveRolePermission removes a permission for a role
  rpc RemoveRolePermission(RemoveRolePermissionRequest) returns (RemoveRolePermissionResponse);

  // Add a legacy string permission to a role
  rpc AddLegacyPermissionToRole(AddLegacyPermissionToRoleRequest) returns (AddLegacyPermissionToRoleResponse);
  // Remove a legacy string permission to a role
  rpc RemoveLegacyPermissionFromRole(RemoveLegacyPermissionFromRoleRequest) returns (RemoveLegacyPermissionFromRoleResponse);

  // AddUserToRole adds a user to a role
  rpc AddUserToRole(AddUserToRoleRequest) returns (AddUserToRoleResponse);
  // RemoveUserFromRole removes a user to a role
  rpc RemoveUserFromRole(RemoveUserFromRoleRequest) returns (RemoveUserFromRoleResponse);

  // User returns a user
  rpc GetUser(GetUserRequest) returns (User);

  // GetLegacyPermissions returns a single legacy permission
  rpc GetLegacyPermissions(GetLegacyPermissionsRequest) returns (GetLegacyPermissionsResponse);
  // CreateLegacyPermission creates a legacy permission
  rpc CreateLegacyPermission(CreateLegacyPermissionRequest) returns (CreateLegacyPermissionResponse);
  // GetLegacyPermission returns a single legacy permission
  rpc GetLegacyPermission(GetLegacyPermissionRequest) returns (LegacyPermission);
  // UpdateLegacyPermission updates a legacy permission
  rpc UpdateLegacyPermission(UpdateLegacyPermissionRequest) returns (UpdateLegacyPermissionResponse);
  // DeleteLegacyPermission deletes a legacy permission
  rpc DeleteLegacyPermission(DeleteLegacyPermissionRequest) returns (DeleteLegacyPermissionResponse);
}

// Method requests and responses.
message CreateRoleRequest {
  // friendly name
  string name = 1;
}

message CreateRoleResponse {
  string id = 1;
  string name = 2;
}

message AddRolePermissionRequest {
  // role id to give permission to
  string role_id = 1;
  // permission to give
  Permission permission = 2;
}

message AddRolePermissionResponse {
}

message AddLegacyPermissionToRoleRequest {
  string role_id = 1;
  string legacy_permission_id = 2;
}

message AddLegacyPermissionToRoleResponse {
}

message RemoveLegacyPermissionFromRoleRequest {
  string role_id = 1;
  string legacy_permission_id = 2;
}

message RemoveLegacyPermissionFromRoleResponse {
}

message OverrideRoleRequest {
  // role to override
  string id = 1;
  // name to give to role
  string name = 2;
  // permissions to set
  repeated Permission permissions = 3;
  // memberships to set
  repeated Role.UserMembership user_memberships = 4;
}

message OverrideRoleResponse {
}

message GetRolesRequest {
}

message GetRolesResponse {
  message Role {
    string id = 1;
    string name = 2;
  }

  repeated Role roles = 1;
}

message GetRoleRequest {
  // role to retrieve
  string id = 1;
}

message Role {
  message UserMembership {
    string user_id = 1;
    // time when the user's membership will expire
    google.protobuf.Timestamp expiration = 2;
  }

  string id = 1;
  string name = 2;
  repeated UserMembership user_memberships = 3;
  repeated AttachedPermission permissions = 4;
}

message StringArrayValue {
  repeated string value = 1;
}

message UpdateRoleRequest {
  // role to update. all parameters MUST be provided.
  string id = 1;
  // new value for name
  google.protobuf.StringValue name = 2;
  // new value for legacy permission ids
  StringArrayValue legacy_permission_ids = 3;
}

message UpdateRoleResponse {
}

message RemoveRolePermissionRequest {
  // role id to give permission to
  string role_id = 1;
  // the role's permission to remove
  string role_permission_id = 2;
}

message RemoveRolePermissionResponse {
}

message AddUserToRoleRequest {
  // role id to give permission to
  string role_id = 1;
  // user to give permission to
  string user_id = 2;
  // time when the user's membership will expire
  google.protobuf.Timestamp membership_expiration = 3;
}

message AddUserToRoleResponse {
}

message RemoveUserFromRoleRequest {
  // role id to give permission to
  string role_id = 1;
  // user to give permission to
  string user_id = 2;
}

message RemoveUserFromRoleResponse {
}

message DeleteRoleRequest {
  // role to delete
  string id = 1;
}

message DeleteRoleResponse {
}

message GetUserRequest {
  string id = 1;
}

message User {
  message RoleMembership {
    string id = 1;
    string name = 2;
    // time when the user's membership will expire
    google.protobuf.Timestamp membership_expiration = 3;
  }

  string id = 1;
  repeated RoleMembership role_memberships = 2;
  repeated AttachedPermission permissions = 3;
}

message GetLegacyPermissionsRequest {
}

message GetLegacyPermissionsResponse {
  message LegacyPermission {
    string id = 1;
    string name = 2;
    string description = 3;
  }

  repeated LegacyPermission legacy_permissions = 1;
}

message CreateLegacyPermissionRequest {
  string id = 1;
  string name = 2;
  string description = 3;
}

message CreateLegacyPermissionResponse {
}

message GetLegacyPermissionRequest {
  string id = 1;
}

message LegacyPermission {
  message Role {
    string id = 1;
    string name = 2;
  }

  string id = 1;
  string name = 2;
  string description = 3;

  repeated Role roles = 4;
}


message UpdateLegacyPermissionRequest {
  string id = 1;
  google.protobuf.StringValue name = 2;
  google.protobuf.StringValue description = 3;
}

message UpdateLegacyPermissionResponse {
}

message DeleteLegacyPermissionRequest {
  string id = 1;
}

message DeleteLegacyPermissionResponse {
}

message Permission {
  message LegacyPermission {
    string id = 1;
    string name = 2;
  }

  message TwitchUserPermission {
    enum ActionType {
      ANY = 0;  // any user action
      GET_PII = 1; // Get personally idefifying info
    }

    message AnyResource {}

    ActionType action = 1; // a specific user action

    oneof resource {
      AnyResource any = 2; // any user
      string twitch_user_id = 3; // a specific twitch user
    }
  }

  oneof value {
    LegacyPermission legacy = 1;
    TwitchUserPermission twitch_user = 2;
  }
}

message AttachedPermission {
  string id = 1;
  Permission permission = 2;
}
