1
0
mirror of https://github.com/bitwarden/server.git synced 2025-05-20 11:04:31 -05:00

manager group user apis

This commit is contained in:
Kyle Spearrin 2018-10-18 08:38:22 -04:00
parent 33bfd12b7d
commit 45a77c8903
13 changed files with 102 additions and 106 deletions

View File

@ -96,12 +96,12 @@ namespace Bit.Api.Controllers
}
[HttpGet("{id}/users")]
public async Task<ListResponseModel<SelectionReadOnlyResponseModel>> GetUsers(string orgId, string id)
public async Task<IEnumerable<SelectionReadOnlyResponseModel>> GetUsers(string orgId, string id)
{
var collection = await GetCollectionAsync(new Guid(id), new Guid(orgId));
var collectionUsers = await _collectionRepository.GetManyUsersByIdAsync(collection.Id);
var responses = collectionUsers.Select(cu => new SelectionReadOnlyResponseModel(cu));
return new ListResponseModel<SelectionReadOnlyResponseModel>(responses);
return responses;
}
[HttpPost("")]

View File

@ -8,6 +8,7 @@ using Bit.Core.Models.Api;
using Bit.Core.Exceptions;
using Bit.Core.Services;
using Bit.Core;
using System.Collections.Generic;
namespace Bit.Api.Controllers
{
@ -68,7 +69,7 @@ namespace Bit.Api.Controllers
}
[HttpGet("{id}/users")]
public async Task<ListResponseModel<GroupUserResponseModel>> GetUsers(string orgId, string id)
public async Task<IEnumerable<Guid>> GetUsers(string orgId, string id)
{
var idGuid = new Guid(id);
var group = await _groupRepository.GetByIdAsync(idGuid);
@ -77,9 +78,8 @@ namespace Bit.Api.Controllers
throw new NotFoundException();
}
var groups = await _groupRepository.GetManyUserDetailsByIdAsync(idGuid);
var responses = groups.Select(g => new GroupUserResponseModel(g));
return new ListResponseModel<GroupUserResponseModel>(responses);
var groupIds = await _groupRepository.GetManyUserIdsByIdAsync(idGuid);
return groupIds;
}
[HttpPost("")]
@ -110,6 +110,17 @@ namespace Bit.Api.Controllers
return new GroupResponseModel(group);
}
[HttpPut("{id}/users")]
public async Task PutUsers(string orgId, string id, [FromBody]IEnumerable<Guid> model)
{
var group = await _groupRepository.GetByIdAsync(new Guid(id));
if(group == null || !_currentContext.OrganizationAdmin(group.OrganizationId))
{
throw new NotFoundException();
}
await _groupRepository.UpdateUsersAsync(group.Id, model);
}
[HttpDelete("{id}")]
[HttpPost("{id}/delete")]
public async Task Delete(string orgId, string id)

View File

