1
0
mirror of https://github.com/bitwarden/server synced 2025-12-25 12:43:14 +00:00

Merge remote-tracking branch 'origin/master' into feature/flexible-collections

This commit is contained in:
Thomas Rittson
2023-10-23 08:47:11 +10:00
196 changed files with 1219 additions and 817 deletions

View File

@@ -1,8 +1,9 @@
using System.ComponentModel.DataAnnotations;
using Bit.Core.Entities;
using Bit.Core.Models;
using Bit.Core.Utilities;
namespace Bit.Core.Entities;
namespace Bit.Core.AdminConsole.Entities;
public class Group : ITableObject<Guid>, IExternal
{

View File

@@ -1,4 +1,4 @@
namespace Bit.Core.Entities;
namespace Bit.Core.AdminConsole.Entities;
public class GroupUser
{

View File

@@ -1,6 +1,6 @@
using Bit.Core.Entities;
using Bit.Core.AdminConsole.Entities;
namespace Bit.Core.Models.Business;
namespace Bit.Core.AdminConsole.Models.Business;
public class ImportedGroup
{

View File

@@ -1,7 +1,7 @@
using System.Data;
using Bit.Core.Entities;
using Bit.Core.AdminConsole.Entities;
namespace Bit.Core.Models.Data;
namespace Bit.Core.AdminConsole.Models.Data;
public class GroupWithCollections : Group
{

View File

@@ -1,16 +1,18 @@
using Bit.Core.Context;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.OrganizationFeatures.Groups.Interfaces;
using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Context;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Models.Data;
using Bit.Core.OrganizationFeatures.Groups.Interfaces;
using Bit.Core.Repositories;
using Bit.Core.Services;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
namespace Bit.Core.OrganizationFeatures.Groups;
namespace Bit.Core.AdminConsole.OrganizationFeatures.Groups;
public class CreateGroupCommand : ICreateGroupCommand
{
@@ -46,7 +48,7 @@ public class CreateGroupCommand : ICreateGroupCommand
await GroupRepositoryUpdateUsersAsync(group, users);
}
await _eventService.LogGroupEventAsync(group, Enums.EventType.Group_Created);
await _eventService.LogGroupEventAsync(group, Core.Enums.EventType.Group_Created);
}
public async Task CreateGroupAsync(Group group, Organization organization, EventSystemUser systemUser,
@@ -61,7 +63,7 @@ public class CreateGroupCommand : ICreateGroupCommand
await GroupRepositoryUpdateUsersAsync(group, users, systemUser);
}
await _eventService.LogGroupEventAsync(group, Enums.EventType.Group_Created, systemUser);
await _eventService.LogGroupEventAsync(group, Core.Enums.EventType.Group_Created, systemUser);
}
private async Task GroupRepositoryCreateGroupAsync(Group group, Organization organization, IEnumerable<CollectionAccessSelection> collections = null)

View File

@@ -1,11 +1,11 @@
using Bit.Core.Entities;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.OrganizationFeatures.Groups.Interfaces;
using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.OrganizationFeatures.Groups.Interfaces;
using Bit.Core.Repositories;
using Bit.Core.Services;
namespace Bit.Core.OrganizationFeatures.Groups;
namespace Bit.Core.AdminConsole.OrganizationFeatures.Groups;
public class DeleteGroupCommand : IDeleteGroupCommand
{

View File

@@ -1,8 +1,9 @@
using Bit.Core.Entities;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Models.Data;
namespace Bit.Core.OrganizationFeatures.Groups.Interfaces;
namespace Bit.Core.AdminConsole.OrganizationFeatures.Groups.Interfaces;
public interface ICreateGroupCommand
{

View File

@@ -1,7 +1,7 @@
using Bit.Core.Entities;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.Enums;
namespace Bit.Core.OrganizationFeatures.Groups.Interfaces;
namespace Bit.Core.AdminConsole.OrganizationFeatures.Groups.Interfaces;
public interface IDeleteGroupCommand
{

View File

@@ -1,8 +1,9 @@
using Bit.Core.Entities;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Models.Data;
namespace Bit.Core.OrganizationFeatures.Groups.Interfaces;
namespace Bit.Core.AdminConsole.OrganizationFeatures.Groups.Interfaces;
public interface IUpdateGroupCommand
{

View File

@@ -1,12 +1,14 @@
using Bit.Core.Entities;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.OrganizationFeatures.Groups.Interfaces;
using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Models.Data;
using Bit.Core.OrganizationFeatures.Groups.Interfaces;
using Bit.Core.Repositories;
using Bit.Core.Services;
namespace Bit.Core.OrganizationFeatures.Groups;
namespace Bit.Core.AdminConsole.OrganizationFeatures.Groups;
public class UpdateGroupCommand : IUpdateGroupCommand
{
@@ -36,7 +38,7 @@ public class UpdateGroupCommand : IUpdateGroupCommand
await GroupRepositoryUpdateUsersAsync(group, userIds);
}
await _eventService.LogGroupEventAsync(group, Enums.EventType.Group_Updated);
await _eventService.LogGroupEventAsync(group, Core.Enums.EventType.Group_Updated);
}
public async Task UpdateGroupAsync(Group group, Organization organization, EventSystemUser systemUser,
@@ -51,7 +53,7 @@ public class UpdateGroupCommand : IUpdateGroupCommand
await GroupRepositoryUpdateUsersAsync(group, userIds, systemUser);
}
await _eventService.LogGroupEventAsync(group, Enums.EventType.Group_Updated, systemUser);
await _eventService.LogGroupEventAsync(group, Core.Enums.EventType.Group_Updated, systemUser);
}
private async Task GroupRepositoryUpdateGroupAsync(Group group, IEnumerable<CollectionAccessSelection> collections = null)

View File

@@ -1,7 +1,8 @@
using Bit.Core.Entities;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.Models.Data;
using Bit.Core.Repositories;
namespace Bit.Core.Repositories;
namespace Bit.Core.AdminConsole.Repositories;
public interface IGroupRepository : IRepository<Group, Guid>
{

View File

@@ -1,7 +1,7 @@
using Bit.Core.Entities;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.Enums;
namespace Bit.Core.Services;
namespace Bit.Core.AdminConsole.Services;
public interface IGroupService
{

View File

@@ -1,9 +1,12 @@
using Bit.Core.Entities;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Repositories;
using Bit.Core.Services;
namespace Bit.Core.Services;
namespace Bit.Core.AdminConsole.Services.Implementations;
public class GroupService : IGroupService
{

View File

@@ -1,5 +1,5 @@
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.OrganizationFeatures.OrganizationDomains.Interfaces;
using Bit.Core.Repositories;
using Bit.Core.Services;
@@ -18,15 +18,9 @@ public class DeleteOrganizationDomainCommand : IDeleteOrganizationDomainCommand
_eventService = eventService;
}
public async Task DeleteAsync(Guid id)
public async Task DeleteAsync(OrganizationDomain organizationDomain)
{
var domain = await _organizationDomainRepository.GetByIdAsync(id);
if (domain is null)
{
throw new NotFoundException();
}
await _organizationDomainRepository.DeleteAsync(domain);
await _eventService.LogOrganizationDomainEventAsync(domain, EventType.OrganizationDomain_Removed);
await _organizationDomainRepository.DeleteAsync(organizationDomain);
await _eventService.LogOrganizationDomainEventAsync(organizationDomain, EventType.OrganizationDomain_Removed);
}
}

View File

@@ -4,15 +4,15 @@ using Bit.Core.Repositories;
namespace Bit.Core.OrganizationFeatures.OrganizationDomains;
public class GetOrganizationDomainByIdQuery : IGetOrganizationDomainByIdQuery
public class GetOrganizationDomainByIdOrganizationIdQuery : IGetOrganizationDomainByIdOrganizationIdQuery
{
private readonly IOrganizationDomainRepository _organizationDomainRepository;
public GetOrganizationDomainByIdQuery(IOrganizationDomainRepository organizationDomainRepository)
public GetOrganizationDomainByIdOrganizationIdQuery(IOrganizationDomainRepository organizationDomainRepository)
{
_organizationDomainRepository = organizationDomainRepository;
}
public async Task<OrganizationDomain> GetOrganizationDomainById(Guid id)
=> await _organizationDomainRepository.GetByIdAsync(id);
public async Task<OrganizationDomain> GetOrganizationDomainByIdOrganizationIdAsync(Guid id, Guid organizationId)
=> await _organizationDomainRepository.GetDomainByIdOrganizationIdAsync(id, organizationId);
}

View File

@@ -13,6 +13,6 @@ public class GetOrganizationDomainByOrganizationIdQuery : IGetOrganizationDomain
_organizationDomainRepository = organizationDomainRepository;
}
public async Task<ICollection<OrganizationDomain>> GetDomainsByOrganizationId(Guid orgId)
public async Task<ICollection<OrganizationDomain>> GetDomainsByOrganizationIdAsync(Guid orgId)
=> await _organizationDomainRepository.GetDomainsByOrganizationIdAsync(orgId);
}

View File

@@ -1,6 +1,8 @@
namespace Bit.Core.OrganizationFeatures.OrganizationDomains.Interfaces;
using Bit.Core.Entities;
namespace Bit.Core.OrganizationFeatures.OrganizationDomains.Interfaces;
public interface IDeleteOrganizationDomainCommand
{
Task DeleteAsync(Guid id);
Task DeleteAsync(OrganizationDomain organizationDomain);
}

View File

@@ -0,0 +1,8 @@
using Bit.Core.Entities;
namespace Bit.Core.OrganizationFeatures.OrganizationDomains.Interfaces;
public interface IGetOrganizationDomainByIdOrganizationIdQuery
{
Task<OrganizationDomain> GetOrganizationDomainByIdOrganizationIdAsync(Guid id, Guid organizationId);
}

View File

@@ -1,8 +0,0 @@
using Bit.Core.Entities;
namespace Bit.Core.OrganizationFeatures.OrganizationDomains.Interfaces;
public interface IGetOrganizationDomainByIdQuery
{
Task<OrganizationDomain> GetOrganizationDomainById(Guid id);
}

View File

@@ -4,5 +4,5 @@ namespace Bit.Core.OrganizationFeatures.OrganizationDomains.Interfaces;
public interface IGetOrganizationDomainByOrganizationIdQuery
{
Task<ICollection<OrganizationDomain>> GetDomainsByOrganizationId(Guid orgId);
Task<ICollection<OrganizationDomain>> GetDomainsByOrganizationIdAsync(Guid orgId);
}

View File

@@ -4,5 +4,5 @@ namespace Bit.Core.OrganizationFeatures.OrganizationDomains.Interfaces;
public interface IVerifyOrganizationDomainCommand
{
Task<OrganizationDomain> VerifyOrganizationDomain(Guid id);
Task<OrganizationDomain> VerifyOrganizationDomainAsync(OrganizationDomain organizationDomain);
}

View File

@@ -27,14 +27,8 @@ public class VerifyOrganizationDomainCommand : IVerifyOrganizationDomainCommand
_logger = logger;
}
public async Task<OrganizationDomain> VerifyOrganizationDomain(Guid id)
public async Task<OrganizationDomain> VerifyOrganizationDomainAsync(OrganizationDomain domain)
{
var domain = await _organizationDomainRepository.GetByIdAsync(id);
if (domain is null)
{
throw new NotFoundException();
}
if (domain.VerifiedDate is not null)
{
domain.SetLastCheckedDate();

View File

@@ -1,8 +1,8 @@
using Bit.Core.AdminConsole.OrganizationAuth;
using Bit.Core.AdminConsole.OrganizationAuth.Interfaces;
using Bit.Core.AdminConsole.OrganizationFeatures.Groups;
using Bit.Core.AdminConsole.OrganizationFeatures.Groups.Interfaces;
using Bit.Core.Models.Business.Tokenables;
using Bit.Core.OrganizationFeatures.Groups;
using Bit.Core.OrganizationFeatures.Groups.Interfaces;
using Bit.Core.OrganizationFeatures.OrganizationApiKeys;
using Bit.Core.OrganizationFeatures.OrganizationApiKeys.Interfaces;
using Bit.Core.OrganizationFeatures.OrganizationCollections;
@@ -119,7 +119,7 @@ public static class OrganizationServiceCollectionExtensions
{
services.AddScoped<ICreateOrganizationDomainCommand, CreateOrganizationDomainCommand>();
services.AddScoped<IVerifyOrganizationDomainCommand, VerifyOrganizationDomainCommand>();
services.AddScoped<IGetOrganizationDomainByIdQuery, GetOrganizationDomainByIdQuery>();
services.AddScoped<IGetOrganizationDomainByIdOrganizationIdQuery, GetOrganizationDomainByIdOrganizationIdQuery>();
services.AddScoped<IGetOrganizationDomainByOrganizationIdQuery, GetOrganizationDomainByOrganizationIdQuery>();
services.AddScoped<IDeleteOrganizationDomainCommand, DeleteOrganizationDomainCommand>();
}

View File

@@ -1,4 +1,5 @@
using Bit.Core.AdminConsole.Models.OrganizationConnectionConfigs;
using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Auth.Enums;
using Bit.Core.Auth.Repositories;
using Bit.Core.Context;

View File

@@ -19,4 +19,6 @@ public interface IEventRepository
PageOptions pageOptions);
Task CreateAsync(IEvent e);
Task CreateManyAsync(IEnumerable<IEvent> e);
Task<PagedResult<IEvent>> GetManyByOrganizationServiceAccountAsync(Guid organizationId, Guid serviceAccountId,
DateTime startDate, DateTime endDate, PageOptions pageOptions);
}

View File

@@ -5,6 +5,7 @@ namespace Bit.Core.Repositories;
public interface IOrganizationConnectionRepository : IRepository<OrganizationConnection, Guid>
{
Task<OrganizationConnection> GetByIdOrganizationIdAsync(Guid id, Guid organizationId);
Task<ICollection<OrganizationConnection>> GetByOrganizationIdTypeAsync(Guid organizationId, OrganizationConnectionType type);
Task<ICollection<OrganizationConnection>> GetEnabledByOrganizationIdTypeAsync(Guid organizationId, OrganizationConnectionType type);
}

View File

@@ -9,6 +9,7 @@ public interface IOrganizationDomainRepository : IRepository<OrganizationDomain,
Task<ICollection<OrganizationDomain>> GetDomainsByOrganizationIdAsync(Guid orgId);
Task<ICollection<OrganizationDomain>> GetManyByNextRunDateAsync(DateTime date);
Task<OrganizationDomainSsoDetailsData> GetOrganizationDomainSsoDetailsAsync(string email);
Task<OrganizationDomain> GetDomainByIdOrganizationIdAsync(Guid id, Guid organizationId);
Task<OrganizationDomain> GetDomainByOrgIdAndDomainNameAsync(Guid orgId, string domainName);
Task<ICollection<OrganizationDomain>> GetExpiredOrganizationDomainsAsync();
Task<bool> DeleteExpiredAsync(int expirationPeriod);

View File

@@ -61,6 +61,14 @@ public class EventRepository : IEventRepository
return await GetManyAsync(partitionKey, $"CipherId={cipher.Id}__Date={{0}}", startDate, endDate, pageOptions);
}
public async Task<PagedResult<IEvent>> GetManyByOrganizationServiceAccountAsync(Guid organizationId,
Guid serviceAccountId, DateTime startDate, DateTime endDate, PageOptions pageOptions)
{
return await GetManyAsync($"OrganizationId={organizationId}",
$"ServiceAccountId={serviceAccountId}__Date={{0}}", startDate, endDate, pageOptions);
}
public async Task CreateAsync(IEvent e)
{
if (!(e is EventTableEntity entity))

View File

@@ -15,4 +15,5 @@ public static class ServiceAccountOperations
public static readonly ServiceAccountOperationRequirement ReadAccessTokens = new() { Name = nameof(ReadAccessTokens) };
public static readonly ServiceAccountOperationRequirement CreateAccessToken = new() { Name = nameof(CreateAccessToken) };
public static readonly ServiceAccountOperationRequirement RevokeAccessTokens = new() { Name = nameof(RevokeAccessTokens) };
public static readonly ServiceAccountOperationRequirement ReadEvents = new() { Name = nameof(ReadEvents) };
}

View File

@@ -1,4 +1,5 @@
#nullable enable
using Bit.Core.AdminConsole.Entities;
using Bit.Core.Entities;
using Bit.Core.Utilities;

View File

@@ -1,4 +1,5 @@
using Bit.Core.Entities;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.Entities;
using Bit.Core.Entities.Provider;
using Bit.Core.Enums;
using Bit.Core.SecretsManager.Entities;

View File

@@ -1,4 +1,5 @@
using System.Security.Claims;
using Bit.Core.AdminConsole.Models.Business;
using Bit.Core.Auth.Enums;
using Bit.Core.Entities;
using Bit.Core.Enums;

View File

@@ -1,4 +1,5 @@
using Bit.Core.Context;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.Context;
using Bit.Core.Entities;
using Bit.Core.Entities.Provider;
using Bit.Core.Enums;

View File

@@ -1,5 +1,8 @@
using System.Security.Claims;
using System.Text.Json;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.Models.Business;
using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Auth.Enums;
using Bit.Core.Auth.Models.Business;
using Bit.Core.Auth.Repositories;

View File

@@ -1,4 +1,5 @@
using Bit.Core.Entities;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.Entities;
using Bit.Core.Entities.Provider;
using Bit.Core.Enums;
using Bit.Core.SecretsManager.Entities;