-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
Copy pathGroupsController.cs
192 lines (181 loc) · 7.91 KB
/
GroupsController.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
using System.Net;
using Bit.Api.AdminConsole.Public.Models.Request;
using Bit.Api.AdminConsole.Public.Models.Response;
using Bit.Api.Models.Public.Response;
using Bit.Core.AdminConsole.OrganizationFeatures.Groups.Interfaces;
using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Context;
using Bit.Core.Repositories;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Bit.Api.AdminConsole.Public.Controllers;
[Route("public/groups")]
[Authorize("Organization")]
public class GroupsController : Controller
{
private readonly IGroupRepository _groupRepository;
private readonly IOrganizationRepository _organizationRepository;
private readonly ICurrentContext _currentContext;
private readonly ICreateGroupCommand _createGroupCommand;
private readonly IUpdateGroupCommand _updateGroupCommand;
public GroupsController(
IGroupRepository groupRepository,
IOrganizationRepository organizationRepository,
ICurrentContext currentContext,
ICreateGroupCommand createGroupCommand,
IUpdateGroupCommand updateGroupCommand)
{
_groupRepository = groupRepository;
_organizationRepository = organizationRepository;
_currentContext = currentContext;
_createGroupCommand = createGroupCommand;
_updateGroupCommand = updateGroupCommand;
}
/// <summary>
/// Retrieve a group.
/// </summary>
/// <remarks>
/// Retrieves the details of an existing group. You need only supply the unique group identifier
/// that was returned upon group creation.
/// </remarks>
/// <param name="id">The identifier of the group to be retrieved.</param>
[HttpGet("{id}")]
[ProducesResponseType(typeof(GroupResponseModel), (int)HttpStatusCode.OK)]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task<IActionResult> Get(Guid id)
{
var groupDetails = await _groupRepository.GetByIdWithCollectionsAsync(id);
var group = groupDetails?.Item1;
if (group == null || group.OrganizationId != _currentContext.OrganizationId)
{
return new NotFoundResult();
}
var response = new GroupResponseModel(group, groupDetails.Item2);
return new JsonResult(response);
}
/// <summary>
/// Retrieve a groups's member ids
/// </summary>
/// <remarks>
/// Retrieves the unique identifiers for all members that are associated with this group. You need only
/// supply the unique group identifier that was returned upon group creation.
/// </remarks>
/// <param name="id">The identifier of the group to be retrieved.</param>
[HttpGet("{id}/member-ids")]
[ProducesResponseType(typeof(HashSet<Guid>), (int)HttpStatusCode.OK)]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task<IActionResult> GetMemberIds(Guid id)
{
var group = await _groupRepository.GetByIdAsync(id);
if (group == null || group.OrganizationId != _currentContext.OrganizationId)
{
return new NotFoundResult();
}
var orgUserIds = await _groupRepository.GetManyUserIdsByIdAsync(id);
return new JsonResult(orgUserIds);
}
/// <summary>
/// List all groups.
/// </summary>
/// <remarks>
/// Returns a list of your organization's groups.
/// Group objects listed in this call include information about their associated collections.
/// </remarks>
[HttpGet]
[ProducesResponseType(typeof(ListResponseModel<GroupResponseModel>), (int)HttpStatusCode.OK)]
public async Task<IActionResult> List()
{
var groups = await _groupRepository.GetManyWithCollectionsByOrganizationIdAsync(_currentContext.OrganizationId.Value);
var groupResponses = groups.Select(g => new GroupResponseModel(g.Item1, g.Item2));
var response = new ListResponseModel<GroupResponseModel>(groupResponses);
return new JsonResult(response);
}
/// <summary>
/// Create a group.
/// </summary>
/// <remarks>
/// Creates a new group object.
/// </remarks>
/// <param name="model">The request model.</param>
[HttpPost]
[ProducesResponseType(typeof(GroupResponseModel), (int)HttpStatusCode.OK)]
[ProducesResponseType(typeof(ErrorResponseModel), (int)HttpStatusCode.BadRequest)]
public async Task<IActionResult> Post([FromBody] GroupCreateUpdateRequestModel model)
{
var group = model.ToGroup(_currentContext.OrganizationId.Value);
var organization = await _organizationRepository.GetByIdAsync(_currentContext.OrganizationId.Value);
var associations = model.Collections?.Select(c => c.ToCollectionAccessSelection()).ToList();
await _createGroupCommand.CreateGroupAsync(group, organization, associations);
var response = new GroupResponseModel(group, associations);
return new JsonResult(response);
}
/// <summary>
/// Update a group.
/// </summary>
/// <remarks>
/// Updates the specified group object. If a property is not provided,
/// the value of the existing property will be reset.
/// </remarks>
/// <param name="id">The identifier of the group to be updated.</param>
/// <param name="model">The request model.</param>
[HttpPut("{id}")]
[ProducesResponseType(typeof(GroupResponseModel), (int)HttpStatusCode.OK)]
[ProducesResponseType(typeof(ErrorResponseModel), (int)HttpStatusCode.BadRequest)]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task<IActionResult> Put(Guid id, [FromBody] GroupCreateUpdateRequestModel model)
{
var existingGroup = await _groupRepository.GetByIdAsync(id);
if (existingGroup == null || existingGroup.OrganizationId != _currentContext.OrganizationId)
{
return new NotFoundResult();
}
var updatedGroup = model.ToGroup(existingGroup);
var organization = await _organizationRepository.GetByIdAsync(_currentContext.OrganizationId.Value);
var associations = model.Collections?.Select(c => c.ToCollectionAccessSelection()).ToList();
await _updateGroupCommand.UpdateGroupAsync(updatedGroup, organization, associations);
var response = new GroupResponseModel(updatedGroup, associations);
return new JsonResult(response);
}
/// <summary>
/// Update a group's members.
/// </summary>
/// <remarks>
/// Updates the specified group's member associations.
/// </remarks>
/// <param name="id">The identifier of the group to be updated.</param>
/// <param name="model">The request model.</param>
[HttpPut("{id}/member-ids")]
[ProducesResponseType((int)HttpStatusCode.OK)]
[ProducesResponseType(typeof(ErrorResponseModel), (int)HttpStatusCode.BadRequest)]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task<IActionResult> PutMemberIds(Guid id, [FromBody] UpdateMemberIdsRequestModel model)
{
var existingGroup = await _groupRepository.GetByIdAsync(id);
if (existingGroup == null || existingGroup.OrganizationId != _currentContext.OrganizationId)
{
return new NotFoundResult();
}
await _groupRepository.UpdateUsersAsync(existingGroup.Id, model.MemberIds);
return new OkResult();
}
/// <summary>
/// Delete a group.
/// </summary>
/// <remarks>
/// Permanently deletes a group. This cannot be undone.
/// </remarks>
/// <param name="id">The identifier of the group to be deleted.</param>
[HttpDelete("{id}")]
[ProducesResponseType((int)HttpStatusCode.OK)]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task<IActionResult> Delete(Guid id)
{
var group = await _groupRepository.GetByIdAsync(id);
if (group == null || group.OrganizationId != _currentContext.OrganizationId)
{
return new NotFoundResult();
}
await _groupRepository.DeleteAsync(group);
return new OkResult();
}
}