@ -1,32 +0,0 @@
using System;
using Bit.Core.Models.Data;
using Bit.Core.Enums;
namespace Bit.Core.Models.Api
{
public class GroupUserResponseModel : ResponseModel
{
public GroupUserResponseModel(GroupUserDetails groupUser)
: base("groupUser")
{
if(groupUser == null)
{
throw new ArgumentNullException(nameof(groupUser));
}
OrganizationUserId = groupUser.OrganizationUserId.ToString();
AccessAll = groupUser.AccessAll;
Name = groupUser.Name;
Email = groupUser.Email;
Type = groupUser.Type;
Status = groupUser.Status;
}
public string OrganizationUserId { get; set; }
public bool AccessAll { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public OrganizationUserType Type { get; set; }
public OrganizationUserStatusType Status { get; set; }
}
}

View File

@ -3,10 +3,9 @@ using Bit.Core.Models.Data;
namespace Bit.Core.Models.Api
{
public class SelectionReadOnlyResponseModel : ResponseModel
public class SelectionReadOnlyResponseModel
{
public SelectionReadOnlyResponseModel(SelectionReadOnly selection)
: base("selection")
{
if(selection == null)
{

View File

@ -1,14 +0,0 @@
using System;
namespace Bit.Core.Models.Data
{
public class GroupUserDetails
{
public Guid OrganizationUserId { get; set; }
public bool AccessAll { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public Enums.OrganizationUserStatusType Status { get; set; }
public Enums.OrganizationUserType Type { get; set; }
}
}

View File

@ -10,8 +10,8 @@ namespace Bit.Core.Repositories
{
Task<Tuple<Group, ICollection<SelectionReadOnly>>> GetByIdWithCollectionsAsync(Guid id);
Task<ICollection<Group>> GetManyByOrganizationIdAsync(Guid organizationId);
Task<ICollection<GroupUserDetails>> GetManyUserDetailsByIdAsync(Guid id);
Task<ICollection<Guid>> GetManyIdsByUserIdAsync(Guid organizationUserId);
Task<ICollection<Guid>> GetManyUserIdsByIdAsync(Guid id);
Task<ICollection<GroupUser>> GetManyGroupUsersByOrganizationIdAsync(Guid organizationId);
Task CreateAsync(Group obj, IEnumerable<SelectionReadOnly> collections);
Task ReplaceAsync(Group obj, IEnumerable<SelectionReadOnly> collections);

View File

@ -168,7 +168,7 @@ namespace Bit.Core.Repositories.SqlServer
{
var results = await connection.ExecuteAsync(
$"[{Schema}].[CollectionUser_UpdateUsers]",
new { Id = id, Users = users.ToArrayTVP() },
new { CollectionId = id, Users = users.ToArrayTVP() },
commandType: CommandType.StoredProcedure);
}
}

View File

@ -51,19 +51,6 @@ namespace Bit.Core.Repositories.SqlServer
}
}
public async Task<ICollection<GroupUserDetails>> GetManyUserDetailsByIdAsync(Guid id)
{
using(var connection = new SqlConnection(ConnectionString))
{
var results = await connection.QueryAsync<GroupUserDetails>(
$"[{Schema}].[GroupUserDetails_ReadByGroupId]",
new { GroupId = id },
commandType: CommandType.StoredProcedure);
return results.ToList();
}
}
public async Task<ICollection<Guid>> GetManyIdsByUserIdAsync(Guid organizationUserId)
{
using(var connection = new SqlConnection(ConnectionString))
@ -77,6 +64,19 @@ namespace Bit.Core.Repositories.SqlServer
}
}
public async Task<ICollection<Guid>> GetManyUserIdsByIdAsync(Guid id)
{
using(var connection = new SqlConnection(ConnectionString))
{
var results = await connection.QueryAsync<Guid>(
$"[{Schema}].[GroupUser_ReadOrganizationUserIdsByGroupId]",
new { GroupId = id },
commandType: CommandType.StoredProcedure);
return results.ToList();
}
}
public async Task<ICollection<GroupUser>> GetManyGroupUsersByOrganizationIdAsync(Guid organizationId)
{
using(var connection = new SqlConnection(ConnectionString))

View File

@ -174,7 +174,6 @@
<Build Include="dbo\Stored Procedures\GroupUser_ReadGroupIdsByOrganizationUserId.sql" />
<Build Include="dbo\Stored Procedures\GroupUser_UpdateGroups.sql" />
<Build Include="dbo\Stored Procedures\GroupUser_UpdateUsers.sql" />
<Build Include="dbo\Stored Procedures\GroupUserDetails_ReadByGroupId.sql" />
<Build Include="dbo\Stored Procedures\OrganizationUser_CreateWithCollections.sql" />
<Build Include="dbo\Stored Procedures\OrganizationUser_ReadWithCollectionsById.sql" />
<Build Include="dbo\Stored Procedures\OrganizationUser_UpdateWithCollections.sql" />
@ -237,5 +236,6 @@
<Build Include="dbo\Stored Procedures\Collection_ReadWithGroupsByIdUserId.sql" />
<Build Include="dbo\Stored Procedures\Collection_CreateWithGroups.sql" />
<Build Include="dbo\Stored Procedures\CollectionUser_UpdateUsers.sql" />
<Build Include="dbo\Stored Procedures\GroupUser_ReadOrganizationUserIdsByGroupId.sql" />
</ItemGroup>
</Project>

View File

@ -1,11 +1,18 @@
CREATE PROCEDURE [dbo].[CollectionUser_UpdateUsers]
@Id UNIQUEIDENTIFIER,
@CollectionId UNIQUEIDENTIFIER,
@Users AS [dbo].[SelectionReadOnlyArray] READONLY
AS
BEGIN
SET NOCOUNT ON
DECLARE @OrganizationId UNIQUEIDENTIFIER = (SELECT [OrganizationId] FROM [dbo].[Collection] WHERE [Id] = @Id)
DECLARE @OrgId UNIQUEIDENTIFIER = (
SELECT TOP 1
[OrganizationId]
FROM
[dbo].[Collection]
WHERE
[Id] = @CollectionId
)
;WITH [AvailableUsersCTE] AS(
SELECT
@ -13,29 +20,29 @@ BEGIN
FROM
[dbo].[OrganizationUser]
WHERE
OrganizationId = @OrganizationId
OrganizationId = @OrgId
)
MERGE
[dbo].[CollectionUser] AS [Target]
USING
@Users AS [Source]
ON
[Target].[CollectionId] = @Id
[Target].[CollectionId] = @CollectionId
AND [Target].[OrganizationUserId] = [Source].[Id]
WHEN NOT MATCHED BY TARGET
AND [Source].[Id] IN (SELECT [Id] FROM [AvailableUsersCTE]) THEN
INSERT VALUES
(
@Id,
@CollectionId,
[Source].[Id],
[Source].[ReadOnly]
)
WHEN MATCHED AND [Target].[ReadOnly] != [Source].[ReadOnly] THEN
UPDATE SET [Target].[ReadOnly] = [Source].[ReadOnly]
WHEN NOT MATCHED BY SOURCE
AND [Target].[CollectionId] = @Id THEN
AND [Target].[CollectionId] = @CollectionId THEN
DELETE
;
EXEC [dbo].[User_BumpAccountRevisionDateByCollectionId] @Id, @OrganizationId
EXEC [dbo].[User_BumpAccountRevisionDateByCollectionId] @CollectionId, @OrgId
END

View File

@ -1,22 +0,0 @@
CREATE PROCEDURE [dbo].[GroupUserDetails_ReadByGroupId]
@GroupId UNIQUEIDENTIFIER
AS
BEGIN
SET NOCOUNT ON
SELECT
OU.[Id] AS [OrganizationUserId],
OU.[AccessAll],
U.[Name],
ISNULL(U.[Email], OU.[Email]) Email,
OU.[Status],
OU.[Type]
FROM
[dbo].[OrganizationUser] OU
INNER JOIN
[dbo].[GroupUser] GU ON GU.[OrganizationUserId] = OU.[Id]
LEFT JOIN
[dbo].[User] U ON U.[Id] = OU.[UserId]
WHERE
GU.[GroupId] = @GroupId
END

View File

@ -0,0 +1,13 @@
CREATE PROCEDURE [dbo].[GroupUser_ReadOrganizationUserIdsByGroupId]
@GroupId UNIQUEIDENTIFIER
AS
BEGIN
SET NOCOUNT ON
SELECT
[OrganizationUserId]
FROM
[dbo].[GroupUser]
WHERE
[GroupId] = @GroupId
END

View File

@ -124,13 +124,20 @@ END
GO
CREATE PROCEDURE [dbo].[CollectionUser_UpdateUsers]
@Id UNIQUEIDENTIFIER,
@CollectionId UNIQUEIDENTIFIER,
@Users AS [dbo].[SelectionReadOnlyArray] READONLY
AS
BEGIN
SET NOCOUNT ON
DECLARE @OrganizationId UNIQUEIDENTIFIER = (SELECT [OrganizationId] FROM [dbo].[Collection] WHERE [Id] = @Id)
DECLARE @OrgId UNIQUEIDENTIFIER = (
SELECT TOP 1
[OrganizationId]
FROM
[dbo].[Collection]
WHERE
[Id] = @CollectionId
)
;WITH [AvailableUsersCTE] AS(
SELECT
@ -138,31 +145,31 @@ BEGIN
FROM
[dbo].[OrganizationUser]
WHERE
OrganizationId = @OrganizationId
OrganizationId = @OrgId
)
MERGE
[dbo].[CollectionUser] AS [Target]
USING
@Users AS [Source]
ON
[Target].[CollectionId] = @Id
[Target].[CollectionId] = @CollectionId
AND [Target].[OrganizationUserId] = [Source].[Id]
WHEN NOT MATCHED BY TARGET
AND [Source].[Id] IN (SELECT [Id] FROM [AvailableUsersCTE]) THEN
INSERT VALUES
(
@Id,
@CollectionId,
[Source].[Id],
[Source].[ReadOnly]
)
WHEN MATCHED AND [Target].[ReadOnly] != [Source].[ReadOnly] THEN
UPDATE SET [Target].[ReadOnly] = [Source].[ReadOnly]
WHEN NOT MATCHED BY SOURCE
AND [Target].[CollectionId] = @Id THEN
AND [Target].[CollectionId] = @CollectionId THEN
DELETE
;
EXEC [dbo].[User_BumpAccountRevisionDateByCollectionId] @Id, @OrganizationId
EXEC [dbo].[User_BumpAccountRevisionDateByCollectionId] @CollectionId, @OrgId
END
GO
@ -193,3 +200,30 @@ BEGIN
[CollectionId] = @CollectionId
END
GO
IF OBJECT_ID('[dbo].[GroupUserDetails_ReadByGroupId]') IS NOT NULL
BEGIN
DROP PROCEDURE [dbo].[GroupUserDetails_ReadByGroupId]
END
GO
IF OBJECT_ID('[dbo].[GroupUser_ReadOrganizationUserIdsByGroupId]') IS NOT NULL
BEGIN
DROP PROCEDURE [dbo].[GroupUser_ReadOrganizationUserIdsByGroupId]
END
GO
CREATE PROCEDURE [dbo].[GroupUser_ReadOrganizationUserIdsByGroupId]
@GroupId UNIQUEIDENTIFIER
AS
BEGIN
SET NOCOUNT ON
SELECT
[OrganizationUserId]
FROM
[dbo].[GroupUser]
WHERE
[GroupId] = @GroupId
END
GO