Add Handlers for Add/Set/Remove Group Members (#209)

* Adding members to groups.

* Adding Group membership handler and API methods.

* Adding custom methods to permision actions list.
This commit is contained in:
Todd Knight authored and GitHub committed 2020-07-22 15:10:21 -07:00
1 parent 799242fce4
commit ed05652729
18 files changed
+2587 -355

No files matched your search

+117
View File
@@ -0,0 +1,117 @@
package groups
import (
"context"
"fmt"
"github.com/hashicorp/watchtower/api"
)
func (s Group) AddMembers(ctx context.Context, memberIds []string) (*Group, *api.Error, error) {
if s.Client == nil {
return nil, nil, fmt.Errorf("nil client in AddMembers request")
}
// We assume that the client provided has the org and optionally the project id of the request.
if len(memberIds) == 0 {
return nil, nil, fmt.Errorf("empty memberIds slice")
}
body := map[string]interface{}{
"version": s.Version,
"member_ids": memberIds,
}
req, err := s.Client.NewRequest(ctx, "POST", fmt.Sprintf("groups/%s:add-members", s.Id), body)
if err != nil {
return nil, nil, fmt.Errorf("error creating AddMembers request: %w", err)
}
resp, err := s.Client.Do(req)
if err != nil {
return nil, nil, fmt.Errorf("error performing client request during AddMembers call: %w", err)
}
target := new(Group)
apiErr, err := resp.Decode(target)
if err != nil {
return nil, nil, fmt.Errorf("error decoding AddMembers repsonse: %w", err)
}
target.Client = s.Client
return target, apiErr, nil
}
func (s Group) SetMembers(ctx context.Context, memberIds []string) (*Group, *api.Error, error) {
if s.Client == nil {
return nil, nil, fmt.Errorf("nil client in SetMembers request")
}
// We assume that the client provided has the org and optionally the project id of the request.
body := map[string]interface{}{
"version": s.Version,
}
if len(memberIds) > 0 {
body["member_ids"] = memberIds
} else if memberIds != nil {
// In this function, a non-nil but empty list means clear out
body["member_ids"] = nil
}
req, err := s.Client.NewRequest(ctx, "POST", fmt.Sprintf("groups/%s:set-members", s.Id), body)
if err != nil {
return nil, nil, fmt.Errorf("error creating SetMembers request: %w", err)
}
resp, err := s.Client.Do(req)
if err != nil {
return nil, nil, fmt.Errorf("error performing client request during SetMembers call: %w", err)
}
target := new(Group)
apiErr, err := resp.Decode(target)
if err != nil {
return nil, nil, fmt.Errorf("error decoding SetMembers repsonse: %w", err)
}
target.Client = s.Client
return target, apiErr, nil
}
func (s Group) RemoveMembers(ctx context.Context, memberIds []string) (*Group, *api.Error, error) {
if s.Client == nil {
return nil, nil, fmt.Errorf("nil client in RemoveMembers request")
}
// We assume that the client provided has the org and optionally the project id of the request.
if len(memberIds) == 0 {
return nil, nil, fmt.Errorf("empty memberIds slice")
}
body := map[string]interface{}{
"version": s.Version,
"member_ids": memberIds,
}
req, err := s.Client.NewRequest(ctx, "POST", fmt.Sprintf("groups/%s:remove-members", s.Id), body)
if err != nil {
return nil, nil, fmt.Errorf("error creating RemoveMembers request: %w", err)
}
resp, err := s.Client.Do(req)
if err != nil {
return nil, nil, fmt.Errorf("error performing client request during RemoveMembers call: %w", err)
}
target := new(Group)
apiErr, err := resp.Decode(target)
if err != nil {
return nil, nil, fmt.Errorf("error decoding RemoveMembers repsonse: %w", err)
}
target.Client = s.Client
return target, apiErr, nil
}
+12 -2
View File
@@ -36,11 +36,21 @@ type Group struct {
UpdatedTime time.Time `json:"updated_time,omitempty"`
// Whether the resource is disabled
Disabled *bool `json:"disabled,omitempty"`
// The version can be used in subsiquent write requests to ensure this resource
// has not changed and to fail the write if it has.
// Output only.
Version uint32 `json:"version,omitempty"`
// Contains the list of member ids in this group.
// Output only.
MemberIds []string `json:"member_ids,omitempty"`
// The members of this group.
// Output only.
Members []*Member `json:"members,omitempty"`
}
func (s *Group) SetDefault(key string) {
lowerKey := strings.ToLower(key)
validMap := map[string]string{"createdtime": "created_time", "description": "description", "disabled": "disabled", "id": "id", "name": "name", "scope": "scope", "updatedtime": "updated_time"}
validMap := map[string]string{"createdtime": "created_time", "description": "description", "disabled": "disabled", "id": "id", "memberids": "member_ids", "members": "members", "name": "name", "scope": "scope", "updatedtime": "updated_time", "version": "version"}
for k, v := range validMap {
if k == lowerKey || v == lowerKey {
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, v)
@@ -51,7 +61,7 @@ func (s *Group) SetDefault(key string) {
func (s *Group) UnsetDefault(key string) {
lowerKey := strings.ToLower(key)
validMap := map[string]string{"createdtime": "created_time", "description": "description", "disabled": "disabled", "id": "id", "name": "name", "scope": "scope", "updatedtime": "updated_time"}
validMap := map[string]string{"createdtime": "created_time", "description": "description", "disabled": "disabled", "id": "id", "memberids": "member_ids", "members": "members", "name": "name", "scope": "scope", "updatedtime": "updated_time", "version": "version"}
for k, v := range validMap {
if k == lowerKey || v == lowerKey {
s.defaultFields = strutil.StrListDelete(s.defaultFields, v)
+15
View File
@@ -0,0 +1,15 @@
// Code generated by "make api"; DO NOT EDIT.
package groups
type Member struct {
// The ID of the member.
// Output only.
Id string `json:"id,omitempty"`
// The type of the member.
// Output only.
Type string `json:"type,omitempty"`
// The scope ID of the member.
// Output only.
ScopeId string `json:"scope_id,omitempty"`
}
+8
View File
@@ -100,6 +100,14 @@ var inputStructs = []*structInfo{
outName: "Group",
outPkg: "groups",
},
{
inFile: os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/groups/group.pb.go",
inName: "Member",
outFile: os.Getenv("GEN_BASEPATH") + "/api/groups/member.gen.go",
outName: "Member",
outPkg: "groups",
outputOnly: true,
},
{
inFile: os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/roles/role.pb.go",
inName: "Role",
+222
View File
@@ -241,6 +241,105 @@
]
}
},
"/v1/scopes/*/groups/{id}:add-members": {
"post": {
"summary": "Adds Users as members to a Group",
"operationId": "GroupService_AddGroupMembers",
"responses": {
"200": {
"description": "",
"schema": {
"$ref": "#/definitions/controller.api.resources.groups.v1.Group"
}
}
},
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"type": "string"
},
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/controller.api.services.v1.AddGroupMembersRequest"
}
}
],
"tags": [
"controller.api.services.v1.GroupService"
]
}
},
"/v1/scopes/*/groups/{id}:remove-members": {
"post": {
"summary": "Removes the specified members from a Group.",
"operationId": "GroupService_RemoveGroupMembers",
"responses": {
"200": {
"description": "",
"schema": {
"$ref": "#/definitions/controller.api.resources.groups.v1.Group"
}
}
},
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"type": "string"
},
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/controller.api.services.v1.RemoveGroupMembersRequest"
}
}
],
"tags": [
"controller.api.services.v1.GroupService"
]
}
},
"/v1/scopes/*/groups/{id}:set-members": {
"post": {
"summary": "Set a Group's members to exactly the list of provided in the request, removing any members that are not specified.",
"operationId": "GroupService_SetGroupMembers",
"responses": {
"200": {
"description": "",
"schema": {
"$ref": "#/definitions/controller.api.resources.groups.v1.Group"
}
}
},
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"type": "string"
},
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/controller.api.services.v1.SetGroupMembersRequest"
}
}
],
"tags": [
"controller.api.services.v1.GroupService"
]
}
},
"/v1/scopes/*/host-catalogs": {
"get": {
"summary": "Gets a list of HostCatalogs",
@@ -1419,10 +1518,52 @@
"type": "boolean",
"format": "boolean",
"title": "Whether the resource is disabled"
},
"version": {
"type": "integer",
"format": "int64",
"description": "The version can be used in subsiquent write requests to ensure this resource\nhas not changed and to fail the write if it has.\nOutput only.",
"readOnly": true
},
"member_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "Contains the list of member ids in this group.\nOutput only.",
"readOnly": true
},
"members": {
"type": "array",
"items": {
"$ref": "#/definitions/controller.api.resources.groups.v1.Member"
},
"description": "The members of this group.\nOutput only.",
"readOnly": true
}
},
"title": "Group contains all fields related to a Group resource"
},
"controller.api.resources.groups.v1.Member": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "The ID of the member.\nOutput only.",
"readOnly": true
},
"type": {
"type": "string",
"description": "The type of the member.\nOutput only.",
"readOnly": true
},
"scope_id": {
"type": "string",
"description": "The scope ID of the member.\nOutput only.",
"readOnly": true
}
}
},
"controller.api.resources.hosts.v1.Host": {
"type": "object",
"properties": {
@@ -1838,6 +1979,33 @@
},
"title": "User contains all fields related to a User resource"
},
"controller.api.services.v1.AddGroupMembersRequest": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"version": {
"type": "integer",
"format": "int64",
"description": "The version ensures the group hasn't changed since it was last retrieved and if\nit has the request will fail."
},
"member_ids": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"controller.api.services.v1.AddGroupMembersResponse": {
"type": "object",
"properties": {
"item": {
"$ref": "#/definitions/controller.api.resources.groups.v1.Group"
}
}
},
"controller.api.services.v1.AddRoleGrantsRequest": {
"type": "object",
"properties": {
@@ -2196,6 +2364,33 @@
"controller.api.services.v1.RemoveFromHostSetResponse": {
"type": "object"
},
"controller.api.services.v1.RemoveGroupMembersRequest": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"version": {
"type": "integer",
"format": "int64",
"description": "The version ensures the group hasn't changed since it was last retrieved and if\nit has the request will fail."
},
"member_ids": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"controller.api.services.v1.RemoveGroupMembersResponse": {
"type": "object",
"properties": {
"item": {
"$ref": "#/definitions/controller.api.resources.groups.v1.Group"
}
}
},
"controller.api.services.v1.RemoveRoleGrantsRequest": {
"type": "object",
"properties": {
@@ -2250,6 +2445,33 @@
}
}
},
"controller.api.services.v1.SetGroupMembersRequest": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"version": {
"type": "integer",
"format": "int64",
"description": "The version ensures the group hasn't changed since it was last retrieved and if\nit has the request will fail."
},
"member_ids": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"controller.api.services.v1.SetGroupMembersResponse": {
"type": "object",
"properties": {
"item": {
"$ref": "#/definitions/controller.api.resources.groups.v1.Group"
}
}
},
"controller.api.services.v1.SetRoleGrantsRequest": {
"type": "object",
"properties": {
@@ -29,6 +29,75 @@ const (
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type Member struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The ID of the member.
// Output only.
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
// The type of the member.
// Output only.
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
// The scope ID of the member.
// Output only.
ScopeId string `protobuf:"bytes,3,opt,name=scope_id,proto3" json:"scope_id,omitempty"`
}
func (x *Member) Reset() {
*x = Member{}
if protoimpl.UnsafeEnabled {
mi := &file_controller_api_resources_groups_v1_group_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Member) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Member) ProtoMessage() {}
func (x *Member) ProtoReflect() protoreflect.Message {
mi := &file_controller_api_resources_groups_v1_group_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Member.ProtoReflect.Descriptor instead.
func (*Member) Descriptor() ([]byte, []int) {
return file_controller_api_resources_groups_v1_group_proto_rawDescGZIP(), []int{0}
}
func (x *Member) GetId() string {
if x != nil {
return x.Id
}
return ""
}
func (x *Member) GetType() string {
if x != nil {
return x.Type
}
return ""
}
func (x *Member) GetScopeId() string {
if x != nil {
return x.ScopeId
}
return ""
}
// Group contains all fields related to a Group resource
type Group struct {
state protoimpl.MessageState
@@ -53,12 +122,22 @@ type Group struct {
UpdatedTime *timestamp.Timestamp `protobuf:"bytes,6,opt,name=updated_time,proto3" json:"updated_time,omitempty"`
// Whether the resource is disabled
Disabled *wrappers.BoolValue `protobuf:"bytes,7,opt,name=disabled,proto3" json:"disabled,omitempty"`
// The version can be used in subsiquent write requests to ensure this resource
// has not changed and to fail the write if it has.
// Output only.
Version uint32 `protobuf:"varint,8,opt,name=version,proto3" json:"version,omitempty"`
// Contains the list of member ids in this group.
// Output only.
MemberIds []string `protobuf:"bytes,9,rep,name=member_ids,json=memberIds,proto3" json:"member_ids,omitempty"`
// The members of this group.
// Output only.
Members []*Member `protobuf:"bytes,10,rep,name=members,proto3" json:"members,omitempty"`
}
func (x *Group) Reset() {
*x = Group{}
if protoimpl.UnsafeEnabled {
mi := &file_controller_api_resources_groups_v1_group_proto_msgTypes[0]
mi := &file_controller_api_resources_groups_v1_group_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -71,7 +150,7 @@ func (x *Group) String() string {
func (*Group) ProtoMessage() {}
func (x *Group) ProtoReflect() protoreflect.Message {
mi := &file_controller_api_resources_groups_v1_group_proto_msgTypes[0]
mi := &file_controller_api_resources_groups_v1_group_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -84,7 +163,7 @@ func (x *Group) ProtoReflect() protoreflect.Message {
// Deprecated: Use Group.ProtoReflect.Descriptor instead.
func (*Group) Descriptor() ([]byte, []int) {
return file_controller_api_resources_groups_v1_group_proto_rawDescGZIP(), []int{0}
return file_controller_api_resources_groups_v1_group_proto_rawDescGZIP(), []int{1}
}
func (x *Group) GetId() string {
@@ -136,6 +215,27 @@ func (x *Group) GetDisabled() *wrappers.BoolValue {
return nil
}
func (x *Group) GetVersion() uint32 {
if x != nil {
return x.Version
}
return 0
}
func (x *Group) GetMemberIds() []string {
if x != nil {
return x.MemberIds
}
return nil
}
func (x *Group) GetMembers() []*Member {
if x != nil {
return x.Members
}
return nil
}
var File_controller_api_resources_groups_v1_group_proto protoreflect.FileDescriptor
var file_controller_api_resources_groups_v1_group_proto_rawDesc = []byte{
@@ -154,40 +254,53 @@ var file_controller_api_resources_groups_v1_group_proto_rawDesc = []byte{
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65,
0x72, 0x2f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x73, 0x6b, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
0xb8, 0x03, 0x0a, 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x43, 0x0a, 0x05, 0x73, 0x63, 0x6f,
0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72,
0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x73, 0x2e, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63,
0x6f, 0x70, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x42,
0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53,
0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x10, 0xc2, 0xdd, 0x29, 0x0c,
0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61,
0x6d, 0x65, 0x12, 0x5e, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67,
0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x1e, 0xc2, 0xdd, 0x29, 0x1a, 0x0a, 0x0b, 0x64, 0x65, 0x73,
0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69,
0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73,
0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69,
0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69,
0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73,
0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69,
0x6d, 0x65, 0x12, 0x36, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x07,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65,
0x52, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x42, 0x55, 0x5a, 0x53, 0x67, 0x69,
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f,
0x72, 0x70, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x74, 0x6f, 0x77, 0x65, 0x72, 0x2f, 0x69, 0x6e,
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72,
0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x73, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x3b, 0x67, 0x72, 0x6f, 0x75, 0x70,
0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x48, 0x0a, 0x06, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a,
0x08, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
0x08, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x22, 0xb7, 0x04, 0x0a, 0x05, 0x47, 0x72,
0x6f, 0x75, 0x70, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x02, 0x69, 0x64, 0x12, 0x43, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x63,
0x6f, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x49, 0x6e, 0x66,
0x6f, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x42, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56,
0x61, 0x6c, 0x75, 0x65, 0x42, 0x10, 0xc2, 0xdd, 0x29, 0x0c, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
0x12, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x5e, 0x0a, 0x0b,
0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42,
0x1e, 0xc2, 0xdd, 0x29, 0x1a, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
0x6f, 0x6e, 0x12, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52,
0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x0c,
0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c,
0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x0c,
0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c,
0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x08,
0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x64, 0x69, 0x73, 0x61,
0x62, 0x6c, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18,
0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d,
0x0a, 0x0a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x09, 0x20, 0x03,
0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x44, 0x0a,
0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a,
0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73,
0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x62,
0x65, 0x72, 0x73, 0x42, 0x55, 0x5a, 0x53, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x77, 0x61, 0x74, 0x63,
0x68, 0x74, 0x6f, 0x77, 0x65, 0x72, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f,
0x67, 0x65, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61,
0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x67, 0x72, 0x6f,
0x75, 0x70, 0x73, 0x3b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
}
var (
@@ -202,26 +315,28 @@ func file_controller_api_resources_groups_v1_group_proto_rawDescGZIP() []byte {
return file_controller_api_resources_groups_v1_group_proto_rawDescData
}
var file_controller_api_resources_groups_v1_group_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_controller_api_resources_groups_v1_group_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_controller_api_resources_groups_v1_group_proto_goTypes = []interface{}{
(*Group)(nil), // 0: controller.api.resources.groups.v1.Group
(*scopes.ScopeInfo)(nil), // 1: controller.api.resources.scopes.v1.ScopeInfo
(*wrappers.StringValue)(nil), // 2: google.protobuf.StringValue
(*timestamp.Timestamp)(nil), // 3: google.protobuf.Timestamp
(*wrappers.BoolValue)(nil), // 4: google.protobuf.BoolValue
(*Member)(nil), // 0: controller.api.resources.groups.v1.Member
(*Group)(nil), // 1: controller.api.resources.groups.v1.Group
(*scopes.ScopeInfo)(nil), // 2: controller.api.resources.scopes.v1.ScopeInfo
(*wrappers.StringValue)(nil), // 3: google.protobuf.StringValue
(*timestamp.Timestamp)(nil), // 4: google.protobuf.Timestamp
(*wrappers.BoolValue)(nil), // 5: google.protobuf.BoolValue
}
var file_controller_api_resources_groups_v1_group_proto_depIdxs = []int32{
1, // 0: controller.api.resources.groups.v1.Group.scope:type_name -> controller.api.resources.scopes.v1.ScopeInfo
2, // 1: controller.api.resources.groups.v1.Group.name:type_name -> google.protobuf.StringValue
2, // 2: controller.api.resources.groups.v1.Group.description:type_name -> google.protobuf.StringValue
3, // 3: controller.api.resources.groups.v1.Group.created_time:type_name -> google.protobuf.Timestamp
3, // 4: controller.api.resources.groups.v1.Group.updated_time:type_name -> google.protobuf.Timestamp
4, // 5: controller.api.resources.groups.v1.Group.disabled:type_name -> google.protobuf.BoolValue
6, // [6:6] is the sub-list for method output_type
6, // [6:6] is the sub-list for method input_type
6, // [6:6] is the sub-list for extension type_name
6, // [6:6] is the sub-list for extension extendee
0, // [0:6] is the sub-list for field type_name
2, // 0: controller.api.resources.groups.v1.Group.scope:type_name -> controller.api.resources.scopes.v1.ScopeInfo
3, // 1: controller.api.resources.groups.v1.Group.name:type_name -> google.protobuf.StringValue
3, // 2: controller.api.resources.groups.v1.Group.description:type_name -> google.protobuf.StringValue
4, // 3: controller.api.resources.groups.v1.Group.created_time:type_name -> google.protobuf.Timestamp
4, // 4: controller.api.resources.groups.v1.Group.updated_time:type_name -> google.protobuf.Timestamp
5, // 5: controller.api.resources.groups.v1.Group.disabled:type_name -> google.protobuf.BoolValue
0, // 6: controller.api.resources.groups.v1.Group.members:type_name -> controller.api.resources.groups.v1.Member
7, // [7:7] is the sub-list for method output_type
7, // [7:7] is the sub-list for method input_type
7, // [7:7] is the sub-list for extension type_name
7, // [7:7] is the sub-list for extension extendee
0, // [0:7] is the sub-list for field type_name
}
func init() { file_controller_api_resources_groups_v1_group_proto_init() }
@@ -231,6 +346,18 @@ func file_controller_api_resources_groups_v1_group_proto_init() {
}
if !protoimpl.UnsafeEnabled {
file_controller_api_resources_groups_v1_group_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Member); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_controller_api_resources_groups_v1_group_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Group); i {
case 0:
return &v.state
@@ -249,7 +376,7 @@ func file_controller_api_resources_groups_v1_group_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_controller_api_resources_groups_v1_group_proto_rawDesc,
NumEnums: 0,
NumMessages: 1,
NumMessages: 2,
NumExtensions: 0,
NumServices: 0,
},
@@ -9,6 +9,7 @@ package services
import (
context "context"
proto "github.com/golang/protobuf/proto"
wrappers "github.com/golang/protobuf/ptypes/wrappers"
_ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options"
groups "github.com/hashicorp/watchtower/internal/gen/controller/api/resources/groups"
_ "github.com/hashicorp/watchtower/internal/gen/controller/api/resources/scopes"
@@ -536,6 +537,342 @@ func (x *DeleteGroupResponse) GetExisted() bool {
return false
}
type AddGroupMembersRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
// The version ensures the group hasn't changed since it was last retrieved and if
// it has the request will fail.
Version *wrappers.UInt32Value `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"`
MemberIds []string `protobuf:"bytes,3,rep,name=member_ids,proto3" json:"member_ids,omitempty"`
}
func (x *AddGroupMembersRequest) Reset() {
*x = AddGroupMembersRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_controller_api_services_v1_group_service_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *AddGroupMembersRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AddGroupMembersRequest) ProtoMessage() {}
func (x *AddGroupMembersRequest) ProtoReflect() protoreflect.Message {
mi := &file_controller_api_services_v1_group_service_proto_msgTypes[10]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AddGroupMembersRequest.ProtoReflect.Descriptor instead.
func (*AddGroupMembersRequest) Descriptor() ([]byte, []int) {
return file_controller_api_services_v1_group_service_proto_rawDescGZIP(), []int{10}
}
func (x *AddGroupMembersRequest) GetId() string {
if x != nil {
return x.Id
}
return ""
}
func (x *AddGroupMembersRequest) GetVersion() *wrappers.UInt32Value {
if x != nil {
return x.Version
}
return nil
}
func (x *AddGroupMembersRequest) GetMemberIds() []string {
if x != nil {
return x.MemberIds
}
return nil
}
type AddGroupMembersResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Item *groups.Group `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"`
}
func (x *AddGroupMembersResponse) Reset() {
*x = AddGroupMembersResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_controller_api_services_v1_group_service_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *AddGroupMembersResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AddGroupMembersResponse) ProtoMessage() {}
func (x *AddGroupMembersResponse) ProtoReflect() protoreflect.Message {
mi := &file_controller_api_services_v1_group_service_proto_msgTypes[11]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AddGroupMembersResponse.ProtoReflect.Descriptor instead.
func (*AddGroupMembersResponse) Descriptor() ([]byte, []int) {
return file_controller_api_services_v1_group_service_proto_rawDescGZIP(), []int{11}
}
func (x *AddGroupMembersResponse) GetItem() *groups.Group {
if x != nil {
return x.Item
}
return nil
}
type SetGroupMembersRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
// The version ensures the group hasn't changed since it was last retrieved and if
// it has the request will fail.
Version *wrappers.UInt32Value `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"`
MemberIds []string `protobuf:"bytes,3,rep,name=member_ids,proto3" json:"member_ids,omitempty"`
}
func (x *SetGroupMembersRequest) Reset() {
*x = SetGroupMembersRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_controller_api_services_v1_group_service_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *SetGroupMembersRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SetGroupMembersRequest) ProtoMessage() {}
func (x *SetGroupMembersRequest) ProtoReflect() protoreflect.Message {
mi := &file_controller_api_services_v1_group_service_proto_msgTypes[12]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SetGroupMembersRequest.ProtoReflect.Descriptor instead.
func (*SetGroupMembersRequest) Descriptor() ([]byte, []int) {
return file_controller_api_services_v1_group_service_proto_rawDescGZIP(), []int{12}
}
func (x *SetGroupMembersRequest) GetId() string {
if x != nil {
return x.Id
}
return ""
}
func (x *SetGroupMembersRequest) GetVersion() *wrappers.UInt32Value {
if x != nil {
return x.Version
}
return nil
}
func (x *SetGroupMembersRequest) GetMemberIds() []string {
if x != nil {
return x.MemberIds
}
return nil
}
type SetGroupMembersResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Item *groups.Group `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"`
}
func (x *SetGroupMembersResponse) Reset() {
*x = SetGroupMembersResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_controller_api_services_v1_group_service_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *SetGroupMembersResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SetGroupMembersResponse) ProtoMessage() {}
func (x *SetGroupMembersResponse) ProtoReflect() protoreflect.Message {
mi := &file_controller_api_services_v1_group_service_proto_msgTypes[13]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SetGroupMembersResponse.ProtoReflect.Descriptor instead.
func (*SetGroupMembersResponse) Descriptor() ([]byte, []int) {
return file_controller_api_services_v1_group_service_proto_rawDescGZIP(), []int{13}
}
func (x *SetGroupMembersResponse) GetItem() *groups.Group {
if x != nil {
return x.Item
}
return nil
}
type RemoveGroupMembersRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
// The version ensures the group hasn't changed since it was last retrieved and if
// it has the request will fail.
Version *wrappers.UInt32Value `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"`
MemberIds []string `protobuf:"bytes,3,rep,name=member_ids,proto3" json:"member_ids,omitempty"`
}
func (x *RemoveGroupMembersRequest) Reset() {
*x = RemoveGroupMembersRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_controller_api_services_v1_group_service_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *RemoveGroupMembersRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RemoveGroupMembersRequest) ProtoMessage() {}
func (x *RemoveGroupMembersRequest) ProtoReflect() protoreflect.Message {
mi := &file_controller_api_services_v1_group_service_proto_msgTypes[14]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RemoveGroupMembersRequest.ProtoReflect.Descriptor instead.
func (*RemoveGroupMembersRequest) Descriptor() ([]byte, []int) {
return file_controller_api_services_v1_group_service_proto_rawDescGZIP(), []int{14}
}
func (x *RemoveGroupMembersRequest) GetId() string {
if x != nil {
return x.Id
}
return ""
}
func (x *RemoveGroupMembersRequest) GetVersion() *wrappers.UInt32Value {
if x != nil {
return x.Version
}
return nil
}
func (x *RemoveGroupMembersRequest) GetMemberIds() []string {
if x != nil {
return x.MemberIds
}
return nil
}
type RemoveGroupMembersResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Item *groups.Group `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"`
}
func (x *RemoveGroupMembersResponse) Reset() {
*x = RemoveGroupMembersResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_controller_api_services_v1_group_service_proto_msgTypes[15]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *RemoveGroupMembersResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RemoveGroupMembersResponse) ProtoMessage() {}
func (x *RemoveGroupMembersResponse) ProtoReflect() protoreflect.Message {
mi := &file_controller_api_services_v1_group_service_proto_msgTypes[15]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RemoveGroupMembersResponse.ProtoReflect.Descriptor instead.
func (*RemoveGroupMembersResponse) Descriptor() ([]byte, []int) {
return file_controller_api_services_v1_group_service_proto_rawDescGZIP(), []int{15}
}
func (x *RemoveGroupMembersResponse) GetItem() *groups.Group {
if x != nil {
return x.Item
}
return nil
}
var File_controller_api_services_v1_group_service_proto protoreflect.FileDescriptor
var file_controller_api_services_v1_group_service_proto_rawDesc = []byte{
@@ -550,7 +887,9 @@ var file_controller_api_services_v1_group_service_proto_rawDesc = []byte{
0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f,
0x6d, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
0x6d, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70,
0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x73, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x67,
0x72, 0x6f, 0x75, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
@@ -606,67 +945,156 @@ var file_controller_api_services_v1_group_service_proto_rawDesc = []byte{
0x22, 0x2f, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x69, 0x73, 0x74,
0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x78, 0x69, 0x73, 0x74, 0x65,
0x64, 0x32, 0xe5, 0x06, 0x0a, 0x0c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x12, 0xa5, 0x01, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12,
0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74,
0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x63,
0x64, 0x22, 0x80, 0x01, 0x0a, 0x16, 0x41, 0x64, 0x64, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65,
0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02,
0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x36, 0x0a, 0x07,
0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x76, 0x65, 0x72,
0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x69,
0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72,
0x5f, 0x69, 0x64, 0x73, 0x22, 0x58, 0x0a, 0x17, 0x41, 0x64, 0x64, 0x47, 0x72, 0x6f, 0x75, 0x70,
0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x3d, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e,
0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72,
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e,
0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x80,
0x01, 0x0a, 0x16, 0x53, 0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65,
0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x36, 0x0a, 0x07, 0x76, 0x65, 0x72,
0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e,
0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18,
0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x69, 0x64,
0x73, 0x22, 0x58, 0x0a, 0x17, 0x53, 0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d,
0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x04,
0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6f, 0x6e,
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x76, 0x31, 0x2e,
0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x83, 0x01, 0x0a, 0x19,
0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65,
0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x36, 0x0a, 0x07, 0x76, 0x65, 0x72,
0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e,
0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18,
0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x69, 0x64,
0x73, 0x22, 0x5b, 0x0a, 0x1a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70,
0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x3d, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e,
0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72,
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e,
0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x32, 0xda,
0x0c, 0x0a, 0x0c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12,
0xa5, 0x01, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x2b, 0x2e, 0x63,
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65,
0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x72, 0x6f,
0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3e, 0x82, 0xd3, 0xe4, 0x93,
0x02, 0x20, 0x12, 0x18, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x2f, 0x2a,
0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x62, 0x04, 0x69, 0x74,
0x65, 0x6d, 0x92, 0x41, 0x15, 0x12, 0x13, 0x47, 0x65, 0x74, 0x73, 0x20, 0x61, 0x20, 0x73, 0x69,
0x6e, 0x67, 0x6c, 0x65, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x9d, 0x01, 0x0a, 0x0a, 0x4c,
0x69, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70,
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72,
0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15,
0x12, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x67,
0x72, 0x6f, 0x75, 0x70, 0x73, 0x92, 0x41, 0x12, 0x12, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20,
0x61, 0x6c, 0x6c, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0xb2, 0x01, 0x0a, 0x0b, 0x43,
0x72, 0x65, 0x61, 0x74, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x2e, 0x2e, 0x63, 0x6f, 0x6e,
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x47, 0x72,
0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x63, 0x6f, 0x6e,
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x47, 0x72,
0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x42, 0x82, 0xd3, 0xe4,
0x93, 0x02, 0x21, 0x22, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x2f,
0x2a, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x3a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04,
0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, 0x18, 0x12, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x73,
0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12,
0xb0, 0x01, 0x0a, 0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12,
0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x12,
0x18, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x67, 0x72,
0x6f, 0x75, 0x70, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92,
0x41, 0x15, 0x12, 0x13, 0x47, 0x65, 0x74, 0x73, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c,
0x65, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x9d, 0x01, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74,
0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c,
0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e,
0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f,
0x76, 0x31, 0x2f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x67, 0x72, 0x6f, 0x75,
0x70, 0x73, 0x92, 0x41, 0x12, 0x12, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c,
0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0xb2, 0x01, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61,
0x74, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x42, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21,
0x22, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x67,
0x72, 0x6f, 0x75, 0x70, 0x73, 0x3a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65,
0x6d, 0x92, 0x41, 0x18, 0x12, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20,
0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0xb0, 0x01, 0x0a,
0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x2e, 0x2e, 0x63,
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65,
0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x63,
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65,
0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x40, 0x82,
0xd3, 0xe4, 0x93, 0x02, 0x26, 0x32, 0x18, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x63, 0x6f, 0x70, 0x65,
0x73, 0x2f, 0x2a, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a,
0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, 0x11, 0x12, 0x0f,
0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12,
0xa4, 0x01, 0x0a, 0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12,
0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64,
0x61, 0x74, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c,
0x65, 0x74, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64,
0x61, 0x74, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x40, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x32, 0x18, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x63,
0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c,
0x65, 0x74, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x34, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x2a, 0x18, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x63,
0x6f, 0x70, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2f, 0x7b, 0x69,
0x64, 0x7d, 0x3a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92, 0x41,
0x11, 0x12, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x47, 0x72, 0x6f,
0x75, 0x70, 0x12, 0xa4, 0x01, 0x0a, 0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x72, 0x6f,
0x75, 0x70, 0x12, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e,
0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e,
0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x34, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x2a, 0x18, 0x2f, 0x76, 0x31,
0x64, 0x7d, 0x92, 0x41, 0x11, 0x12, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x20, 0x61,
0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0xd6, 0x01, 0x0a, 0x0f, 0x41, 0x64, 0x64, 0x47, 0x72,
0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x32, 0x2e, 0x63, 0x6f, 0x6e,
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x47, 0x72, 0x6f, 0x75, 0x70,
0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33,
0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x47,
0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x5a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x22, 0x24, 0x2f, 0x76, 0x31,
0x2f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73,
0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x92, 0x41, 0x11, 0x12, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
0x73, 0x20, 0x61, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x42, 0x4f, 0x5a, 0x4d, 0x67, 0x69, 0x74,
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72,
0x70, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x74, 0x6f, 0x77, 0x65, 0x72, 0x2f, 0x69, 0x6e, 0x74,
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x73, 0x3b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x61, 0x64, 0x64, 0x2d, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72,
0x73, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, 0x22, 0x12, 0x20, 0x41,
0x64, 0x64, 0x73, 0x20, 0x55, 0x73, 0x65, 0x72, 0x73, 0x20, 0x61, 0x73, 0x20, 0x6d, 0x65, 0x6d,
0x62, 0x65, 0x72, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12,
0xa9, 0x02, 0x0a, 0x0f, 0x53, 0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62,
0x65, 0x72, 0x73, 0x12, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31,
0x2e, 0x53, 0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d,
0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xac, 0x01, 0x82,
0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x22, 0x24, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x63, 0x6f, 0x70, 0x65,
0x73, 0x2f, 0x2a, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a,
0x73, 0x65, 0x74, 0x2d, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x3a, 0x01, 0x2a, 0x62, 0x04,
0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, 0x74, 0x12, 0x72, 0x53, 0x65, 0x74, 0x20, 0x61, 0x20, 0x47,
0x72, 0x6f, 0x75, 0x70, 0x27, 0x73, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x74,
0x6f, 0x20, 0x65, 0x78, 0x61, 0x63, 0x74, 0x6c, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x69,
0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x69,
0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2c, 0x20, 0x72,
0x65, 0x6d, 0x6f, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x6d, 0x65, 0x6d, 0x62,
0x65, 0x72, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74,
0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2e, 0x12, 0xed, 0x01, 0x0a, 0x12,
0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65,
0x72, 0x73, 0x12, 0x35, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e,
0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65,
0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x47, 0x72, 0x6f,
0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x68, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x32, 0x22, 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x73,
0x63, 0x6f, 0x70, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2f, 0x7b,
0x69, 0x64, 0x7d, 0x3a, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x2d, 0x6d, 0x65, 0x6d, 0x62, 0x65,
0x72, 0x73, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, 0x2d, 0x12, 0x2b,
0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63,
0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x66, 0x72,
0x6f, 0x6d, 0x20, 0x61, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x42, 0x4f, 0x5a, 0x4d, 0x67,
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63,
0x6f, 0x72, 0x70, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x74, 0x6f, 0x77, 0x65, 0x72, 0x2f, 0x69,
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x74,
0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x73, 0x3b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -681,44 +1109,63 @@ func file_controller_api_services_v1_group_service_proto_rawDescGZIP() []byte {
return file_controller_api_services_v1_group_service_proto_rawDescData
}
var file_controller_api_services_v1_group_service_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
var file_controller_api_services_v1_group_service_proto_msgTypes = make([]protoimpl.MessageInfo, 16)
var file_controller_api_services_v1_group_service_proto_goTypes = []interface{}{
(*GetGroupRequest)(nil), // 0: controller.api.services.v1.GetGroupRequest
(*GetGroupResponse)(nil), // 1: controller.api.services.v1.GetGroupResponse
(*ListGroupsRequest)(nil), // 2: controller.api.services.v1.ListGroupsRequest
(*ListGroupsResponse)(nil), // 3: controller.api.services.v1.ListGroupsResponse
(*CreateGroupRequest)(nil), // 4: controller.api.services.v1.CreateGroupRequest
(*CreateGroupResponse)(nil), // 5: controller.api.services.v1.CreateGroupResponse
(*UpdateGroupRequest)(nil), // 6: controller.api.services.v1.UpdateGroupRequest
(*UpdateGroupResponse)(nil), // 7: controller.api.services.v1.UpdateGroupResponse
(*DeleteGroupRequest)(nil), // 8: controller.api.services.v1.DeleteGroupRequest
(*DeleteGroupResponse)(nil), // 9: controller.api.services.v1.DeleteGroupResponse
(*groups.Group)(nil), // 10: controller.api.resources.groups.v1.Group
(*field_mask.FieldMask)(nil), // 11: google.protobuf.FieldMask
(*GetGroupRequest)(nil), // 0: controller.api.services.v1.GetGroupRequest
(*GetGroupResponse)(nil), // 1: controller.api.services.v1.GetGroupResponse
(*ListGroupsRequest)(nil), // 2: controller.api.services.v1.ListGroupsRequest
(*ListGroupsResponse)(nil), // 3: controller.api.services.v1.ListGroupsResponse
(*CreateGroupRequest)(nil), // 4: controller.api.services.v1.CreateGroupRequest
(*CreateGroupResponse)(nil), // 5: controller.api.services.v1.CreateGroupResponse
(*UpdateGroupRequest)(nil), // 6: controller.api.services.v1.UpdateGroupRequest
(*UpdateGroupResponse)(nil), // 7: controller.api.services.v1.UpdateGroupResponse
(*DeleteGroupRequest)(nil), // 8: controller.api.services.v1.DeleteGroupRequest
(*DeleteGroupResponse)(nil), // 9: controller.api.services.v1.DeleteGroupResponse
(*AddGroupMembersRequest)(nil), // 10: controller.api.services.v1.AddGroupMembersRequest
(*AddGroupMembersResponse)(nil), // 11: controller.api.services.v1.AddGroupMembersResponse
(*SetGroupMembersRequest)(nil), // 12: controller.api.services.v1.SetGroupMembersRequest
(*SetGroupMembersResponse)(nil), // 13: controller.api.services.v1.SetGroupMembersResponse
(*RemoveGroupMembersRequest)(nil), // 14: controller.api.services.v1.RemoveGroupMembersRequest
(*RemoveGroupMembersResponse)(nil), // 15: controller.api.services.v1.RemoveGroupMembersResponse
(*groups.Group)(nil), // 16: controller.api.resources.groups.v1.Group
(*field_mask.FieldMask)(nil), // 17: google.protobuf.FieldMask
(*wrappers.UInt32Value)(nil), // 18: google.protobuf.UInt32Value
}
var file_controller_api_services_v1_group_service_proto_depIdxs = []int32{
10, // 0: controller.api.services.v1.GetGroupResponse.item:type_name -> controller.api.resources.groups.v1.Group
10, // 1: controller.api.services.v1.ListGroupsResponse.items:type_name -> controller.api.resources.groups.v1.Group
10, // 2: controller.api.services.v1.CreateGroupRequest.item:type_name -> controller.api.resources.groups.v1.Group
10, // 3: controller.api.services.v1.CreateGroupResponse.item:type_name -> controller.api.resources.groups.v1.Group
10, // 4: controller.api.services.v1.UpdateGroupRequest.item:type_name -> controller.api.resources.groups.v1.Group
11, // 5: controller.api.services.v1.UpdateGroupRequest.update_mask:type_name -> google.protobuf.FieldMask
10, // 6: controller.api.services.v1.UpdateGroupResponse.item:type_name -> controller.api.resources.groups.v1.Group
0, // 7: controller.api.services.v1.GroupService.GetGroup:input_type -> controller.api.services.v1.GetGroupRequest
2, // 8: controller.api.services.v1.GroupService.ListGroups:input_type -> controller.api.services.v1.ListGroupsRequest
4, // 9: controller.api.services.v1.GroupService.CreateGroup:input_type -> controller.api.services.v1.CreateGroupRequest
6, // 10: controller.api.services.v1.GroupService.UpdateGroup:input_type -> controller.api.services.v1.UpdateGroupRequest
8, // 11: controller.api.services.v1.GroupService.DeleteGroup:input_type -> controller.api.services.v1.DeleteGroupRequest
1, // 12: controller.api.services.v1.GroupService.GetGroup:output_type -> controller.api.services.v1.GetGroupResponse
3, // 13: controller.api.services.v1.GroupService.ListGroups:output_type -> controller.api.services.v1.ListGroupsResponse
5, // 14: controller.api.services.v1.GroupService.CreateGroup:output_type -> controller.api.services.v1.CreateGroupResponse
7, // 15: controller.api.services.v1.GroupService.UpdateGroup:output_type -> controller.api.services.v1.UpdateGroupResponse
9, // 16: controller.api.services.v1.GroupService.DeleteGroup:output_type -> controller.api.services.v1.DeleteGroupResponse
12, // [12:17] is the sub-list for method output_type
7, // [7:12] is the sub-list for method input_type
7, // [7:7] is the sub-list for extension type_name
7, // [7:7] is the sub-list for extension extendee
0, // [0:7] is the sub-list for field type_name
16, // 0: controller.api.services.v1.GetGroupResponse.item:type_name -> controller.api.resources.groups.v1.Group
16, // 1: controller.api.services.v1.ListGroupsResponse.items:type_name -> controller.api.resources.groups.v1.Group
16, // 2: controller.api.services.v1.CreateGroupRequest.item:type_name -> controller.api.resources.groups.v1.Group
16, // 3: controller.api.services.v1.CreateGroupResponse.item:type_name -> controller.api.resources.groups.v1.Group
16, // 4: controller.api.services.v1.UpdateGroupRequest.item:type_name -> controller.api.resources.groups.v1.Group
17, // 5: controller.api.services.v1.UpdateGroupRequest.update_mask:type_name -> google.protobuf.FieldMask
16, // 6: controller.api.services.v1.UpdateGroupResponse.item:type_name -> controller.api.resources.groups.v1.Group
18, // 7: controller.api.services.v1.AddGroupMembersRequest.version:type_name -> google.protobuf.UInt32Value
16, // 8: controller.api.services.v1.AddGroupMembersResponse.item:type_name -> controller.api.resources.groups.v1.Group
18, // 9: controller.api.services.v1.SetGroupMembersRequest.version:type_name -> google.protobuf.UInt32Value
16, // 10: controller.api.services.v1.SetGroupMembersResponse.item:type_name -> controller.api.resources.groups.v1.Group
18, // 11: controller.api.services.v1.RemoveGroupMembersRequest.version:type_name -> google.protobuf.UInt32Value
16, // 12: controller.api.services.v1.RemoveGroupMembersResponse.item:type_name -> controller.api.resources.groups.v1.Group
0, // 13: controller.api.services.v1.GroupService.GetGroup:input_type -> controller.api.services.v1.GetGroupRequest
2, // 14: controller.api.services.v1.GroupService.ListGroups:input_type -> controller.api.services.v1.ListGroupsRequest
4, // 15: controller.api.services.v1.GroupService.CreateGroup:input_type -> controller.api.services.v1.CreateGroupRequest
6, // 16: controller.api.services.v1.GroupService.UpdateGroup:input_type -> controller.api.services.v1.UpdateGroupRequest
8, // 17: controller.api.services.v1.GroupService.DeleteGroup:input_type -> controller.api.services.v1.DeleteGroupRequest
10, // 18: controller.api.services.v1.GroupService.AddGroupMembers:input_type -> controller.api.services.v1.AddGroupMembersRequest
12, // 19: controller.api.services.v1.GroupService.SetGroupMembers:input_type -> controller.api.services.v1.SetGroupMembersRequest
14, // 20: controller.api.services.v1.GroupService.RemoveGroupMembers:input_type -> controller.api.services.v1.RemoveGroupMembersRequest
1, // 21: controller.api.services.v1.GroupService.GetGroup:output_type -> controller.api.services.v1.GetGroupResponse
3, // 22: controller.api.services.v1.GroupService.ListGroups:output_type -> controller.api.services.v1.ListGroupsResponse
5, // 23: controller.api.services.v1.GroupService.CreateGroup:output_type -> controller.api.services.v1.CreateGroupResponse
7, // 24: controller.api.services.v1.GroupService.UpdateGroup:output_type -> controller.api.services.v1.UpdateGroupResponse
9, // 25: controller.api.services.v1.GroupService.DeleteGroup:output_type -> controller.api.services.v1.DeleteGroupResponse
11, // 26: controller.api.services.v1.GroupService.AddGroupMembers:output_type -> controller.api.services.v1.AddGroupMembersResponse
13, // 27: controller.api.services.v1.GroupService.SetGroupMembers:output_type -> controller.api.services.v1.SetGroupMembersResponse
15, // 28: controller.api.services.v1.GroupService.RemoveGroupMembers:output_type -> controller.api.services.v1.RemoveGroupMembersResponse
21, // [21:29] is the sub-list for method output_type
13, // [13:21] is the sub-list for method input_type
13, // [13:13] is the sub-list for extension type_name
13, // [13:13] is the sub-list for extension extendee
0, // [0:13] is the sub-list for field type_name
}
func init() { file_controller_api_services_v1_group_service_proto_init() }
@@ -847,6 +1294,78 @@ func file_controller_api_services_v1_group_service_proto_init() {
return nil
}
}
file_controller_api_services_v1_group_service_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*AddGroupMembersRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_controller_api_services_v1_group_service_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*AddGroupMembersResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_controller_api_services_v1_group_service_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SetGroupMembersRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_controller_api_services_v1_group_service_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SetGroupMembersResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_controller_api_services_v1_group_service_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RemoveGroupMembersRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_controller_api_services_v1_group_service_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RemoveGroupMembersResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
@@ -854,7 +1373,7 @@ func file_controller_api_services_v1_group_service_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_controller_api_services_v1_group_service_proto_rawDesc,
NumEnums: 0,
NumMessages: 10,
NumMessages: 16,
NumExtensions: 0,
NumServices: 1,
},
@@ -911,6 +1430,22 @@ type GroupServiceClient interface {
// response itself specifies if the resource existed before the DeleteGroup
// request was received.
DeleteGroup(ctx context.Context, in *DeleteGroupRequest, opts ...grpc.CallOption) (*DeleteGroupResponse, error)
// AddGroupMembers adds users as members to a group. The provided
// request must include the scope id and the group id which the users
// will be set to. If the any of the ids are missing, malformed or references a non
// existing resource, an error is returned.
AddGroupMembers(ctx context.Context, in *AddGroupMembersRequest, opts ...grpc.CallOption) (*AddGroupMembersResponse, error)
// SetGroupMembers sets the group's members. Any existing members on
// the group are deleted if they are not included in this request. The provided
// request must include the scope id and the group id which the users
// will be set to. If the any of the ids are missing, malformed or references a non
// existing resource, an error is returned.
SetGroupMembers(ctx context.Context, in *SetGroupMembersRequest, opts ...grpc.CallOption) (*SetGroupMembersResponse, error)
// RemoveGroupMembers removes members from the specified group.
// The provided request must include the scope id and the group id which the users
// will be set to. If the any of the ids are missing, malformed or references a non
// existing resource, an error is returned.
RemoveGroupMembers(ctx context.Context, in *RemoveGroupMembersRequest, opts ...grpc.CallOption) (*RemoveGroupMembersResponse, error)
}
type groupServiceClient struct {
@@ -966,6 +1501,33 @@ func (c *groupServiceClient) DeleteGroup(ctx context.Context, in *DeleteGroupReq
return out, nil
}
func (c *groupServiceClient) AddGroupMembers(ctx context.Context, in *AddGroupMembersRequest, opts ...grpc.CallOption) (*AddGroupMembersResponse, error) {
out := new(AddGroupMembersResponse)
err := c.cc.Invoke(ctx, "/controller.api.services.v1.GroupService/AddGroupMembers", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *groupServiceClient) SetGroupMembers(ctx context.Context, in *SetGroupMembersRequest, opts ...grpc.CallOption) (*SetGroupMembersResponse, error) {
out := new(SetGroupMembersResponse)
err := c.cc.Invoke(ctx, "/controller.api.services.v1.GroupService/SetGroupMembers", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *groupServiceClient) RemoveGroupMembers(ctx context.Context, in *RemoveGroupMembersRequest, opts ...grpc.CallOption) (*RemoveGroupMembersResponse, error) {
out := new(RemoveGroupMembersResponse)
err := c.cc.Invoke(ctx, "/controller.api.services.v1.GroupService/RemoveGroupMembers", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// GroupServiceServer is the server API for GroupService service.
type GroupServiceServer interface {
// GetGroup returns a stored Group if present. The provided request must
@@ -999,6 +1561,22 @@ type GroupServiceServer interface {
// response itself specifies if the resource existed before the DeleteGroup
// request was received.
DeleteGroup(context.Context, *DeleteGroupRequest) (*DeleteGroupResponse, error)
// AddGroupMembers adds users as members to a group. The provided
// request must include the scope id and the group id which the users
// will be set to. If the any of the ids are missing, malformed or references a non
// existing resource, an error is returned.
AddGroupMembers(context.Context, *AddGroupMembersRequest) (*AddGroupMembersResponse, error)
// SetGroupMembers sets the group's members. Any existing members on
// the group are deleted if they are not included in this request. The provided
// request must include the scope id and the group id which the users
// will be set to. If the any of the ids are missing, malformed or references a non
// existing resource, an error is returned.
SetGroupMembers(context.Context, *SetGroupMembersRequest) (*SetGroupMembersResponse, error)
// RemoveGroupMembers removes members from the specified group.
// The provided request must include the scope id and the group id which the users
// will be set to. If the any of the ids are missing, malformed or references a non
// existing resource, an error is returned.
RemoveGroupMembers(context.Context, *RemoveGroupMembersRequest) (*RemoveGroupMembersResponse, error)
}
// UnimplementedGroupServiceServer can be embedded to have forward compatible implementations.
@@ -1020,6 +1598,15 @@ func (*UnimplementedGroupServiceServer) UpdateGroup(context.Context, *UpdateGrou
func (*UnimplementedGroupServiceServer) DeleteGroup(context.Context, *DeleteGroupRequest) (*DeleteGroupResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeleteGroup not implemented")
}
func (*UnimplementedGroupServiceServer) AddGroupMembers(context.Context, *AddGroupMembersRequest) (*AddGroupMembersResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method AddGroupMembers not implemented")
}
func (*UnimplementedGroupServiceServer) SetGroupMembers(context.Context, *SetGroupMembersRequest) (*SetGroupMembersResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method SetGroupMembers not implemented")
}
func (*UnimplementedGroupServiceServer) RemoveGroupMembers(context.Context, *RemoveGroupMembersRequest) (*RemoveGroupMembersResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method RemoveGroupMembers not implemented")
}
func RegisterGroupServiceServer(s *grpc.Server, srv GroupServiceServer) {
s.RegisterService(&_GroupService_serviceDesc, srv)
@@ -1115,6 +1702,60 @@ func _GroupService_DeleteGroup_Handler(srv interface{}, ctx context.Context, dec
return interceptor(ctx, in, info, handler)
}
func _GroupService_AddGroupMembers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(AddGroupMembersRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GroupServiceServer).AddGroupMembers(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/controller.api.services.v1.GroupService/AddGroupMembers",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GroupServiceServer).AddGroupMembers(ctx, req.(*AddGroupMembersRequest))
}
return interceptor(ctx, in, info, handler)
}
func _GroupService_SetGroupMembers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SetGroupMembersRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GroupServiceServer).SetGroupMembers(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/controller.api.services.v1.GroupService/SetGroupMembers",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GroupServiceServer).SetGroupMembers(ctx, req.(*SetGroupMembersRequest))
}
return interceptor(ctx, in, info, handler)
}
func _GroupService_RemoveGroupMembers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(RemoveGroupMembersRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GroupServiceServer).RemoveGroupMembers(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/controller.api.services.v1.GroupService/RemoveGroupMembers",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GroupServiceServer).RemoveGroupMembers(ctx, req.(*RemoveGroupMembersRequest))
}
return interceptor(ctx, in, info, handler)
}
var _GroupService_serviceDesc = grpc.ServiceDesc{
ServiceName: "controller.api.services.v1.GroupService",
HandlerType: (*GroupServiceServer)(nil),
@@ -1139,6 +1780,18 @@ var _GroupService_serviceDesc = grpc.ServiceDesc{
MethodName: "DeleteGroup",
Handler: _GroupService_DeleteGroup_Handler,
},
{
MethodName: "AddGroupMembers",
Handler: _GroupService_AddGroupMembers_Handler,
},
{
MethodName: "SetGroupMembers",
Handler: _GroupService_SetGroupMembers_Handler,
},
{
MethodName: "RemoveGroupMembers",
Handler: _GroupService_RemoveGroupMembers_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "controller/api/services/v1/group_service.proto",
@@ -331,6 +331,216 @@ func local_request_GroupService_DeleteGroup_0(ctx context.Context, marshaler run
}
func request_GroupService_AddGroupMembers_0(ctx context.Context, marshaler runtime.Marshaler, client GroupServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq AddGroupMembersRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
}
protoReq.Id, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
}
msg, err := client.AddGroupMembers(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_GroupService_AddGroupMembers_0(ctx context.Context, marshaler runtime.Marshaler, server GroupServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq AddGroupMembersRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
}
protoReq.Id, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
}
msg, err := server.AddGroupMembers(ctx, &protoReq)
return msg, metadata, err
}
func request_GroupService_SetGroupMembers_0(ctx context.Context, marshaler runtime.Marshaler, client GroupServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq SetGroupMembersRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
}
protoReq.Id, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
}
msg, err := client.SetGroupMembers(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_GroupService_SetGroupMembers_0(ctx context.Context, marshaler runtime.Marshaler, server GroupServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq SetGroupMembersRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
}
protoReq.Id, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
}
msg, err := server.SetGroupMembers(ctx, &protoReq)
return msg, metadata, err
}
func request_GroupService_RemoveGroupMembers_0(ctx context.Context, marshaler runtime.Marshaler, client GroupServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq RemoveGroupMembersRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
}
protoReq.Id, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
}
msg, err := client.RemoveGroupMembers(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_GroupService_RemoveGroupMembers_0(ctx context.Context, marshaler runtime.Marshaler, server GroupServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq RemoveGroupMembersRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
}
protoReq.Id, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
}
msg, err := server.RemoveGroupMembers(ctx, &protoReq)
return msg, metadata, err
}
// RegisterGroupServiceHandlerServer registers the http handlers for service GroupService to "mux".
// UnaryRPC :call GroupServiceServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
@@ -436,6 +646,66 @@ func RegisterGroupServiceHandlerServer(ctx context.Context, mux *runtime.ServeMu
})
mux.Handle("POST", pattern_GroupService_AddGroupMembers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_GroupService_AddGroupMembers_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_GroupService_AddGroupMembers_0(ctx, mux, outboundMarshaler, w, req, response_GroupService_AddGroupMembers_0{resp}, mux.GetForwardResponseOptions()...)
})
mux.Handle("POST", pattern_GroupService_SetGroupMembers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_GroupService_SetGroupMembers_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_GroupService_SetGroupMembers_0(ctx, mux, outboundMarshaler, w, req, response_GroupService_SetGroupMembers_0{resp}, mux.GetForwardResponseOptions()...)
})
mux.Handle("POST", pattern_GroupService_RemoveGroupMembers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_GroupService_RemoveGroupMembers_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_GroupService_RemoveGroupMembers_0(ctx, mux, outboundMarshaler, w, req, response_GroupService_RemoveGroupMembers_0{resp}, mux.GetForwardResponseOptions()...)
})
return nil
}
@@ -577,6 +847,66 @@ func RegisterGroupServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu
})
mux.Handle("POST", pattern_GroupService_AddGroupMembers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_GroupService_AddGroupMembers_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_GroupService_AddGroupMembers_0(ctx, mux, outboundMarshaler, w, req, response_GroupService_AddGroupMembers_0{resp}, mux.GetForwardResponseOptions()...)
})
mux.Handle("POST", pattern_GroupService_SetGroupMembers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_GroupService_SetGroupMembers_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_GroupService_SetGroupMembers_0(ctx, mux, outboundMarshaler, w, req, response_GroupService_SetGroupMembers_0{resp}, mux.GetForwardResponseOptions()...)
})
mux.Handle("POST", pattern_GroupService_RemoveGroupMembers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_GroupService_RemoveGroupMembers_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_GroupService_RemoveGroupMembers_0(ctx, mux, outboundMarshaler, w, req, response_GroupService_RemoveGroupMembers_0{resp}, mux.GetForwardResponseOptions()...)
})
return nil
}
@@ -607,6 +937,33 @@ func (m response_GroupService_UpdateGroup_0) XXX_ResponseBody() interface{} {
return response.Item
}
type response_GroupService_AddGroupMembers_0 struct {
proto.Message
}
func (m response_GroupService_AddGroupMembers_0) XXX_ResponseBody() interface{} {
response := m.Message.(*AddGroupMembersResponse)
return response.Item
}
type response_GroupService_SetGroupMembers_0 struct {
proto.Message
}
func (m response_GroupService_SetGroupMembers_0) XXX_ResponseBody() interface{} {
response := m.Message.(*SetGroupMembersResponse)
return response.Item
}
type response_GroupService_RemoveGroupMembers_0 struct {
proto.Message
}
func (m response_GroupService_RemoveGroupMembers_0) XXX_ResponseBody() interface{} {
response := m.Message.(*RemoveGroupMembersResponse)
return response.Item
}
var (
pattern_GroupService_GetGroup_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "scopes", "groups", "id"}, "", runtime.AssumeColonVerbOpt(true)))
@@ -617,6 +974,12 @@ var (
pattern_GroupService_UpdateGroup_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "scopes", "groups", "id"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_GroupService_DeleteGroup_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "scopes", "groups", "id"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_GroupService_AddGroupMembers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "scopes", "groups", "id"}, "add-members", runtime.AssumeColonVerbOpt(true)))
pattern_GroupService_SetGroupMembers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "scopes", "groups", "id"}, "set-members", runtime.AssumeColonVerbOpt(true)))
pattern_GroupService_RemoveGroupMembers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "scopes", "groups", "id"}, "remove-members", runtime.AssumeColonVerbOpt(true)))
)
var (
@@ -629,4 +992,10 @@ var (
forward_GroupService_UpdateGroup_0 = runtime.ForwardResponseMessage
forward_GroupService_DeleteGroup_0 = runtime.ForwardResponseMessage
forward_GroupService_AddGroupMembers_0 = runtime.ForwardResponseMessage
forward_GroupService_SetGroupMembers_0 = runtime.ForwardResponseMessage
forward_GroupService_RemoveGroupMembers_0 = runtime.ForwardResponseMessage
)
+15
View File
@@ -9,6 +9,21 @@ import (
"google.golang.org/protobuf/proto"
)
// MemberType defines the possible membership types for groups.
type MemberType uint32
const (
UnknownMemberType MemberType = 0
UserMemberType MemberType = 1
)
func (m MemberType) String() string {
return [...]string{
"unknown",
"user",
}[m]
}
const (
groupMemberViewDefaultTableName = "iam_group_member"
groupMemberUserDefaultTable = "iam_group_member_user"
+67 -24
View File
@@ -45,22 +45,22 @@ func (r *Repository) CreateGroup(ctx context.Context, group *Group, opt ...Optio
// be updated. Fields will be set to NULL if the field is a zero value and
// included in fieldMask. Name and Description are the only updatable fields,
// If no updatable fields are included in the fieldMaskPaths, then an error is returned.
func (r *Repository) UpdateGroup(ctx context.Context, group *Group, fieldMaskPaths []string, opt ...Option) (*Group, int, error) {
func (r *Repository) UpdateGroup(ctx context.Context, group *Group, fieldMaskPaths []string, opt ...Option) (*Group, []*GroupMember, int, error) {
if group == nil {
return nil, db.NoRowsAffected, fmt.Errorf("update group: missing group %w", db.ErrNilParameter)
return nil, nil, db.NoRowsAffected, fmt.Errorf("update group: missing group %w", db.ErrNilParameter)
}
if group.Group == nil {
return nil, db.NoRowsAffected, fmt.Errorf("update group: missing group store %w", db.ErrNilParameter)
return nil, nil, db.NoRowsAffected, fmt.Errorf("update group: missing group store %w", db.ErrNilParameter)
}
if group.PublicId == "" {
return nil, db.NoRowsAffected, fmt.Errorf("update group: missing group public id %w", db.ErrInvalidParameter)
return nil, nil, db.NoRowsAffected, fmt.Errorf("update group: missing group public id %w", db.ErrInvalidParameter)
}
for _, f := range fieldMaskPaths {
switch {
case strings.EqualFold("name", f):
case strings.EqualFold("description", f):
default:
return nil, db.NoRowsAffected, fmt.Errorf("update group: field: %s: %w", f, db.ErrInvalidFieldMask)
return nil, nil, db.NoRowsAffected, fmt.Errorf("update group: field: %s: %w", f, db.ErrInvalidFieldMask)
}
}
var dbMask, nullFields []string
@@ -72,31 +72,74 @@ func (r *Repository) UpdateGroup(ctx context.Context, group *Group, fieldMaskPat
fieldMaskPaths,
)
if len(dbMask) == 0 && len(nullFields) == 0 {
return nil, db.NoRowsAffected, fmt.Errorf("update group: %w", db.ErrEmptyFieldMask)
return nil, nil, db.NoRowsAffected, fmt.Errorf("update group: %w", db.ErrEmptyFieldMask)
}
g := group.Clone().(*Group)
resource, rowsUpdated, err := r.update(ctx, g, dbMask, nullFields)
var resource Resource
var rowsUpdated int
var members []*GroupMember
_, err := r.writer.DoTx(
ctx,
db.StdRetryCnt,
db.ExpBackoff{},
func(read db.Reader, w db.Writer) error {
var err error
g := group.Clone().(*Group)
resource, rowsUpdated, err = r.update(ctx, g, dbMask, nullFields)
if err != nil {
return err
}
repo, err := NewRepository(read, w, r.wrapper)
if err != nil {
return fmt.Errorf("update group: failed creating inner repo: %w for %s", err, group.PublicId)
}
members, err = repo.ListGroupMembers(ctx, group.PublicId)
if err != nil {
return fmt.Errorf("update group: listing group members: %w for %s", err, group.PublicId)
}
return nil
},
)
if err != nil {
if db.IsUniqueError(err) {
return nil, db.NoRowsAffected, fmt.Errorf("update group: group %s already exists in org %s: %w", group.Name, group.ScopeId, db.ErrNotUnique)
return nil, nil, db.NoRowsAffected, fmt.Errorf("update group: group %s already exists in org %s: %w", group.Name, group.ScopeId, db.ErrNotUnique)
}
return nil, db.NoRowsAffected, fmt.Errorf("update group: %w for %s", err, group.PublicId)
return nil, nil, db.NoRowsAffected, fmt.Errorf("update group: %w for %s", err, group.PublicId)
}
return resource.(*Group), rowsUpdated, err
return resource.(*Group), members, rowsUpdated, err
}
// LookupGroup will look up a group in the repository. If the group is not
// found, it will return nil, nil.
func (r *Repository) LookupGroup(ctx context.Context, withPublicId string, opt ...Option) (*Group, error) {
func (r *Repository) LookupGroup(ctx context.Context, withPublicId string, opt ...Option) (*Group, []*GroupMember, error) {
if withPublicId == "" {
return nil, fmt.Errorf("lookup group: missing public id %w", db.ErrNilParameter)
return nil, nil, fmt.Errorf("lookup group: missing public id %w", db.ErrNilParameter)
}
g := allocGroup()
g.PublicId = withPublicId
if err := r.reader.LookupByPublicId(ctx, &g); err != nil {
return nil, fmt.Errorf("lookup group: failed %w for %s", err, withPublicId)
var members []*GroupMember
_, err := r.writer.DoTx(
ctx,
db.StdRetryCnt,
db.ExpBackoff{},
func(read db.Reader, w db.Writer) error {
if err := read.LookupByPublicId(ctx, &g); err != nil {
return fmt.Errorf("lookup group: failed %w for %s", err, withPublicId)
}
repo, err := NewRepository(read, w, r.wrapper)
if err != nil {
return fmt.Errorf("lookup group: failed creating inner repo: %w for %s", err, withPublicId)
}
members, err = repo.ListGroupMembers(ctx, withPublicId)
if err != nil {
return fmt.Errorf("lookup group: listing group members: %w for %s", err, withPublicId)
}
return nil
},
)
if err != nil {
return nil, nil, fmt.Errorf("lookup group: failed %w for %s", err, withPublicId)
}
return &g, nil
return &g, members, nil
}
// DeleteGroup will delete a group from the repository.
@@ -184,7 +227,7 @@ func (r *Repository) AddGroupMembers(ctx context.Context, groupId string, groupV
}
updatedGroup := allocGroup()
updatedGroup.PublicId = groupId
updatedGroup.Version = uint32(groupVersion) + 1
updatedGroup.Version = groupVersion + 1
var groupOplogMsg oplog.Message
rowsUpdated, err := w.Update(ctx, &updatedGroup, []string{"Version"}, nil, db.NewOplogMsg(&groupOplogMsg), db.WithVersion(&groupVersion))
if err != nil {
@@ -271,7 +314,7 @@ func (r *Repository) DeleteGroupMembers(ctx context.Context, groupId string, gro
}
updatedGroup := allocGroup()
updatedGroup.PublicId = groupId
updatedGroup.Version = uint32(groupVersion) + 1
updatedGroup.Version = groupVersion + 1
var groupOplogMsg oplog.Message
rowsUpdated, err := w.Update(ctx, &updatedGroup, []string{"Version"}, nil, db.NewOplogMsg(&groupOplogMsg), db.WithVersion(&groupVersion))
if err != nil {
@@ -314,7 +357,7 @@ func (r *Repository) DeleteGroupMembers(ctx context.Context, groupId string, gro
// and will return an error.
func (r *Repository) SetGroupMembers(ctx context.Context, groupId string, groupVersion uint32, userIds []string, opt ...Option) ([]*GroupMember, int, error) {
if groupId == "" {
return nil, db.NoRowsAffected, fmt.Errorf("set group members: missing role id: %w", db.ErrInvalidParameter)
return nil, db.NoRowsAffected, fmt.Errorf("set group members: missing group id: %w", db.ErrInvalidParameter)
}
if groupVersion == 0 {
return nil, db.NoRowsAffected, fmt.Errorf("set group members: version cannot be zero: %w", db.ErrInvalidParameter)
@@ -323,7 +366,7 @@ func (r *Repository) SetGroupMembers(ctx context.Context, groupId string, groupV
group.PublicId = groupId
scope, err := group.GetScope(ctx, r.reader)
if err != nil {
return nil, db.NoRowsAffected, fmt.Errorf("set group members: unable to get role %s scope: %w", groupId, err)
return nil, db.NoRowsAffected, fmt.Errorf("set group members: unable to get members %s scope: %w", groupId, err)
}
// find existing members (since we're using groupVersion, we can safely do
@@ -392,7 +435,7 @@ func (r *Repository) SetGroupMembers(ctx context.Context, groupId string, groupV
}
updatedGroup := allocGroup()
updatedGroup.PublicId = groupId
updatedGroup.Version = uint32(groupVersion) + 1
updatedGroup.Version = groupVersion + 1
var groupOplogMsg oplog.Message
rowsUpdated, err := w.Update(ctx, &updatedGroup, []string{"Version"}, nil, db.NewOplogMsg(&groupOplogMsg), db.WithVersion(&groupVersion))
if err != nil {
@@ -405,7 +448,7 @@ func (r *Repository) SetGroupMembers(ctx context.Context, groupId string, groupV
userOplogMsgs := make([]*oplog.Message, 0, len(deleteMembers))
rowsDeleted, err := w.DeleteItems(ctx, deleteMembers, db.NewOplogMsgs(&userOplogMsgs))
if err != nil {
return fmt.Errorf("set group members: unable to delete user roles: %w", err)
return fmt.Errorf("set group members: unable to delete group member: %w", err)
}
if rowsDeleted != len(deleteMembers) {
return fmt.Errorf("set group members: members deleted %d did not match request for %d", rowsDeleted, len(deleteMembers))
@@ -424,8 +467,8 @@ func (r *Repository) SetGroupMembers(ctx context.Context, groupId string, groupV
metadata["op-type"] = append(metadata["op-type"], oplog.OpType_OP_TYPE_CREATE.String())
}
// we're done with all the principal writes, so let's write the
// role's update oplog message
// we're done with all the membership writes, so let's write the
// group's update oplog message
if err := w.WriteOplogEntryWith(ctx, r.wrapper, groupTicket, metadata, msgs); err != nil {
return fmt.Errorf("set group members: unable to write oplog for additions: %w", err)
}
+5 -5
View File
@@ -161,7 +161,7 @@ func TestRepository_CreateGroup(t *testing.T) {
assert.NotNil(grp.CreateTime)
assert.NotNil(grp.UpdateTime)
foundGrp, err := repo.LookupGroup(context.Background(), grp.PublicId)
foundGrp, _, err := repo.LookupGroup(context.Background(), grp.PublicId)
assert.NoError(err)
assert.True(proto.Equal(foundGrp, grp))
@@ -400,7 +400,7 @@ func TestRepository_UpdateGroup(t *testing.T) {
if tt.wantDup {
g := TestGroup(t, conn, org.PublicId)
g.Name = tt.args.name
_, _, err := repo.UpdateGroup(context.Background(), g, tt.args.fieldMaskPaths, tt.args.opt...)
_, _, _, err := repo.UpdateGroup(context.Background(), g, tt.args.fieldMaskPaths, tt.args.opt...)
assert.NoError(err)
}
@@ -426,7 +426,7 @@ func TestRepository_UpdateGroup(t *testing.T) {
groupAfterUpdate = resource.(*Group)
}
} else {
groupAfterUpdate, updatedRows, err = repo.UpdateGroup(context.Background(), &updateGrp, tt.args.fieldMaskPaths, tt.args.opt...)
groupAfterUpdate, _, updatedRows, err = repo.UpdateGroup(context.Background(), &updateGrp, tt.args.fieldMaskPaths, tt.args.opt...)
}
if tt.wantErr {
assert.Error(err)
@@ -449,7 +449,7 @@ func TestRepository_UpdateGroup(t *testing.T) {
default:
assert.NotEqual(u.UpdateTime, groupAfterUpdate.UpdateTime)
}
foundGrp, err := repo.LookupGroup(context.Background(), u.PublicId)
foundGrp, _, err := repo.LookupGroup(context.Background(), u.PublicId)
assert.NoError(err)
assert.True(proto.Equal(groupAfterUpdate, foundGrp))
dbassert := dbassert.New(t, rw)
@@ -539,7 +539,7 @@ func TestRepository_DeleteGroup(t *testing.T) {
}
assert.NoError(err)
assert.Equal(tt.wantRowsDeleted, deletedRows)
foundGroup, err := repo.LookupGroup(context.Background(), tt.args.group.PublicId)
foundGroup, _, err := repo.LookupGroup(context.Background(), tt.args.group.PublicId)
assert.Error(err)
assert.Nil(foundGroup)
assert.True(errors.Is(err, db.ErrRecordNotFound))
@@ -9,6 +9,20 @@ import "google/protobuf/wrappers.proto";
import "controller/api/resources/scopes/v1/scope.proto";
import "controller/custom_options/v1/masks.proto";
message Member {
// The ID of the member.
// Output only.
string id = 1;
// The type of the member.
// Output only.
string type = 2;
// The scope ID of the member.
// Output only.
string scope_id = 3 [json_name="scope_id"];
}
// Group contains all fields related to a Group resource
message Group {
// The ID of the Project
@@ -18,7 +32,7 @@ message Group {
// Scope information for this resource
// Output only.
resources.scopes.v1.ScopeInfo scope = 2;
// Optional name for identification purposes
google.protobuf.StringValue name = 3 [(custom_options.v1.mask_mapping) = {this:"name" that: "name"}];
@@ -35,4 +49,17 @@ message Group {
// Whether the resource is disabled
google.protobuf.BoolValue disabled = 7;
// The version can be used in subsiquent write requests to ensure this resource
// has not changed and to fail the write if it has.
// Output only.
uint32 version = 8;
// Contains the list of member ids in this group.
// Output only.
repeated string member_ids = 9;
// The members of this group.
// Output only.
repeated Member members = 10;
}
@@ -7,6 +7,7 @@ option go_package = "github.com/hashicorp/watchtower/internal/gen/controller/api
import "protoc-gen-swagger/options/annotations.proto";
import "google/api/annotations.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/wrappers.proto";
import "controller/api/resources/groups/v1/group.proto";
import "controller/api/resources/scopes/v1/scope.proto";
@@ -87,6 +88,52 @@ service GroupService {
summary: "Deletes a Group"
};
}
// AddGroupMembers adds users as members to a group. The provided
// request must include the scope id and the group id which the users
// will be set to. If the any of the ids are missing, malformed or references a non
// existing resource, an error is returned.
rpc AddGroupMembers(AddGroupMembersRequest) returns (AddGroupMembersResponse) {
option (google.api.http) = {
post: "/v1/scopes/*/groups/{id}:add-members"
body: "*"
response_body: "item"
};
option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = {
summary: "Adds Users as members to a Group"
};
}
// SetGroupMembers sets the group's members. Any existing members on
// the group are deleted if they are not included in this request. The provided
// request must include the scope id and the group id which the users
// will be set to. If the any of the ids are missing, malformed or references a non
// existing resource, an error is returned.
rpc SetGroupMembers(SetGroupMembersRequest) returns (SetGroupMembersResponse) {
option (google.api.http) = {
post: "/v1/scopes/*/groups/{id}:set-members"
body: "*"
response_body: "item"
};
option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = {
summary: "Set a Group's members to exactly the list of provided in the request, removing any members that are not specified."
};
}
// RemoveGroupMembers removes members from the specified group.
// The provided request must include the scope id and the group id which the users
// will be set to. If the any of the ids are missing, malformed or references a non
// existing resource, an error is returned.
rpc RemoveGroupMembers(RemoveGroupMembersRequest) returns (RemoveGroupMembersResponse) {
option (google.api.http) = {
post: "/v1/scopes/*/groups/{id}:remove-members"
body: "*"
response_body: "item"
};
option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = {
summary: "Removes the specified members from a Group."
};
}
}
message GetGroupRequest {
@@ -132,3 +179,39 @@ message DeleteGroupRequest {
message DeleteGroupResponse {
bool existed = 1;
}
message AddGroupMembersRequest {
string id = 1;
// The version ensures the group hasn't changed since it was last retrieved and if
// it has the request will fail.
google.protobuf.UInt32Value version = 2;
repeated string member_ids = 3 [json_name="member_ids"];
}
message AddGroupMembersResponse {
resources.groups.v1.Group item = 1;
}
message SetGroupMembersRequest {
string id = 1;
// The version ensures the group hasn't changed since it was last retrieved and if
// it has the request will fail.
google.protobuf.UInt32Value version = 2;
repeated string member_ids = 3 [json_name="member_ids"];
}
message SetGroupMembersResponse {
resources.groups.v1.Group item = 1;
}
message RemoveGroupMembersRequest {
string id = 1;
// The version ensures the group hasn't changed since it was last retrieved and if
// it has the request will fail.
google.protobuf.UInt32Value version = 2;
repeated string member_ids = 3 [json_name="member_ids"];
}
message RemoveGroupMembersResponse {
resources.groups.v1.Group item = 1;
}
+54 -125
View File
@@ -1,103 +1,17 @@
package controller
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/hashicorp/watchtower/internal/gen/controller/api/services"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestGrpcGatewayRouting(t *testing.T) {
ctx := context.Background()
// The unimplemented result indicates the grpc routing is happening successfully otherwise it would return NotFound.
routed := http.StatusNotImplemented
unrouted := http.StatusNotFound
cases := []struct {
name string
setup func(mux *runtime.ServeMux)
url string
expectedResult int
}{
{
name: "users",
setup: func(mux *runtime.ServeMux) {
require.NoError(t, services.RegisterUserServiceHandlerServer(ctx, mux, &services.UnimplementedUserServiceServer{}))
},
url: "v1/scopes/someid/users",
expectedResult: routed,
},
{
name: "roles",
setup: func(mux *runtime.ServeMux) {
require.NoError(t, services.RegisterRoleServiceHandlerServer(ctx, mux, &services.UnimplementedRoleServiceServer{}))
},
url: "v1/scopes/someid/roles",
expectedResult: routed,
},
{
name: "groups",
setup: func(mux *runtime.ServeMux) {
require.NoError(t, services.RegisterGroupServiceHandlerServer(ctx, mux, &services.UnimplementedGroupServiceServer{}))
},
url: "v1/scopes/someid/groups",
expectedResult: routed,
},
{
name: "not routed",
setup: func(mux *runtime.ServeMux) {},
url: "v1/nothing",
expectedResult: unrouted,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
mux := runtime.NewServeMux()
tc.setup(mux)
// List request
req := httptest.NewRequest("GET", fmt.Sprintf("http://localhost/%s", tc.url), nil)
resp := httptest.NewRecorder()
mux.ServeHTTP(resp, req)
assert.Equal(t, tc.expectedResult, resp.Result().StatusCode, "Got response %v", resp)
// Create request
req = httptest.NewRequest("POST", fmt.Sprintf("http://localhost/%s", tc.url), nil)
resp = httptest.NewRecorder()
mux.ServeHTTP(resp, req)
assert.Equal(t, tc.expectedResult, resp.Result().StatusCode, "Got response %v", resp)
// Get request
req = httptest.NewRequest("GET", fmt.Sprintf("http://localhost/%s/somemadeupid", tc.url), nil)
resp = httptest.NewRecorder()
mux.ServeHTTP(resp, req)
assert.Equal(t, tc.expectedResult, resp.Result().StatusCode, "Got response %v", resp)
// Update request
req = httptest.NewRequest("PATCH", fmt.Sprintf("http://localhost/%s/somemadeupid", tc.url), nil)
resp = httptest.NewRecorder()
mux.ServeHTTP(resp, req)
assert.Equal(t, tc.expectedResult, resp.Result().StatusCode, "Got response %v", resp)
// Delete request
req = httptest.NewRequest("DELETE", fmt.Sprintf("http://localhost/%s/somemadeupid", tc.url), nil)
resp = httptest.NewRecorder()
mux.ServeHTTP(resp, req)
assert.Equal(t, tc.expectedResult, resp.Result().StatusCode, "Got response %v", resp)
})
}
}
func TestAuthenticationHandler(t *testing.T) {
c := NewTestController(t, &TestControllerOpts{DefaultOrgId: "o_1234567890"})
defer c.Shutdown()
@@ -120,48 +34,63 @@ func TestAuthenticationHandler(t *testing.T) {
assert.Truef(t, strings.HasPrefix(tok, pubId), "Token: %q, Id: %q", tok, pubId)
}
func TestGrpcGatewayRouting_CustomActions(t *testing.T) {
ctx := context.Background()
// The unimplemented result indicates the grpc routing is happening successfully otherwise it would return NotFound.
routed := http.StatusNotImplemented
func TestHandleImplementedPaths(t *testing.T) {
c := NewTestController(t, &TestControllerOpts{
DisableAuthorizationFailures: true,
})
defer c.Shutdown()
cases := []struct {
name string
setup func(mux *runtime.ServeMux)
post_urls []string
}{
{
name: "roles",
setup: func(mux *runtime.ServeMux) {
require.NoError(t, services.RegisterRoleServiceHandlerServer(ctx, mux, &services.UnimplementedRoleServiceServer{}))
},
post_urls: []string{
"v1/scopes/someid/roles/r_anotherid:add-principals",
"v1/scopes/someid/roles/r_anotherid:set-principals",
"v1/scopes/someid/roles/r_anotherid:remove-principals",
"v1/scopes/someid/roles/r_anotherid:add-principals",
"v1/scopes/someid/roles/r_anotherid:set-principals",
"v1/scopes/someid/roles/r_anotherid:remove-principals",
"v1/scopes/someid/roles/r_anotherid:add-grants",
"v1/scopes/someid/roles/r_anotherid:set-grants",
"v1/scopes/someid/roles/r_anotherid:remove-grants",
"v1/scopes/someid/roles/r_anotherid:add-grants",
"v1/scopes/someid/roles/r_anotherid:set-grants",
"v1/scopes/someid/roles/r_anotherid:remove-grants",
},
for verb, paths := range map[string][]string{
"GET": {
"v1/scopes/someid",
"v1/scopes/someid/users",
"v1/scopes/someid/users/someid",
"v1/scopes/someid/roles",
"v1/scopes/someid/roles/someid",
"v1/scopes/someid/groups",
"v1/scopes/someid/groups/someid",
"v1/scopes/someid/host-catalogs",
"v1/scopes/someid/host-catalogs/someid",
},
}
"POST": {
// Creation end points
"v1/scopes",
"v1/scopes/someid/users",
"v1/scopes/someid/roles",
"v1/scopes/someid/groups",
for _, tc := range cases {
for _, url := range tc.post_urls {
t.Run(tc.name+"_"+url, func(t *testing.T) {
mux := runtime.NewServeMux()
tc.setup(mux)
req := httptest.NewRequest("POST", fmt.Sprintf("http://localhost/%s", url), nil)
resp := httptest.NewRecorder()
mux.ServeHTTP(resp, req)
assert.Equal(t, routed, resp.Result().StatusCode, "Got response %v", resp)
// custom methods
"v1/scopes/someid/roles/someid:add-principals",
"v1/scopes/someid/roles/someid:set-principals",
"v1/scopes/someid/roles/someid:remove-principals",
"v1/scopes/someid/roles/someid:add-grants",
"v1/scopes/someid/roles/someid:set-grants",
"v1/scopes/someid/roles/someid:remove-grants",
"v1/scopes/someid/groups/someid:add-members",
"v1/scopes/someid/groups/someid:set-members",
"v1/scopes/someid/groups/someid:remove-members",
},
"DELETE": {
"v1/scopes/someid",
"v1/scopes/someid/users/someid",
"v1/scopes/someid/roles/someid",
"v1/scopes/someid/groups/someid",
},
"PATCH": {
"v1/scopes/someid",
"v1/scopes/someid/users/someid",
"v1/scopes/someid/roles/someid",
"v1/scopes/someid/groups/someid",
},
} {
for _, p := range paths {
t.Run(fmt.Sprintf("%s/%s", verb, p), func(t *testing.T) {
url := fmt.Sprintf("%s/%s", c.ApiAddrs()[0], p)
req, err := http.NewRequest(verb, url, nil)
require.NoError(t, err)
resp, err := http.DefaultClient.Do(req)
require.NoError(t, err)
assert.NotEqualf(t, resp.StatusCode, http.StatusNotFound, "Got response %v, wanted not 404", resp.StatusCode)
})
}
}
@@ -132,22 +132,70 @@ func (s Service) DeleteGroup(ctx context.Context, req *pbs.DeleteGroupRequest) (
return &pbs.DeleteGroupResponse{Existed: existed}, nil
}
// AddGroupMembers implements the interface pbs.GroupServiceServer.
func (s Service) AddGroupMembers(ctx context.Context, req *pbs.AddGroupMembersRequest) (*pbs.AddGroupMembersResponse, error) {
authResults := auth.Verify(ctx)
if !authResults.Valid {
return nil, handlers.ForbiddenError()
}
if err := validateAddGroupMembersRequest(req); err != nil {
return nil, err
}
g, err := s.addMembersInRepo(ctx, req.GetId(), req.GetMemberIds(), req.GetVersion().GetValue())
if err != nil {
return nil, err
}
return &pbs.AddGroupMembersResponse{Item: g}, nil
}
// SetGroupMembers implements the interface pbs.GroupServiceServer.
func (s Service) SetGroupMembers(ctx context.Context, req *pbs.SetGroupMembersRequest) (*pbs.SetGroupMembersResponse, error) {
authResults := auth.Verify(ctx)
if !authResults.Valid {
return nil, handlers.ForbiddenError()
}
if err := validateSetGroupMembersRequest(req); err != nil {
return nil, err
}
g, err := s.setMembersInRepo(ctx, req.GetId(), req.GetMemberIds(), req.GetVersion().GetValue())
if err != nil {
return nil, err
}
return &pbs.SetGroupMembersResponse{Item: g}, nil
}
// RemoveGroupMembers implements the interface pbs.GroupServiceServer.
func (s Service) RemoveGroupMembers(ctx context.Context, req *pbs.RemoveGroupMembersRequest) (*pbs.RemoveGroupMembersResponse, error) {
authResults := auth.Verify(ctx)
if !authResults.Valid {
return nil, handlers.ForbiddenError()
}
if err := validateRemoveGroupMembersRequest(req); err != nil {
return nil, err
}
g, err := s.removeMembersInRepo(ctx, req.GetId(), req.GetMemberIds(), req.GetVersion().GetValue())
if err != nil {
return nil, err
}
return &pbs.RemoveGroupMembersResponse{Item: g}, nil
}
func (s Service) getFromRepo(ctx context.Context, id string) (*pb.Group, error) {
repo, err := s.repoFn()
if err != nil {
return nil, err
}
u, err := repo.LookupGroup(ctx, id)
g, m, err := repo.LookupGroup(ctx, id)
if err != nil {
if errors.Is(err, db.ErrRecordNotFound) {
return nil, handlers.NotFoundErrorf("Group %q doesn't exist.", id)
}
return nil, err
}
if u == nil {
if g == nil {
return nil, handlers.NotFoundErrorf("Group %q doesn't exist.", id)
}
return toProto(u), nil
return toProto(g, m), nil
}
func (s Service) createInRepo(ctx context.Context, scopeId string, item *pb.Group) (*pb.Group, error) {
@@ -173,7 +221,7 @@ func (s Service) createInRepo(ctx context.Context, scopeId string, item *pb.Grou
if out == nil {
return nil, status.Error(codes.Internal, "Unable to create group but no error returned from repository.")
}
return toProto(out), nil
return toProto(out, nil), nil
}
func (s Service) updateInRepo(ctx context.Context, scopeId, id string, mask []string, item *pb.Group) (*pb.Group, error) {
@@ -197,14 +245,14 @@ func (s Service) updateInRepo(ctx context.Context, scopeId, id string, mask []st
if err != nil {
return nil, err
}
out, rowsUpdated, err := repo.UpdateGroup(ctx, u, dbMask)
out, m, rowsUpdated, err := repo.UpdateGroup(ctx, u, dbMask)
if err != nil {
return nil, status.Errorf(codes.Internal, "Unable to update group: %v.", err)
}
if rowsUpdated == 0 {
return nil, handlers.NotFoundErrorf("Group %q doesn't exist.", id)
}
return toProto(out), nil
return toProto(out, m), nil
}
func (s Service) deleteFromRepo(ctx context.Context, id string) (bool, error) {
@@ -233,16 +281,74 @@ func (s Service) listFromRepo(ctx context.Context, scopeId string) ([]*pb.Group,
}
var outGl []*pb.Group
for _, g := range gl {
outGl = append(outGl, toProto(g))
outGl = append(outGl, toProto(g, nil))
}
return outGl, nil
}
func toProto(in *iam.Group) *pb.Group {
func (s Service) addMembersInRepo(ctx context.Context, groupId string, userIds []string, version uint32) (*pb.Group, error) {
repo, err := s.repoFn()
if err != nil {
return nil, err
}
_, err = repo.AddGroupMembers(ctx, groupId, version, userIds)
if err != nil {
return nil, status.Errorf(codes.Internal, "Unable to add members to group: %v.", err)
}
out, m, err := repo.LookupGroup(ctx, groupId)
if err != nil {
return nil, status.Errorf(codes.Internal, "Unable to look up group: %v.", err)
}
if out == nil {
return nil, status.Error(codes.Internal, "Unable to lookup group after adding member to it.")
}
return toProto(out, m), nil
}
func (s Service) setMembersInRepo(ctx context.Context, groupId string, userIds []string, version uint32) (*pb.Group, error) {
repo, err := s.repoFn()
if err != nil {
return nil, err
}
_, _, err = repo.SetGroupMembers(ctx, groupId, version, userIds)
if err != nil {
return nil, status.Errorf(codes.Internal, "Unable to set members on group: %v.", err)
}
out, m, err := repo.LookupGroup(ctx, groupId)
if err != nil {
return nil, status.Errorf(codes.Internal, "Unable to look up group: %v.", err)
}
if out == nil {
return nil, status.Error(codes.Internal, "Unable to lookup group after setting members for it.")
}
return toProto(out, m), nil
}
func (s Service) removeMembersInRepo(ctx context.Context, groupId string, userIds []string, version uint32) (*pb.Group, error) {
repo, err := s.repoFn()
if err != nil {
return nil, err
}
_, err = repo.DeleteGroupMembers(ctx, groupId, version, userIds)
if err != nil {
return nil, status.Errorf(codes.Internal, "Unable to remove members from group: %v.", err)
}
out, m, err := repo.LookupGroup(ctx, groupId)
if err != nil {
return nil, status.Errorf(codes.Internal, "Unable to look up group: %v.", err)
}
if out == nil {
return nil, status.Error(codes.Internal, "Unable to lookup group after removing members from it.")
}
return toProto(out, m), nil
}
func toProto(in *iam.Group, members []*iam.GroupMember) *pb.Group {
out := pb.Group{
Id: in.GetPublicId(),
CreatedTime: in.GetCreateTime().GetTimestamp(),
UpdatedTime: in.GetUpdateTime().GetTimestamp(),
Version: in.Version,
}
if in.GetDescription() != "" {
out.Description = &wrapperspb.StringValue{Value: in.GetDescription()}
@@ -250,6 +356,14 @@ func toProto(in *iam.Group) *pb.Group {
if in.GetName() != "" {
out.Name = &wrapperspb.StringValue{Value: in.GetName()}
}
for _, m := range members {
out.MemberIds = append(out.MemberIds, m.GetMemberId())
out.Members = append(out.Members, &pb.Member{
Id: m.GetMemberId(),
Type: m.GetType(),
ScopeId: m.GetMemberScopeId(),
})
}
return &out
}
@@ -337,6 +451,54 @@ func validateListRequest(req *pbs.ListGroupsRequest) error {
return nil
}
func validateAddGroupMembersRequest(req *pbs.AddGroupMembersRequest) error {
badFields := map[string]string{}
if !validId(req.GetId(), iam.GroupPrefix+"_") {
badFields["id"] = "Incorrectly formatted identifier."
}
if req.GetVersion() == nil {
badFields["version"] = "Required field."
}
if len(req.GetMemberIds()) == 0 {
badFields["member_ids"] = "Must be non-empty."
}
if len(badFields) > 0 {
return handlers.InvalidArgumentErrorf("Errors in provided fields.", badFields)
}
return nil
}
func validateSetGroupMembersRequest(req *pbs.SetGroupMembersRequest) error {
badFields := map[string]string{}
if !validId(req.GetId(), iam.GroupPrefix+"_") {
badFields["id"] = "Incorrectly formatted identifier."
}
if req.GetVersion() == nil {
badFields["version"] = "Required field."
}
if len(badFields) > 0 {
return handlers.InvalidArgumentErrorf("Errors in provided fields.", badFields)
}
return nil
}
func validateRemoveGroupMembersRequest(req *pbs.RemoveGroupMembersRequest) error {
badFields := map[string]string{}
if !validId(req.GetId(), iam.GroupPrefix+"_") {
badFields["id"] = "Incorrectly formatted identifier."
}
if req.GetVersion() == nil {
badFields["version"] = "Required field."
}
if len(req.GetMemberIds()) == 0 {
badFields["member_ids"] = "Must be non-empty."
}
if len(badFields) > 0 {
return handlers.InvalidArgumentErrorf("Errors in provided fields.", badFields)
}
return nil
}
func validId(id, prefix string) bool {
if !strings.HasPrefix(id, prefix) {
return false
@@ -7,6 +7,7 @@ import (
"testing"
"github.com/golang/protobuf/ptypes"
"github.com/google/go-cmp/cmp"
"github.com/hashicorp/watchtower/internal/auth"
"github.com/hashicorp/watchtower/internal/db"
pb "github.com/hashicorp/watchtower/internal/gen/controller/api/resources/groups"
@@ -19,6 +20,7 @@ import (
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/testing/protocmp"
"google.golang.org/protobuf/types/known/wrapperspb"
"github.com/stretchr/testify/assert"
@@ -41,10 +43,47 @@ func createDefaultGroupsAndRepo(t *testing.T) (*iam.Group, *iam.Group, func() (*
return og, pg, repoFn
}
func equalMembers(g *pb.Group, members []string) bool {
if len(g.Members) != len(members) {
return false
}
for _, m := range members {
var foundInMembers bool
var foundInPrincipalIds bool
for _, v := range g.Members {
if v.Id == m {
foundInMembers = true
}
}
for _, v := range g.MemberIds {
if v == m {
foundInPrincipalIds = true
}
}
if !foundInMembers || !foundInPrincipalIds {
return false
}
}
return true
}
func TestGet(t *testing.T) {
assert := assert.New(t)
require := require.New(t)
og, pg, repo := createDefaultGroupsAndRepo(t)
conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn)
wrap := db.TestWrapper(t)
repoFn := func() (*iam.Repository, error) {
return iam.NewRepository(rw, rw, wrap)
}
o, p := iam.TestScopes(t, conn)
u := iam.TestUser(t, conn, o.GetPublicId())
og := iam.TestGroup(t, conn, o.GetPublicId(), iam.WithDescription("default"), iam.WithName("default"))
_ = iam.TestGroupMember(t, conn, og.GetPublicId(), u.GetPublicId())
pg := iam.TestGroup(t, conn, p.GetPublicId(), iam.WithDescription("default"), iam.WithName("default"))
_ = iam.TestGroupMember(t, conn, pg.GetPublicId(), u.GetPublicId())
toMerge := &pbs.GetGroupRequest{
Id: og.GetPublicId(),
}
@@ -56,6 +95,15 @@ func TestGet(t *testing.T) {
Description: &wrapperspb.StringValue{Value: og.GetDescription()},
CreatedTime: og.CreateTime.GetTimestamp(),
UpdatedTime: og.UpdateTime.GetTimestamp(),
Version: 1,
MemberIds: []string{u.GetPublicId()},
Members: []*pb.Member{
{
Id: u.GetPublicId(),
Type: iam.UserMemberType.String(),
ScopeId: u.GetScopeId(),
},
},
}
wantProjGroup := &pb.Group{
@@ -65,6 +113,15 @@ func TestGet(t *testing.T) {
Description: &wrapperspb.StringValue{Value: pg.GetDescription()},
CreatedTime: pg.CreateTime.GetTimestamp(),
UpdatedTime: pg.UpdateTime.GetTimestamp(),
Version: 1,
MemberIds: []string{u.GetPublicId()},
Members: []*pb.Member{
{
Id: u.GetPublicId(),
Type: iam.UserMemberType.String(),
ScopeId: u.GetScopeId(),
},
},
}
cases := []struct {
@@ -130,15 +187,16 @@ func TestGet(t *testing.T) {
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
req := proto.Clone(toMerge).(*pbs.GetGroupRequest)
proto.Merge(req, tc.req)
s, err := groups.NewService(repo)
s, err := groups.NewService(repoFn)
require.NoError(err, "Couldn't create new group service.")
got, gErr := s.GetGroup(auth.DisabledAuthTestContext(auth.WithScopeId(tc.scopeId)), req)
assert.Equal(tc.errCode, status.Code(gErr), "GetGroup(%+v) got error %v, wanted %v", req, gErr, tc.errCode)
assert.True(proto.Equal(got, tc.res), "GetGroup(%q) got response\n%q, wanted\n%q", req, got, tc.res)
assert.Empty(cmp.Diff(got, tc.res, protocmp.Transform()), "GetGroup(%q) got response\n%q, wanted\n%q", req, got, tc.res)
})
}
}
@@ -161,6 +219,7 @@ func TestList(t *testing.T) {
Scope: &scopes.ScopeInfo{Id: oWithGroups.GetPublicId(), Type: scope.Org.String()},
CreatedTime: og.GetCreateTime().GetTimestamp(),
UpdatedTime: og.GetUpdateTime().GetTimestamp(),
Version: 1,
})
pg := iam.TestGroup(t, conn, pWithGroups.GetPublicId())
wantProjGroups = append(wantProjGroups, &pb.Group{
@@ -168,6 +227,7 @@ func TestList(t *testing.T) {
Scope: &scopes.ScopeInfo{Id: pWithGroups.GetPublicId(), Type: scope.Project.String()},
CreatedTime: pg.GetCreateTime().GetTimestamp(),
UpdatedTime: pg.GetUpdateTime().GetTimestamp(),
Version: 1,
})
}
@@ -374,6 +434,7 @@ func TestCreate(t *testing.T) {
Scope: &scopes.ScopeInfo{Id: defaultOGroup.GetScopeId(), Type: scope.Org.String()},
Name: &wrapperspb.StringValue{Value: "name"},
Description: &wrapperspb.StringValue{Value: "desc"},
Version: 1,
},
},
errCode: codes.OK,
@@ -393,6 +454,7 @@ func TestCreate(t *testing.T) {
Scope: &scopes.ScopeInfo{Id: defaultPGroup.GetScopeId(), Type: scope.Project.String()},
Name: &wrapperspb.StringValue{Value: "name"},
Description: &wrapperspb.StringValue{Value: "desc"},
Version: 1,
},
},
errCode: codes.OK,
@@ -449,23 +511,35 @@ func TestCreate(t *testing.T) {
got.Item.Id, tc.res.Item.Id = "", ""
got.Item.CreatedTime, got.Item.UpdatedTime, tc.res.Item.CreatedTime, tc.res.Item.UpdatedTime = nil, nil, nil, nil
}
assert.True(proto.Equal(got, tc.res), "CreateGroup(%q) got response %q, wanted %q", req, got, tc.res)
assert.Empty(cmp.Diff(got, tc.res, protocmp.Transform()), "CreateGroup(%q) got response %q, wanted %q", req, got, tc.res)
})
}
}
func TestUpdate(t *testing.T) {
require := require.New(t)
og, pg, repoFn := createDefaultGroupsAndRepo(t)
tested, err := groups.NewService(repoFn)
require.NoError(err, "Error when getting new group service.")
conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn)
wrap := db.TestWrapper(t)
repoFn := func() (*iam.Repository, error) {
return iam.NewRepository(rw, rw, wrap)
}
o, p := iam.TestScopes(t, conn)
u := iam.TestUser(t, conn, o.GetPublicId())
og := iam.TestGroup(t, conn, o.GetPublicId(), iam.WithDescription("default"), iam.WithName("default"))
_ = iam.TestGroupMember(t, conn, og.GetPublicId(), u.GetPublicId())
pg := iam.TestGroup(t, conn, p.GetPublicId(), iam.WithDescription("default"), iam.WithName("default"))
_ = iam.TestGroupMember(t, conn, pg.GetPublicId(), u.GetPublicId())
resetGroups := func() {
repo, err := repoFn()
require.NoError(err, "Couldn't get a new repo")
og, _, err = repo.UpdateGroup(context.Background(), og, []string{"Name", "Description"})
og, _, _, err = repo.UpdateGroup(context.Background(), og, []string{"Name", "Description"})
require.NoError(err, "Failed to reset the group")
pg, _, err = repo.UpdateGroup(context.Background(), pg, []string{"Name", "Description"})
pg, _, _, err = repo.UpdateGroup(context.Background(), pg, []string{"Name", "Description"})
require.NoError(err, "Failed to reset the group")
}
@@ -475,6 +549,7 @@ func TestUpdate(t *testing.T) {
Id: og.GetPublicId(),
}
tested, err := groups.NewService(repoFn)
cases := []struct {
name string
scopeId string
@@ -483,31 +558,39 @@ func TestUpdate(t *testing.T) {
errCode codes.Code
}{
{
scopeId: og.GetScopeId(),
name: "Update an Existing Group",
req: &pbs.UpdateGroupRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"name", "description"},
},
Item: &pb.Group{
Name: &wrapperspb.StringValue{Value: "new"},
Description: &wrapperspb.StringValue{Value: "desc"},
},
},
res: &pbs.UpdateGroupResponse{
Item: &pb.Group{
Id: og.GetPublicId(),
Scope: &scopes.ScopeInfo{Id: og.GetScopeId(), Type: scope.Org.String()},
Name: &wrapperspb.StringValue{Value: "new"},
Description: &wrapperspb.StringValue{Value: "desc"},
CreatedTime: og.GetCreateTime().GetTimestamp(),
},
},
errCode: codes.OK,
},
{
scopeId: og.GetScopeId(),
req: &pbs.UpdateGroupRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"name", "description"},
},
Item: &pb.Group{
Name: &wrapperspb.StringValue{Value: "new"},
Description: &wrapperspb.StringValue{Value: "desc"},
},
},
res: &pbs.UpdateGroupResponse{
Item: &pb.Group{
Id: og.GetPublicId(),
Scope: &scopes.ScopeInfo{Id: og.GetScopeId(), Type: scope.Org.String()},
Name: &wrapperspb.StringValue{Value: "new"},
Description: &wrapperspb.StringValue{Value: "desc"},
CreatedTime: og.GetCreateTime().GetTimestamp(),
MemberIds: []string{u.GetPublicId()},
Members: []*pb.Member{
{
Id: u.GetPublicId(),
Type: iam.UserMemberType.String(),
ScopeId: u.GetScopeId(),
},
},
},
},
errCode: codes.OK,
},
{
name: "Multiple Paths in single string",
scopeId: og.GetScopeId(),
req: &pbs.UpdateGroupRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"name,description"},
@@ -524,13 +607,21 @@ func TestUpdate(t *testing.T) {
Name: &wrapperspb.StringValue{Value: "new"},
Description: &wrapperspb.StringValue{Value: "desc"},
CreatedTime: og.GetCreateTime().GetTimestamp(),
MemberIds: []string{u.GetPublicId()},
Members: []*pb.Member{
{
Id: u.GetPublicId(),
Type: iam.UserMemberType.String(),
ScopeId: u.GetScopeId(),
},
},
},
},
errCode: codes.OK,
},
{
scopeId: pg.GetScopeId(),
name: "Update an Existing Project Scoped Group",
scopeId: pg.GetScopeId(),
req: &pbs.UpdateGroupRequest{
Id: pg.GetPublicId(),
UpdateMask: &field_mask.FieldMask{
@@ -548,13 +639,21 @@ func TestUpdate(t *testing.T) {
Name: &wrapperspb.StringValue{Value: "new"},
Description: &wrapperspb.StringValue{Value: "desc"},
CreatedTime: pg.GetCreateTime().GetTimestamp(),
MemberIds: []string{u.GetPublicId()},
Members: []*pb.Member{
{
Id: u.GetPublicId(),
Type: iam.UserMemberType.String(),
ScopeId: u.GetScopeId(),
},
},
},
},
errCode: codes.OK,
},
{
scopeId: pg.GetScopeId(),
name: "Multiple Paths in single string",
scopeId: pg.GetScopeId(),
req: &pbs.UpdateGroupRequest{
Id: pg.GetPublicId(),
UpdateMask: &field_mask.FieldMask{
@@ -572,6 +671,14 @@ func TestUpdate(t *testing.T) {
Name: &wrapperspb.StringValue{Value: "new"},
Description: &wrapperspb.StringValue{Value: "desc"},
CreatedTime: pg.GetCreateTime().GetTimestamp(),
MemberIds: []string{u.GetPublicId()},
Members: []*pb.Member{
{
Id: u.GetPublicId(),
Type: iam.UserMemberType.String(),
ScopeId: u.GetScopeId(),
},
},
},
},
errCode: codes.OK,
@@ -627,13 +734,21 @@ func TestUpdate(t *testing.T) {
Scope: &scopes.ScopeInfo{Id: og.GetScopeId(), Type: scope.Org.String()},
Description: &wrapperspb.StringValue{Value: "default"},
CreatedTime: og.GetCreateTime().GetTimestamp(),
MemberIds: []string{u.GetPublicId()},
Members: []*pb.Member{
{
Id: u.GetPublicId(),
Type: iam.UserMemberType.String(),
ScopeId: u.GetScopeId(),
},
},
},
},
errCode: codes.OK,
},
{
scopeId: og.GetScopeId(),
name: "Update Only Name",
scopeId: og.GetScopeId(),
req: &pbs.UpdateGroupRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"name"},
@@ -650,13 +765,21 @@ func TestUpdate(t *testing.T) {
Name: &wrapperspb.StringValue{Value: "updated"},
Description: &wrapperspb.StringValue{Value: "default"},
CreatedTime: og.GetCreateTime().GetTimestamp(),
MemberIds: []string{u.GetPublicId()},
Members: []*pb.Member{
{
Id: u.GetPublicId(),
Type: iam.UserMemberType.String(),
ScopeId: u.GetScopeId(),
},
},
},
},
errCode: codes.OK,
},
{
scopeId: og.GetScopeId(),
name: "Update Only Description",
scopeId: og.GetScopeId(),
req: &pbs.UpdateGroupRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"description"},
@@ -673,6 +796,14 @@ func TestUpdate(t *testing.T) {
Name: &wrapperspb.StringValue{Value: "default"},
Description: &wrapperspb.StringValue{Value: "notignored"},
CreatedTime: og.GetCreateTime().GetTimestamp(),
MemberIds: []string{u.GetPublicId()},
Members: []*pb.Member{
{
Id: u.GetPublicId(),
Type: iam.UserMemberType.String(),
ScopeId: u.GetScopeId(),
},
},
},
},
errCode: codes.OK,
@@ -754,8 +885,320 @@ func TestUpdate(t *testing.T) {
// Clear all values which are hard to compare against.
got.Item.UpdatedTime, tc.res.Item.UpdatedTime = nil, nil
// TODO: Figure out the best way to test version updates.
got.Item.Version = 0
}
assert.True(proto.Equal(got, tc.res), "UpdateGroup(%q) got response %q, wanted %q", req, got, tc.res)
assert.Empty(cmp.Diff(got, tc.res, protocmp.Transform()), "UpdateGroup(%q) got response %q, wanted %q", req, got, tc.res)
})
}
}
func TestAddMember(t *testing.T) {
conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn)
wrap := db.TestWrapper(t)
repoFn := func() (*iam.Repository, error) {
return iam.NewRepository(rw, rw, wrap)
}
s, err := groups.NewService(repoFn)
require.NoError(t, err, "Error when getting new group service.")
o, p := iam.TestScopes(t, conn)
users := []*iam.User{
iam.TestUser(t, conn, o.GetPublicId()),
iam.TestUser(t, conn, o.GetPublicId()),
iam.TestUser(t, conn, o.GetPublicId()),
}
addCases := []struct {
name string
setup func(*iam.Group)
addUsers []string
addGroups []string
resultUsers []string
resultGroups []string
wantErr bool
}{
{
name: "Add user on empty group",
setup: func(g *iam.Group) {},
addUsers: []string{users[1].GetPublicId()},
resultUsers: []string{users[1].GetPublicId()},
},
{
name: "Add user on populated group",
setup: func(g *iam.Group) {
iam.TestGroupMember(t, conn, g.GetPublicId(), users[0].GetPublicId())
},
addUsers: []string{users[1].GetPublicId()},
resultUsers: []string{users[0].GetPublicId(), users[1].GetPublicId()},
},
{
name: "Add empty on populated group",
setup: func(g *iam.Group) {
iam.TestGroupMember(t, conn, g.GetPublicId(), users[0].GetPublicId())
iam.TestGroupMember(t, conn, g.GetPublicId(), users[1].GetPublicId())
},
wantErr: true,
},
}
for _, tc := range addCases {
for _, scp := range []*iam.Scope{o, p} {
t.Run(tc.name+"_"+scp.GetType(), func(t *testing.T) {
grp := iam.TestGroup(t, conn, scp.GetPublicId())
tc.setup(grp)
req := &pbs.AddGroupMembersRequest{
Id: grp.GetPublicId(),
Version: &wrapperspb.UInt32Value{Value: grp.GetVersion()},
MemberIds: tc.addUsers,
}
got, err := s.AddGroupMembers(auth.DisabledAuthTestContext(auth.WithScopeId(scp.GetPublicId())), req)
if tc.wantErr {
assert.Error(t, err)
return
}
s, ok := status.FromError(err)
require.True(t, ok)
require.NoError(t, err, "Got error: %v", s)
assert.True(t, equalMembers(got.GetItem(), tc.resultUsers))
})
}
}
grp := iam.TestGroup(t, conn, p.GetPublicId())
failCases := []struct {
name string
req *pbs.AddGroupMembersRequest
errCode codes.Code
}{
{
name: "Bad Group Id",
req: &pbs.AddGroupMembersRequest{
Id: "bad id",
Version: &wrapperspb.UInt32Value{Value: grp.GetVersion()},
},
errCode: codes.InvalidArgument,
},
}
for _, tc := range failCases {
t.Run(tc.name, func(t *testing.T) {
assert := assert.New(t)
_, gErr := s.AddGroupMembers(auth.DisabledAuthTestContext(auth.WithScopeId(grp.GetScopeId())), tc.req)
assert.Equal(tc.errCode, status.Code(gErr), "AddGroupMembers(%+v) got error %v, wanted %v", tc.req, gErr, tc.errCode)
})
}
}
func TestSetMember(t *testing.T) {
conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn)
wrap := db.TestWrapper(t)
repoFn := func() (*iam.Repository, error) {
return iam.NewRepository(rw, rw, wrap)
}
s, err := groups.NewService(repoFn)
require.NoError(t, err, "Error when getting new group service.")
o, p := iam.TestScopes(t, conn)
users := []*iam.User{
iam.TestUser(t, conn, o.GetPublicId()),
iam.TestUser(t, conn, o.GetPublicId()),
iam.TestUser(t, conn, o.GetPublicId()),
}
setCases := []struct {
name string
setup func(*iam.Group)
setUsers []string
setGroups []string
resultUsers []string
resultGroups []string
wantErr bool
}{
{
name: "Set user on empty group",
setup: func(r *iam.Group) {},
setUsers: []string{users[1].GetPublicId()},
resultUsers: []string{users[1].GetPublicId()},
},
{
name: "Set user on populated group",
setup: func(r *iam.Group) {
iam.TestGroupMember(t, conn, r.GetPublicId(), users[0].GetPublicId())
},
setUsers: []string{users[1].GetPublicId()},
resultUsers: []string{users[1].GetPublicId()},
},
{
name: "Set empty on populated group",
setup: func(r *iam.Group) {
iam.TestGroupMember(t, conn, r.GetPublicId(), users[0].GetPublicId())
iam.TestGroupMember(t, conn, r.GetPublicId(), users[1].GetPublicId())
},
setUsers: []string{},
resultUsers: nil,
},
}
for _, tc := range setCases {
for _, scp := range []*iam.Scope{o, p} {
t.Run(tc.name+"_"+scp.GetType(), func(t *testing.T) {
grp := iam.TestGroup(t, conn, scp.GetPublicId())
tc.setup(grp)
req := &pbs.SetGroupMembersRequest{
Id: grp.GetPublicId(),
Version: &wrapperspb.UInt32Value{Value: grp.GetVersion()},
MemberIds: tc.setUsers,
}
got, err := s.SetGroupMembers(auth.DisabledAuthTestContext(auth.WithScopeId(scp.GetPublicId())), req)
if tc.wantErr {
assert.Error(t, err)
return
}
s, ok := status.FromError(err)
require.True(t, ok)
require.NoError(t, err, "Got error: %v", s)
assert.True(t, equalMembers(got.GetItem(), append(tc.resultUsers, tc.resultGroups...)))
})
}
}
grp := iam.TestGroup(t, conn, p.GetPublicId())
failCases := []struct {
name string
req *pbs.SetGroupMembersRequest
errCode codes.Code
}{
{
name: "Bad Group Id",
req: &pbs.SetGroupMembersRequest{
Id: "bad id",
Version: &wrapperspb.UInt32Value{Value: grp.GetVersion()},
},
errCode: codes.InvalidArgument,
},
}
for _, tc := range failCases {
t.Run(tc.name, func(t *testing.T) {
assert := assert.New(t)
_, gErr := s.SetGroupMembers(auth.DisabledAuthTestContext(auth.WithScopeId(grp.GetScopeId())), tc.req)
assert.Equal(tc.errCode, status.Code(gErr), "SetGroupMembers(%+v) got error %v, wanted %v", tc.req, gErr, tc.errCode)
})
}
}
func TestRemoveMember(t *testing.T) {
conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn)
wrap := db.TestWrapper(t)
repoFn := func() (*iam.Repository, error) {
return iam.NewRepository(rw, rw, wrap)
}
s, err := groups.NewService(repoFn)
require.NoError(t, err, "Error when getting new grp service.")
o, p := iam.TestScopes(t, conn)
users := []*iam.User{
iam.TestUser(t, conn, o.GetPublicId()),
iam.TestUser(t, conn, o.GetPublicId()),
iam.TestUser(t, conn, o.GetPublicId()),
}
addCases := []struct {
name string
setup func(*iam.Group)
removeUsers []string
removeGroups []string
resultUsers []string
resultGroups []string
wantErr bool
}{
{
name: "Remove user on empty group",
setup: func(r *iam.Group) {},
removeUsers: []string{users[1].GetPublicId()},
wantErr: true,
},
{
name: "Remove 1 of 2 users from group",
setup: func(r *iam.Group) {
iam.TestGroupMember(t, conn, r.GetPublicId(), users[0].GetPublicId())
iam.TestGroupMember(t, conn, r.GetPublicId(), users[1].GetPublicId())
},
removeUsers: []string{users[1].GetPublicId()},
resultUsers: []string{users[0].GetPublicId()},
},
{
name: "Remove all users from group",
setup: func(r *iam.Group) {
iam.TestGroupMember(t, conn, r.GetPublicId(), users[0].GetPublicId())
iam.TestGroupMember(t, conn, r.GetPublicId(), users[1].GetPublicId())
},
removeUsers: []string{users[0].GetPublicId(), users[1].GetPublicId()},
resultUsers: []string{},
},
{
name: "Remove empty on populated group",
setup: func(r *iam.Group) {
iam.TestGroupMember(t, conn, r.GetPublicId(), users[0].GetPublicId())
},
wantErr: true,
},
}
for _, tc := range addCases {
for _, scp := range []*iam.Scope{o, p} {
t.Run(tc.name+"_"+scp.GetType(), func(t *testing.T) {
grp := iam.TestGroup(t, conn, scp.GetPublicId())
tc.setup(grp)
req := &pbs.RemoveGroupMembersRequest{
Id: grp.GetPublicId(),
Version: &wrapperspb.UInt32Value{Value: grp.GetVersion()},
MemberIds: tc.removeUsers,
}
got, err := s.RemoveGroupMembers(auth.DisabledAuthTestContext(auth.WithScopeId(scp.GetPublicId())), req)
if tc.wantErr {
assert.Error(t, err)
return
}
s, ok := status.FromError(err)
require.True(t, ok)
require.NoError(t, err, "Got error: %v", s)
assert.True(t, equalMembers(got.GetItem(), tc.resultUsers))
})
}
}
grp := iam.TestGroup(t, conn, p.GetPublicId())
failCases := []struct {
name string
req *pbs.AddGroupMembersRequest
errCode codes.Code
}{
{
name: "Bad Group Id",
req: &pbs.AddGroupMembersRequest{
Id: "bad id",
Version: &wrapperspb.UInt32Value{Value: grp.GetVersion()},
},
errCode: codes.InvalidArgument,
},
}
for _, tc := range failCases {
t.Run(tc.name, func(t *testing.T) {
assert := assert.New(t)
_, gErr := s.AddGroupMembers(auth.DisabledAuthTestContext(auth.WithScopeId(grp.GetScopeId())), tc.req)
assert.Equal(tc.errCode, status.Code(gErr), "AddGroupMembers(%+v) got error %v, wanted %v", tc.req, gErr, tc.errCode)
})
}
}
@@ -358,14 +358,14 @@ func (s Service) addPrinciplesInRepo(ctx context.Context, roleId string, princip
}
_, err = repo.AddPrincipalRoles(ctx, roleId, version, principalIds)
if err != nil {
return nil, status.Errorf(codes.Internal, "Unable to add principles to role: %v.", err)
return nil, status.Errorf(codes.Internal, "Unable to add principals to role: %v.", err)
}
out, pr, roleGrants, err := repo.LookupRole(ctx, roleId)
if err != nil {
return nil, status.Errorf(codes.Internal, "Unable to look up role: %v.", err)
}
if out == nil {
return nil, status.Error(codes.Internal, "Unable to lookup role after adding principles to it.")
return nil, status.Error(codes.Internal, "Unable to lookup role after adding principals to it.")
}
return toProto(out, pr, roleGrants), nil
}
@@ -377,14 +377,14 @@ func (s Service) setPrinciplesInRepo(ctx context.Context, roleId string, princip
}
_, _, err = repo.SetPrincipalRoles(ctx, roleId, version, principalIds)
if err != nil {
return nil, status.Errorf(codes.Internal, "Unable to set principles on role: %v.", err)
return nil, status.Errorf(codes.Internal, "Unable to set principals on role: %v.", err)
}
out, pr, roleGrants, err := repo.LookupRole(ctx, roleId)
if err != nil {
return nil, status.Errorf(codes.Internal, "Unable to look up role: %v.", err)
}
if out == nil {
return nil, status.Error(codes.Internal, "Unable to lookup role after setting principles for it.")
return nil, status.Error(codes.Internal, "Unable to lookup role after setting principals for it.")
}
return toProto(out, pr, roleGrants), nil
}
@@ -396,14 +396,14 @@ func (s Service) removePrinciplesInRepo(ctx context.Context, roleId string, prin
}
_, err = repo.DeletePrincipalRoles(ctx, roleId, version, principalIds)
if err != nil {
return nil, status.Errorf(codes.Internal, "Unable to remove principles from role: %v.", err)
return nil, status.Errorf(codes.Internal, "Unable to remove principals from role: %v.", err)
}
out, pr, roleGrants, err := repo.LookupRole(ctx, roleId)
if err != nil {
return nil, status.Errorf(codes.Internal, "Unable to look up role: %v.", err)
}
if out == nil {
return nil, status.Error(codes.Internal, "Unable to lookup role after removing principles from it.")
return nil, status.Error(codes.Internal, "Unable to lookup role after removing principals from it.")
}
return toProto(out, pr, roleGrants), nil
}
+9
View File
@@ -22,6 +22,9 @@ const (
SetPrincipals Type = 13
RemovePrincipals Type = 14
Deauthenticate Type = 15
AddMembers Type = 16
SetMembers Type = 17
RemoveMembers Type = 18
)
var Map = map[string]Type{
@@ -40,6 +43,9 @@ var Map = map[string]Type{
SetPrincipals.String(): SetPrincipals,
RemovePrincipals.String(): RemovePrincipals,
Deauthenticate.String(): Deauthenticate,
AddMembers.String(): AddMembers,
SetMembers.String(): SetMembers,
RemoveMembers.String(): RemoveMembers,
}
func (a Type) String() string {
@@ -60,5 +66,8 @@ func (a Type) String() string {
"set-principals",
"remove-principals",
"deauthenticate",
"add-members",
"set-members",
"remove-members",
}[a]
}