syntax = "proto3";

import "proto/context.proto";
import "proto/user_id.proto";

package grp;

// Group represents a group that a user is a member of.
// Next tag: 10
message Group {
  reserved 8;

  // The unique ID of this group.
  // Ex. "GR4576963743584254779"
  string id = 1;

  // The name of this group (may be displayed to users).
  // Ex. "Tyler Williams Group"
  string name = 2;

  // Optional. The domains owned by this group.
  // Ex. "iterationinc.com"
  string owned_domain = 3;

  // True if this group has linked a Github token.
  bool github_linked = 4;

  // The unique URL segment for this group which is used
  // to construct nice-looking URLs for this group, such as
  // https://app.buildbuddy.com/join/:url-identifier
  //
  // May consist of only lowercase ASCII letters (a-z) and hyphens.
  //
  // Ex: "iteration-inc"
  string url_identifier = 5;

  // Whether sharing features are allowed by this group.
  bool sharing_enabled = 6;

  // Whether builds for this group will use custom executors provided by the
  // group.
  bool use_group_owned_executors = 7;

  // Role represent's the authenticated user's role within this group, which
  // determines which actions the user is authorized to perform.
  Role role = 9;

  enum Role {
    UNKNOWN_ROLE = 0;
    // Developers cannot perform certain privileged actions such as creating API
    // keys and viewing usage data, but can perform most other common actions
    // such as viewing invocation history.
    DEVELOPER_ROLE = 1;
    // Admins have unrestricted access to any data owned by this group.
    ADMIN_ROLE = 2;
  }
}

message JoinGroupRequest {
  context.RequestContext request_context = 2;

  // The unique ID of this group.
  // Ex. "GR4576963743584254779"
  string id = 1;
}

message JoinGroupResponse {
  context.ResponseContext response_context = 1;
}

message GetGroupRequest {
  context.RequestContext request_context = 2;

  // The unique URL segment for this group which is used
  // to construct nice-looking URLs for this group, such as
  // https://app.buildbuddy.com/join/:url-identifier
  //
  // May consist of only lowercase ASCII letters (a-z) and hyphens.
  //
  // Ex: "iteration-inc"
  string url_identifier = 1;
}

// Publicly visible group info.
// DO NOT add new fields exposing sensitive data.
message GetGroupResponse {
  context.ResponseContext response_context = 4;

  // The unique ID of the group.
  // Ex. "GR4576963743584254779"
  string id = 1;

  // The name of this group (may be displayed to users).
  // Ex. "Tyler Williams Group"
  string name = 2;

  // Optional. The domains owned by this group.
  // Ex. "iterationinc.com"
  string owned_domain = 3;

  // True if the group has SSO enabled.
  bool sso_enabled = 5;
}

message GetGroupUsersRequest {
  context.RequestContext request_context = 1;

  // The ID of the group to get the users from.
  string group_id = 2;

  // Statuses of members to retrieve (required).
  repeated GroupMembershipStatus group_membership_status = 3;
}

message GetGroupUsersResponse {
  context.ResponseContext response_context = 1;

  message GroupUser {
    user_id.DisplayUser user = 1;
    GroupMembershipStatus group_membership_status = 2;
    Group.Role role = 3;
  }

  // Users related to the group that match the request criteria.
  repeated GroupUser user = 2;
}

message UpdateGroupUsersRequest {
  context.RequestContext request_context = 1;

  // The ID of the group to update.
  string group_id = 2;

  // Update applied to a user in the group.
  message Update {
    enum MembershipAction {
      UNKNOWN_MEMBERSHIP_ACTION = 0;
      // Add the user to the group.
      ADD = 1;
      // Remove the user from the group as well as any pending membership
      // requests.
      REMOVE = 2;
    }

    user_id.UserId user_id = 1;

    // New membership status. If unset, membership status is unaffected.
    MembershipAction membership_action = 2;

    // New role to apply to the user within this group. If unset, role is
    // unaffected.
    Group.Role role = 3;
  }

  // Updates to apply to group users.
  repeated Update update = 3;
}

message UpdateGroupUsersResponse {
  context.ResponseContext response_context = 1;
}

message CreateGroupRequest {
  context.RequestContext request_context = 4;

  // The name of this group (may be displayed to users).
  // Ex. "Tyler Williams Group"
  string name = 1;

  // Whether new users who sign up with an email that matches the
  // authenticated user's email will be automatically added to the
  // group.
  bool auto_populate_from_owned_domain = 2;

  // The unique URL segment for this group which is used
  // to construct nice-looking URLs for this group, such as
  // https://app.buildbuddy.com/join/:url-identifier
  //
  // May consist of only lowercase ASCII letters (a-z) and hyphens.
  //
  // Ex: "iteration-inc"
  string url_identifier = 3;

  // Whether sharing features are allowed by this group.
  bool sharing_enabled = 5;

  // Whether builds for this group will use custom executors provided by the
  // group.
  bool use_group_owned_executors = 6;
}

message CreateGroupResponse {
  context.ResponseContext response_context = 2;

  // ID of the created group.
  // Ex. "GR4576963743584254779"
  string id = 1;
}

message UpdateGroupRequest {
  context.RequestContext request_context = 5;

  // The ID of the group to be updated.
  string id = 1;

  // The name of this group (may be displayed to users).
  // Ex. "Tyler Williams Group"
  string name = 2;

  // Whether new users who sign up with an email that matches the
  // authenticated user's email will be automatically added to the
  // group.
  bool auto_populate_from_owned_domain = 3;

  // The unique URL segment for this group which is used
  // to construct nice-looking URLs for this group, such as
  // https://app.buildbuddy.com/join/:url-identifier
  //
  // May consist of only lowercase ASCII letters (a-z) and hyphens.
  //
  // Ex: "iteration-inc"
  string url_identifier = 4;

  // Whether sharing features are allowed by this group.
  bool sharing_enabled = 6;

  // Whether builds for this group will use custom executors provided by the
  // group.
  bool use_group_owned_executors = 7;
}

message UpdateGroupResponse {
  context.ResponseContext response_context = 1;
}

enum GroupMembershipStatus {
  UNKNOWN_MEMBERSHIP_STATUS = 0;
  // The user is a member of the group.
  MEMBER = 1;
  // The user has requested to join the group but is not yet a member.
  REQUESTED = 2;
}
