mirror of
https://github.com/bitwarden/server.git
synced 2025-07-09 20:03:47 -05:00
Group access & sproc/model refactoring.
This commit is contained in:
@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using Bit.Core.Models.Table;
|
||||
using Bit.Core.Models.Data;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bit.Core.Models.Api
|
||||
@ -20,19 +19,6 @@ namespace Bit.Core.Models.Api
|
||||
Name = collection.Name;
|
||||
}
|
||||
|
||||
public CollectionResponseModel(CollectionUserCollectionDetails collection, string obj = "collection")
|
||||
: base(obj)
|
||||
{
|
||||
if(collection == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(collection));
|
||||
}
|
||||
|
||||
Id = collection.Id.ToString();
|
||||
OrganizationId = collection.OrganizationId.ToString();
|
||||
Name = collection.Name;
|
||||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
public string OrganizationId { get; set; }
|
||||
public string Name { get; set; }
|
||||
@ -48,15 +34,4 @@ namespace Bit.Core.Models.Api
|
||||
|
||||
public IEnumerable<Guid> GroupIds { get; set; }
|
||||
}
|
||||
|
||||
public class CollectionUserDetailsResponseModel : CollectionResponseModel
|
||||
{
|
||||
public CollectionUserDetailsResponseModel(CollectionUserCollectionDetails collection)
|
||||
: base(collection, "collectionUserDetails")
|
||||
{
|
||||
ReadOnly = collection.ReadOnly;
|
||||
}
|
||||
|
||||
public bool ReadOnly { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +0,0 @@
|
||||
using System;
|
||||
using Bit.Core.Models.Data;
|
||||
|
||||
namespace Bit.Core.Models.Api
|
||||
{
|
||||
public class OrganizationUserCollectionResponseModel : ResponseModel
|
||||
{
|
||||
public OrganizationUserCollectionResponseModel(CollectionUserCollectionDetails details,
|
||||
string obj = "organizationUserCollection")
|
||||
: base(obj)
|
||||
{
|
||||
if(details == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(details));
|
||||
}
|
||||
|
||||
Id = details.Id.ToString();
|
||||
Name = details.Name;
|
||||
ReadOnly = details.ReadOnly;
|
||||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public bool ReadOnly { get; set; }
|
||||
}
|
||||
}
|
@ -3,11 +3,27 @@ using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Bit.Core.Models.Table;
|
||||
|
||||
namespace Bit.Core.Models.Api
|
||||
{
|
||||
public class OrganizationUserResponseModel : ResponseModel
|
||||
{
|
||||
public OrganizationUserResponseModel(OrganizationUser organizationUser, string obj = "organizationUser")
|
||||
: base(obj)
|
||||
{
|
||||
if(organizationUser == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(organizationUser));
|
||||
}
|
||||
|
||||
Id = organizationUser.Id.ToString();
|
||||
UserId = organizationUser.UserId?.ToString();
|
||||
Type = organizationUser.Type;
|
||||
Status = organizationUser.Status;
|
||||
AccessAll = organizationUser.AccessAll;
|
||||
}
|
||||
|
||||
public OrganizationUserResponseModel(OrganizationUserUserDetails organizationUser, string obj = "organizationUser")
|
||||
: base(obj)
|
||||
{
|
||||
@ -18,8 +34,6 @@ namespace Bit.Core.Models.Api
|
||||
|
||||
Id = organizationUser.Id.ToString();
|
||||
UserId = organizationUser.UserId?.ToString();
|
||||
Name = organizationUser.Name;
|
||||
Email = organizationUser.Email;
|
||||
Type = organizationUser.Type;
|
||||
Status = organizationUser.Status;
|
||||
AccessAll = organizationUser.AccessAll;
|
||||
@ -27,8 +41,6 @@ namespace Bit.Core.Models.Api
|
||||
|
||||
public string Id { get; set; }
|
||||
public string UserId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Email { get; set; }
|
||||
public OrganizationUserType Type { get; set; }
|
||||
public OrganizationUserStatusType Status { get; set; }
|
||||
public bool AccessAll { get; set; }
|
||||
@ -36,14 +48,48 @@ namespace Bit.Core.Models.Api
|
||||
|
||||
public class OrganizationUserDetailsResponseModel : OrganizationUserResponseModel
|
||||
{
|
||||
public OrganizationUserDetailsResponseModel(OrganizationUserUserDetails organizationUser,
|
||||
IEnumerable<CollectionUserCollectionDetails> collections)
|
||||
public OrganizationUserDetailsResponseModel(OrganizationUser organizationUser,
|
||||
IEnumerable<SelectionReadOnly> collections)
|
||||
: base(organizationUser, "organizationUserDetails")
|
||||
{
|
||||
Collections = new ListResponseModel<OrganizationUserCollectionResponseModel>(
|
||||
collections.Select(c => new OrganizationUserCollectionResponseModel(c)));
|
||||
Collections = collections.Select(c => new CollectionSelection(c));
|
||||
}
|
||||
|
||||
public ListResponseModel<OrganizationUserCollectionResponseModel> Collections { get; set; }
|
||||
public IEnumerable<CollectionSelection> Collections { get; set; }
|
||||
|
||||
public class CollectionSelection
|
||||
{
|
||||
public CollectionSelection(Data.SelectionReadOnly selection)
|
||||
{
|
||||
if(selection == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(selection));
|
||||
}
|
||||
|
||||
Id = selection.Id.ToString();
|
||||
ReadOnly = selection.ReadOnly;
|
||||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
public bool ReadOnly { get; set; }
|
||||
}
|
||||
}
|
||||
public class OrganizationUserUserDetailsResponseModel : OrganizationUserResponseModel
|
||||
{
|
||||
public OrganizationUserUserDetailsResponseModel(OrganizationUserUserDetails organizationUser,
|
||||
string obj = "organizationUserUserDetails")
|
||||
: base(organizationUser, obj)
|
||||
{
|
||||
if(organizationUser == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(organizationUser));
|
||||
}
|
||||
|
||||
Name = organizationUser.Name;
|
||||
Email = organizationUser.Email;
|
||||
}
|
||||
|
||||
public string Name { get; set; }
|
||||
public string Email { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -2,11 +2,9 @@
|
||||
|
||||
namespace Bit.Core.Models.Data
|
||||
{
|
||||
public class CollectionUserCollectionDetails
|
||||
public class SelectionReadOnly
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid OrganizationId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public bool ReadOnly { get; set; }
|
||||
}
|
||||
}
|
@ -9,7 +9,6 @@ namespace Bit.Core.Repositories
|
||||
public interface ICollectionUserRepository : IRepository<CollectionUser, Guid>
|
||||
{
|
||||
Task<ICollection<CollectionUser>> GetManyByOrganizationUserIdAsync(Guid orgUserId);
|
||||
Task<ICollection<CollectionUserCollectionDetails>> GetManyDetailsByUserIdAsync(Guid userId);
|
||||
Task<ICollection<CollectionUserUserDetails>> GetManyDetailsByCollectionIdAsync(Guid organizationId, Guid collectionId);
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ namespace Bit.Core.Repositories
|
||||
Task<ICollection<OrganizationUser>> GetManyByOrganizationAsync(Guid organizationId, OrganizationUserType? type);
|
||||
Task<OrganizationUser> GetByOrganizationAsync(Guid organizationId, string email);
|
||||
Task<OrganizationUser> GetByOrganizationAsync(Guid organizationId, Guid userId);
|
||||
Task<Tuple<OrganizationUserUserDetails, ICollection<CollectionUserCollectionDetails>>> GetDetailsByIdAsync(Guid id);
|
||||
Task<Tuple<OrganizationUser, ICollection<SelectionReadOnly>>> GetByIdWithCollectionsAsync(Guid id);
|
||||
Task<ICollection<OrganizationUserUserDetails>> GetManyDetailsByOrganizationAsync(Guid organizationId);
|
||||
Task<ICollection<OrganizationUserOrganizationDetails>> GetManyDetailsByUserAsync(Guid userId,
|
||||
OrganizationUserStatusType? status = null);
|
||||
|
@ -68,11 +68,15 @@ namespace Bit.Core.Repositories.SqlServer
|
||||
using(var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
var results = await connection.QueryAsync<Collection>(
|
||||
$"[{Schema}].[{Table}_ReadByUserId]",
|
||||
$"[{Schema}].[Collection_ReadByUserId]",
|
||||
new { UserId = userId },
|
||||
commandType: CommandType.StoredProcedure);
|
||||
|
||||
return results.ToList();
|
||||
// Return distinct Id results.
|
||||
return results
|
||||
.GroupBy(c => c.Id)
|
||||
.Select(c => c.First())
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,19 +33,6 @@ namespace Bit.Core.Repositories.SqlServer
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ICollection<CollectionUserCollectionDetails>> GetManyDetailsByUserIdAsync(Guid userId)
|
||||
{
|
||||
using(var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
var results = await connection.QueryAsync<CollectionUserCollectionDetails>(
|
||||
$"[{Schema}].[CollectionUserCollectionDetails_ReadByUserId]",
|
||||
new { UserId = userId },
|
||||
commandType: CommandType.StoredProcedure);
|
||||
|
||||
return results.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ICollection<CollectionUserUserDetails>> GetManyDetailsByCollectionIdAsync(Guid organizationId,
|
||||
Guid collectionId)
|
||||
{
|
||||
@ -56,7 +43,11 @@ namespace Bit.Core.Repositories.SqlServer
|
||||
new { OrganizationId = organizationId, CollectionId = collectionId },
|
||||
commandType: CommandType.StoredProcedure);
|
||||
|
||||
return results.ToList();
|
||||
// Return distinct Id results. If at least one of the grouped results is not ReadOnly, that we return it.
|
||||
return results
|
||||
.GroupBy(c => c.Id)
|
||||
.Select(g => g.OrderBy(og => og.ReadOnly).First())
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -114,19 +114,18 @@ namespace Bit.Core.Repositories.SqlServer
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Tuple<OrganizationUserUserDetails, ICollection<CollectionUserCollectionDetails>>>
|
||||
GetDetailsByIdAsync(Guid id)
|
||||
public async Task<Tuple<OrganizationUser, ICollection<SelectionReadOnly>>> GetByIdWithCollectionsAsync(Guid id)
|
||||
{
|
||||
using(var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
var results = await connection.QueryMultipleAsync(
|
||||
"[dbo].[OrganizationUserUserDetails_ReadById]",
|
||||
"[dbo].[OrganizationUser_ReadWithCollectionsById]",
|
||||
new { Id = id },
|
||||
commandType: CommandType.StoredProcedure);
|
||||
|
||||
var user = (await results.ReadAsync<OrganizationUserUserDetails>()).SingleOrDefault();
|
||||
var collections = (await results.ReadAsync<CollectionUserCollectionDetails>()).ToList();
|
||||
return new Tuple<OrganizationUserUserDetails, ICollection<CollectionUserCollectionDetails>>(user, collections);
|
||||
var user = (await results.ReadAsync<OrganizationUser>()).SingleOrDefault();
|
||||
var collections = (await results.ReadAsync<SelectionReadOnly>()).ToList();
|
||||
return new Tuple<OrganizationUser, ICollection<SelectionReadOnly>>(user, collections);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user