mirror of
https://github.com/bitwarden/server.git
synced 2025-07-02 16:42:50 -05:00
SubvaultUser APIs and services
This commit is contained in:
@ -1,19 +0,0 @@
|
||||
using Bit.Core.Models.Table;
|
||||
|
||||
namespace Bit.Core.Models.Api
|
||||
{
|
||||
public class OrganizationUserInviteRequestModel
|
||||
{
|
||||
public string Email { get; set; }
|
||||
}
|
||||
|
||||
public class OrganizationUserAcceptRequestModel
|
||||
{
|
||||
public string Token { get; set; }
|
||||
}
|
||||
|
||||
public class OrganizationUserConfirmRequestModel
|
||||
{
|
||||
public string Key { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
using Bit.Core.Models.Table;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bit.Core.Models.Api
|
||||
{
|
||||
public class OrganizationUserInviteRequestModel
|
||||
{
|
||||
public string Email { get; set; }
|
||||
}
|
||||
|
||||
public class OrganizationUserAcceptRequestModel
|
||||
{
|
||||
public string Token { get; set; }
|
||||
}
|
||||
|
||||
public class OrganizationUserConfirmRequestModel
|
||||
{
|
||||
public string Key { get; set; }
|
||||
}
|
||||
|
||||
public class OrganizationUserUpdateRequestModel
|
||||
{
|
||||
public Enums.OrganizationUserType Type { get; set; }
|
||||
public IEnumerable<Subvault> Subvaults { get; set; }
|
||||
|
||||
public class Subvault
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string SubvaultId { get; set; }
|
||||
public bool Admin { get; set; }
|
||||
public bool ReadOnly { get; set; }
|
||||
|
||||
public SubvaultUser ToSubvaultUser()
|
||||
{
|
||||
var user = new SubvaultUser
|
||||
{
|
||||
SubvaultId = new Guid(SubvaultId),
|
||||
Admin = Admin,
|
||||
ReadOnly = ReadOnly
|
||||
};
|
||||
|
||||
if(string.IsNullOrWhiteSpace(Id))
|
||||
{
|
||||
user.Id = new Guid(Id);
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
42
src/Core/Models/Api/Request/SubvaultUserRequestModel.cs
Normal file
42
src/Core/Models/Api/Request/SubvaultUserRequestModel.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Core.Models.Table;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Bit.Core.Models.Api
|
||||
{
|
||||
public class SubvaultUserSubvaultRequestModel
|
||||
{
|
||||
public string UserId { get; set; }
|
||||
public IEnumerable<Subvault> Subvaults { get; set; }
|
||||
|
||||
public IEnumerable<SubvaultUser> ToSubvaultUsers()
|
||||
{
|
||||
return Subvaults.Select(s => new SubvaultUser
|
||||
{
|
||||
OrganizationUserId = new Guid(UserId),
|
||||
SubvaultId = new Guid(s.SubvaultId),
|
||||
Admin = s.Admin,
|
||||
ReadOnly = s.ReadOnly
|
||||
});
|
||||
}
|
||||
|
||||
public class Subvault
|
||||
{
|
||||
public string SubvaultId { get; set; }
|
||||
public bool Admin { get; set; }
|
||||
public bool ReadOnly { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
public class SubvaultUserUserRequestModel
|
||||
{
|
||||
public string UserId { get; set; }
|
||||
public bool Admin { get; set; }
|
||||
public bool ReadOnly { get; set; }
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@ namespace Bit.Core.Models.Table
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid SubvaultId { get; set; }
|
||||
public Guid UserId { get; set; }
|
||||
public Guid OrganizationUserId { get; set; }
|
||||
public bool Admin { get; set; }
|
||||
public bool ReadOnly { get; set; }
|
||||
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
|
||||
|
@ -9,6 +9,7 @@ namespace Bit.Core.Repositories
|
||||
{
|
||||
Task<Subvault> GetByIdAdminUserIdAsync(Guid id, Guid userId);
|
||||
Task<ICollection<Subvault>> GetManyByOrganizationIdAdminUserIdAsync(Guid organizationId, Guid userId);
|
||||
Task<ICollection<Subvault>> GetManyByOrganizationIdAsync(Guid organizationId);
|
||||
Task<ICollection<Subvault>> GetManyByUserIdAsync(Guid userId);
|
||||
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Models.Table;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bit.Core.Repositories
|
||||
{
|
||||
public interface ISubvaultUserRepository : IRepository<SubvaultUser, Guid>
|
||||
{
|
||||
|
||||
Task<ICollection<SubvaultUser>> GetManyByOrganizationUserIdAsync(Guid orgUserId);
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,19 @@ namespace Bit.Core.Repositories.SqlServer
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ICollection<Subvault>> GetManyByOrganizationIdAsync(Guid organizationId)
|
||||
{
|
||||
using(var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
var results = await connection.QueryAsync<Subvault>(
|
||||
$"[{Schema}].[{Table}_ReadByOrganizationId]",
|
||||
new { OrganizationId = organizationId },
|
||||
commandType: CommandType.StoredProcedure);
|
||||
|
||||
return results.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ICollection<Subvault>> GetManyByUserIdAsync(Guid userId)
|
||||
{
|
||||
using(var connection = new SqlConnection(ConnectionString))
|
||||
|
@ -1,5 +1,11 @@
|
||||
using System;
|
||||
using Bit.Core.Models.Table;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using Dapper;
|
||||
using System.Linq;
|
||||
|
||||
namespace Bit.Core.Repositories.SqlServer
|
||||
{
|
||||
@ -12,5 +18,18 @@ namespace Bit.Core.Repositories.SqlServer
|
||||
public SubvaultUserRepository(string connectionString)
|
||||
: base(connectionString)
|
||||
{ }
|
||||
|
||||
public async Task<ICollection<SubvaultUser>> GetManyByOrganizationUserIdAsync(Guid orgUserId)
|
||||
{
|
||||
using(var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
var results = await connection.QueryAsync<SubvaultUser>(
|
||||
$"[{Schema}].[{Table}_ReadByOrganizationUserId]",
|
||||
new { OrganizationUserId = orgUserId },
|
||||
commandType: CommandType.StoredProcedure);
|
||||
|
||||
return results.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
using Bit.Core.Models.Business;
|
||||
using Bit.Core.Models.Table;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
@ -11,5 +12,6 @@ namespace Bit.Core.Services
|
||||
Task<OrganizationUser> InviteUserAsync(Guid organizationId, string email);
|
||||
Task<OrganizationUser> AcceptUserAsync(Guid organizationUserId, User user, string token);
|
||||
Task<OrganizationUser> ConfirmUserAsync(Guid organizationUserId, string key);
|
||||
Task<OrganizationUser> SaveUserAsync(OrganizationUser user, IEnumerable<SubvaultUser> subvaults);
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ using Bit.Core.Models.Business;
|
||||
using Bit.Core.Models.Table;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Core.Exceptions;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
@ -13,15 +14,21 @@ namespace Bit.Core.Services
|
||||
{
|
||||
private readonly IOrganizationRepository _organizationRepository;
|
||||
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||
private readonly ISubvaultRepository _subvaultRepository;
|
||||
private readonly ISubvaultUserRepository _subvaultUserRepository;
|
||||
private readonly IUserRepository _userRepository;
|
||||
|
||||
public OrganizationService(
|
||||
IOrganizationRepository organizationRepository,
|
||||
IOrganizationUserRepository organizationUserRepository,
|
||||
ISubvaultRepository subvaultRepository,
|
||||
ISubvaultUserRepository subvaultUserRepository,
|
||||
IUserRepository userRepository)
|
||||
{
|
||||
_organizationRepository = organizationRepository;
|
||||
_organizationUserRepository = organizationUserRepository;
|
||||
_subvaultRepository = subvaultRepository;
|
||||
_subvaultUserRepository = subvaultUserRepository;
|
||||
_userRepository = userRepository;
|
||||
}
|
||||
|
||||
@ -141,5 +148,37 @@ namespace Bit.Core.Services
|
||||
|
||||
return orgUser;
|
||||
}
|
||||
|
||||
public async Task<OrganizationUser> SaveUserAsync(OrganizationUser user, IEnumerable<SubvaultUser> subvaults)
|
||||
{
|
||||
if(user.Id.Equals(default(Guid)))
|
||||
{
|
||||
throw new BadRequestException("Invite the user first.");
|
||||
}
|
||||
|
||||
await _organizationUserRepository.ReplaceAsync(user);
|
||||
|
||||
var orgSubvaults = await _subvaultRepository.GetManyByOrganizationIdAsync(user.OrganizationId);
|
||||
var currentUserSubvaults = await _subvaultUserRepository.GetManyByOrganizationUserIdAsync(user.Id);
|
||||
|
||||
// Let's make sure all these belong to this user and organization.
|
||||
var filteredSubvaults = subvaults.Where(s =>
|
||||
orgSubvaults.Any(os => os.Id == s.SubvaultId) &&
|
||||
(s.Id == default(Guid) || currentUserSubvaults.Any(cs => cs.Id == s.Id)));
|
||||
|
||||
var subvaultsToDelete = currentUserSubvaults.Where(cs => !subvaults.Any(s => s.Id == cs.Id));
|
||||
|
||||
foreach(var subvault in filteredSubvaults)
|
||||
{
|
||||
await _subvaultUserRepository.UpsertAsync(subvault);
|
||||
}
|
||||
|
||||
foreach(var subvault in subvaultsToDelete)
|
||||
{
|
||||
await _subvaultUserRepository.DeleteAsync(subvault);
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user