From f6ebb20847220d99ee0b3b0e28778b969bd54118 Mon Sep 17 00:00:00 2001 From: Oscar Hinton Date: Thu, 15 Jul 2021 16:37:27 +0200 Subject: [PATCH] [Provider] Add support for events (#1447) --- .../src/CommCore/Services/ProviderService.cs | 28 +- .../Portal/EnterprisePortalCurrentContext.cs | 4 +- src/Api/Controllers/EventsController.cs | 38 + .../ProviderOrganizationsController.cs | 13 + .../Controllers/ProviderUsersController.cs | 24 +- src/Api/Controllers/ProvidersController.cs | 24 +- src/Core/Context/CurrentContext.cs | 37 +- src/Core/Context/ICurrentContext.cs | 5 +- .../ProviderOrganizationProviderUserType.cs | 8 - .../Providers/ProviderUpdateRequestModel.cs | 31 + .../Models/Api/Response/EventResponseModel.cs | 4 + .../ProfileOrganizationResponseModel.cs | 6 +- ...rofileProviderOrganizationResponseModel.cs | 43 +- .../Providers/ProviderUserResponseModel.cs | 4 +- src/Core/Models/Data/EventTableEntity.cs | 40 +- src/Core/Models/Data/IEvent.cs | 2 + .../ProviderUserOrganizationDetails.cs | 13 +- .../Data/Provider/ProviderUserPublicKey.cs | 1 + src/Core/Models/EntityFramework/Event.cs | 2 - .../ProviderOrganizationProviderUser.cs | 18 - src/Core/Models/Table/Event.cs | 4 + .../ProviderOrganizationProviderUser.cs | 25 - .../EntityFramework/DatabaseContext.cs | 4 - .../EntityFramework/EventRepository.cs | 52 + ...viderOrganizationProviderUserRepository.cs | 20 - .../ProviderOrganizationRepository.cs | 18 +- .../EntityFramework/ProviderRepository.cs | 25 +- .../EntityFramework/ProviderUserRepository.cs | 14 +- ...ntReadPageByProviderIdActingUserIdQuery.cs | 41 + .../Queries/EventReadPageByProviderIdQuery.cs | 38 + ...izationUserOrganizationDetailsViewQuery.cs | 8 +- ...roviderUserOrganizationDetailsViewQuery.cs | 46 + ...rProviderDetailsReadByUserIdStatusQuery.cs | 1 + src/Core/Repositories/IEventRepository.cs | 4 + ...viderOrganizationProviderUserRepository.cs | 9 - .../IProviderOrganizationRepository.cs | 2 +- .../Repositories/SqlServer/EventRepository.cs | 21 + ...viderOrganizationProviderUserRepository.cs | 17 - .../ProviderOrganizationRepository.cs | 8 +- .../SqlServer/ProviderRepository.cs | 1 - .../TableStorage/EventRepository.cs | 13 + src/Core/Services/IOrganizationService.cs | 1 + src/Core/Services/IProviderService.cs | 2 +- .../Services/Implementations/EventService.cs | 35 +- .../Implementations/OrganizationService.cs | 2 +- .../NoopProviderService.cs | 2 +- .../Utilities/ServiceCollectionExtensions.cs | 2 - src/Notifications/NotificationsHub.cs | 10 +- src/Sql/Sql.sqlproj | 9 +- .../dbo/Stored Procedures/Event_Create.sql | 8 +- .../Event_ReadPageByProviderId.sql | 23 + ...Event_ReadPageByProviderIdActingUserId.sql | 25 + ...roviderOrganizationProviderUser_Create.sql | 33 - ...derOrganizationProviderUser_DeleteById.sql | 27 - ...viderOrganizationProviderUser_ReadById.sql | 13 - ...roviderOrganizationProviderUser_Update.sql | 26 - .../ProviderOrganization_Create.sql | 2 +- ...viderOrganization_ReadByOrganizationId.sql | 13 + .../ProviderOrganization_ReadByUserId.sql | 17 - .../Stored Procedures/ProviderUser_Create.sql | 2 +- .../dbo/Stored Procedures/Provider_Create.sql | 2 +- .../User_ReadPublicKeysByProviderUserIds.sql | 1 + src/Sql/dbo/Tables/Event.sql | 2 + .../ProviderOrganizationProviderUser.sql | 12 - ...derUserProviderOrganizationDetailsView.sql | 1 + test/Core.Test/Services/EventServiceTests.cs | 3 + ...rovider.sql => 2021-07-08_00_Provider.sql} | 400 +++-- ...oviderOrganizationProviderUser.Designer.cs | 1480 ++++++++++++++++ ..._RemoveProviderOrganizationProviderUser.cs | 91 + .../DatabaseContextModelSnapshot.cs | 60 +- ...oviderOrganizationProviderUser.Designer.cs | 1489 +++++++++++++++++ ..._RemoveProviderOrganizationProviderUser.cs | 76 + .../DatabaseContextModelSnapshot.cs | 57 +- ...emoveProviderOrganizationProviderUser.psql | Bin 0 -> 674 bytes 74 files changed, 4007 insertions(+), 635 deletions(-) delete mode 100644 src/Core/Enums/Provider/ProviderOrganizationProviderUserType.cs create mode 100644 src/Core/Models/Api/Request/Providers/ProviderUpdateRequestModel.cs delete mode 100644 src/Core/Models/EntityFramework/Provider/ProviderOrganizationProviderUser.cs delete mode 100644 src/Core/Models/Table/Provider/ProviderOrganizationProviderUser.cs delete mode 100644 src/Core/Repositories/EntityFramework/ProviderOrganizationProviderUserRepository.cs create mode 100644 src/Core/Repositories/EntityFramework/Queries/EventReadPageByProviderIdActingUserIdQuery.cs create mode 100644 src/Core/Repositories/EntityFramework/Queries/EventReadPageByProviderIdQuery.cs create mode 100644 src/Core/Repositories/EntityFramework/Queries/ProviderUserOrganizationDetailsViewQuery.cs delete mode 100644 src/Core/Repositories/IProviderOrganizationProviderUserRepository.cs delete mode 100644 src/Core/Repositories/SqlServer/ProviderOrganizationProviderUserRepository.cs create mode 100644 src/Sql/dbo/Stored Procedures/Event_ReadPageByProviderId.sql create mode 100644 src/Sql/dbo/Stored Procedures/Event_ReadPageByProviderIdActingUserId.sql delete mode 100644 src/Sql/dbo/Stored Procedures/ProviderOrganizationProviderUser_Create.sql delete mode 100644 src/Sql/dbo/Stored Procedures/ProviderOrganizationProviderUser_DeleteById.sql delete mode 100644 src/Sql/dbo/Stored Procedures/ProviderOrganizationProviderUser_ReadById.sql delete mode 100644 src/Sql/dbo/Stored Procedures/ProviderOrganizationProviderUser_Update.sql create mode 100644 src/Sql/dbo/Stored Procedures/ProviderOrganization_ReadByOrganizationId.sql delete mode 100644 src/Sql/dbo/Stored Procedures/ProviderOrganization_ReadByUserId.sql delete mode 100644 src/Sql/dbo/Tables/ProviderOrganizationProviderUser.sql rename util/Migrator/DbScripts/{2021-07-02_00_Provider.sql => 2021-07-08_00_Provider.sql} (86%) create mode 100644 util/MySqlMigrations/Migrations/20210709095522_RemoveProviderOrganizationProviderUser.Designer.cs create mode 100644 util/MySqlMigrations/Migrations/20210709095522_RemoveProviderOrganizationProviderUser.cs create mode 100644 util/PostgresMigrations/Migrations/20210709092227_RemoveProviderOrganizationProviderUser.Designer.cs create mode 100644 util/PostgresMigrations/Migrations/20210709092227_RemoveProviderOrganizationProviderUser.cs create mode 100644 util/PostgresMigrations/RemoveProviderOrganizationProviderUser.psql diff --git a/bitwarden_license/src/CommCore/Services/ProviderService.cs b/bitwarden_license/src/CommCore/Services/ProviderService.cs index cc08b210be..ec127b79c8 100644 --- a/bitwarden_license/src/CommCore/Services/ProviderService.cs +++ b/bitwarden_license/src/CommCore/Services/ProviderService.cs @@ -354,13 +354,19 @@ namespace Bit.CommCore.Services public async Task AddOrganization(Guid providerId, Guid organizationId, Guid addingUserId, string key) { + var po = await _providerOrganizationRepository.GetByOrganizationId(organizationId); + if (po != null) + { + throw new BadRequestException("Organization already belongs to a provider."); + } + var providerOrganization = new ProviderOrganization { ProviderId = providerId, OrganizationId = organizationId, Key = key, }; - + await _providerOrganizationRepository.CreateAsync(providerOrganization); } @@ -379,9 +385,23 @@ namespace Bit.CommCore.Services return providerOrganization; } - // TODO: Implement this - public Task RemoveOrganization(Guid providerOrganizationId, Guid removingUserId) => throw new NotImplementedException(); - + public async Task RemoveOrganization(Guid providerId, Guid providerOrganizationId, Guid removingUserId) + { + var providerOrganization = await _providerOrganizationRepository.GetByIdAsync(providerOrganizationId); + + if (providerOrganization == null || providerOrganization.ProviderId != providerId) + { + throw new BadRequestException("Invalid organization"); + } + + if (!await _organizationService.HasConfirmedOwnersExceptAsync(providerOrganization.OrganizationId, new Guid[] {})) + { + throw new BadRequestException("Organization needs to have at least one confirmed owner"); + } + + await _providerOrganizationRepository.DeleteAsync(providerOrganization); + } + private async Task SendInviteAsync(ProviderUser providerUser, Provider provider) { var nowMillis = CoreHelpers.ToEpocMilliseconds(DateTime.UtcNow); diff --git a/bitwarden_license/src/Portal/EnterprisePortalCurrentContext.cs b/bitwarden_license/src/Portal/EnterprisePortalCurrentContext.cs index e417e6538b..57914c7e9b 100644 --- a/bitwarden_license/src/Portal/EnterprisePortalCurrentContext.cs +++ b/bitwarden_license/src/Portal/EnterprisePortalCurrentContext.cs @@ -15,8 +15,8 @@ namespace Bit.Portal { private readonly IServiceProvider _serviceProvider; - public EnterprisePortalCurrentContext(IProviderOrganizationRepository providerOrganizationRepository, - IServiceProvider serviceProvider) : base(providerOrganizationRepository) + public EnterprisePortalCurrentContext(IProviderUserRepository providerUserRepository, + IServiceProvider serviceProvider) : base(providerUserRepository) { _serviceProvider = serviceProvider; } diff --git a/src/Api/Controllers/EventsController.cs b/src/Api/Controllers/EventsController.cs index 3caa65237c..8c6de4a11a 100644 --- a/src/Api/Controllers/EventsController.cs +++ b/src/Api/Controllers/EventsController.cs @@ -19,6 +19,7 @@ namespace Bit.Api.Controllers private readonly IUserService _userService; private readonly ICipherRepository _cipherRepository; private readonly IOrganizationUserRepository _organizationUserRepository; + private readonly IProviderUserRepository _providerUserRepository; private readonly IEventRepository _eventRepository; private readonly ICurrentContext _currentContext; @@ -26,12 +27,14 @@ namespace Bit.Api.Controllers IUserService userService, ICipherRepository cipherRepository, IOrganizationUserRepository organizationUserRepository, + IProviderUserRepository providerUserRepository, IEventRepository eventRepository, ICurrentContext currentContext) { _userService = userService; _cipherRepository = cipherRepository; _organizationUserRepository = organizationUserRepository; + _providerUserRepository = providerUserRepository; _eventRepository = eventRepository; _currentContext = currentContext; } @@ -117,6 +120,41 @@ namespace Bit.Api.Controllers return new ListResponseModel(responses, result.ContinuationToken); } + [HttpGet("~/providers/{providerId:guid}/events")] + public async Task> GetProvider(Guid providerId, + [FromQuery]DateTime? start = null, [FromQuery]DateTime? end = null, [FromQuery]string continuationToken = null) + { + if (!_currentContext.ProviderAccessEventLogs(providerId)) + { + throw new NotFoundException(); + } + + var dateRange = GetDateRange(start, end); + var result = await _eventRepository.GetManyByProviderAsync(providerId, dateRange.Item1, dateRange.Item2, + new PageOptions { ContinuationToken = continuationToken }); + var responses = result.Data.Select(e => new EventResponseModel(e)); + return new ListResponseModel(responses, result.ContinuationToken); + } + + [HttpGet("~/providers/{providerId:guid}/users/{id:guid}/events")] + public async Task> GetProviderUser(Guid providerId, Guid id, + [FromQuery]DateTime? start = null, [FromQuery]DateTime? end = null, [FromQuery]string continuationToken = null) + { + var providerUser = await _providerUserRepository.GetByIdAsync(id); + if (providerUser == null || !providerUser.UserId.HasValue || + !_currentContext.ProviderAccessEventLogs(providerUser.ProviderId)) + { + throw new NotFoundException(); + } + + var dateRange = GetDateRange(start, end); + var result = await _eventRepository.GetManyByProviderActingUserAsync(providerUser.ProviderId, + providerUser.UserId.Value, dateRange.Item1, dateRange.Item2, + new PageOptions { ContinuationToken = continuationToken }); + var responses = result.Data.Select(e => new EventResponseModel(e)); + return new ListResponseModel(responses, result.ContinuationToken); + } + private Tuple GetDateRange(DateTime? start, DateTime? end) { if (!end.HasValue || !start.HasValue) diff --git a/src/Api/Controllers/ProviderOrganizationsController.cs b/src/Api/Controllers/ProviderOrganizationsController.cs index 227d48e3b7..6ae6711117 100644 --- a/src/Api/Controllers/ProviderOrganizationsController.cs +++ b/src/Api/Controllers/ProviderOrganizationsController.cs @@ -79,5 +79,18 @@ namespace Bit.Api.Controllers var result = await _providerService.CreateOrganizationAsync(providerId, organizationSignup, user); return new ProviderOrganizationResponseModel(result); } + + [HttpDelete("{id:guid}")] + [HttpPost("{id:guid}/delete")] + public async Task Delete(Guid providerId, Guid id) + { + if (!_currentContext.ManageProviderOrganizations(providerId)) + { + throw new NotFoundException(); + } + + var userId = _userService.GetProperUserId(User); + await _providerService.RemoveOrganization(providerId, id, userId.Value); + } } } diff --git a/src/Api/Controllers/ProviderUsersController.cs b/src/Api/Controllers/ProviderUsersController.cs index 07a0824bf5..5da6a3bc18 100644 --- a/src/Api/Controllers/ProviderUsersController.cs +++ b/src/Api/Controllers/ProviderUsersController.cs @@ -38,7 +38,7 @@ namespace Bit.Api.Controllers public async Task Get(Guid providerId, Guid id) { var providerUser = await _providerUserRepository.GetByIdAsync(id); - if (providerUser == null || !_currentContext.ManageProviderUsers(providerUser.ProviderId)) + if (providerUser == null || !_currentContext.ProviderManageUsers(providerUser.ProviderId)) { throw new NotFoundException(); } @@ -49,7 +49,7 @@ namespace Bit.Api.Controllers [HttpGet("")] public async Task> Get(Guid providerId) { - if (!_currentContext.ManageProviderUsers(providerId)) + if (!_currentContext.ProviderManageUsers(providerId)) { throw new NotFoundException(); } @@ -62,7 +62,7 @@ namespace Bit.Api.Controllers [HttpPost("invite")] public async Task Invite(Guid providerId, [FromBody]ProviderUserInviteRequestModel model) { - if (!_currentContext.ManageProviderUsers(providerId)) + if (!_currentContext.ProviderManageUsers(providerId)) { throw new NotFoundException(); } @@ -74,7 +74,7 @@ namespace Bit.Api.Controllers [HttpPost("reinvite")] public async Task> BulkReinvite(Guid providerId, [FromBody]ProviderUserBulkRequestModel model) { - if (!_currentContext.ManageProviderUsers(providerId)) + if (!_currentContext.ProviderManageUsers(providerId)) { throw new NotFoundException(); } @@ -88,7 +88,7 @@ namespace Bit.Api.Controllers [HttpPost("{id:guid}/reinvite")] public async Task Reinvite(Guid providerId, Guid id) { - if (!_currentContext.ManageProviderUsers(providerId)) + if (!_currentContext.ProviderManageUsers(providerId)) { throw new NotFoundException(); } @@ -112,7 +112,7 @@ namespace Bit.Api.Controllers [HttpPost("{id:guid}/confirm")] public async Task Confirm(Guid providerId, Guid id, [FromBody]ProviderUserConfirmRequestModel model) { - if (!_currentContext.ManageProviderUsers(providerId)) + if (!_currentContext.ProviderManageUsers(providerId)) { throw new NotFoundException(); } @@ -125,7 +125,7 @@ namespace Bit.Api.Controllers public async Task> BulkConfirm(Guid providerId, [FromBody]ProviderUserBulkConfirmRequestModel model) { - if (!_currentContext.ManageProviderUsers(providerId)) + if (!_currentContext.ProviderManageUsers(providerId)) { throw new NotFoundException(); } @@ -140,13 +140,13 @@ namespace Bit.Api.Controllers [HttpPost("public-keys")] public async Task> UserPublicKeys(Guid providerId, [FromBody]ProviderUserBulkRequestModel model) { - if (!_currentContext.ManageProviderUsers(providerId)) + if (!_currentContext.ProviderManageUsers(providerId)) { throw new NotFoundException(); } var result = await _providerUserRepository.GetManyPublicKeysByProviderUserAsync(providerId, model.Ids); - var responses = result.Select(r => new ProviderUserPublicKeyResponseModel(r.Id, r.PublicKey)).ToList(); + var responses = result.Select(r => new ProviderUserPublicKeyResponseModel(r.Id, r.UserId, r.PublicKey)).ToList(); return new ListResponseModel(responses); } @@ -154,7 +154,7 @@ namespace Bit.Api.Controllers [HttpPost("{id:guid}")] public async Task Put(Guid providerId, Guid id, [FromBody]ProviderUserUpdateRequestModel model) { - if (!_currentContext.ManageProviderUsers(providerId)) + if (!_currentContext.ProviderManageUsers(providerId)) { throw new NotFoundException(); } @@ -173,7 +173,7 @@ namespace Bit.Api.Controllers [HttpPost("{id:guid}/delete")] public async Task Delete(Guid providerId, Guid id) { - if (!_currentContext.ManageProviderUsers(providerId)) + if (!_currentContext.ProviderManageUsers(providerId)) { throw new NotFoundException(); } @@ -186,7 +186,7 @@ namespace Bit.Api.Controllers [HttpPost("delete")] public async Task> BulkDelete(Guid providerId, [FromBody]ProviderUserBulkRequestModel model) { - if (!_currentContext.ManageProviderUsers(providerId)) + if (!_currentContext.ProviderManageUsers(providerId)) { throw new NotFoundException(); } diff --git a/src/Api/Controllers/ProvidersController.cs b/src/Api/Controllers/ProvidersController.cs index 9f4eb4d92c..d0d9061e1e 100644 --- a/src/Api/Controllers/ProvidersController.cs +++ b/src/Api/Controllers/ProvidersController.cs @@ -5,6 +5,7 @@ using Bit.Core.Exceptions; using Bit.Core.Models.Api; using Bit.Core.Repositories; using Bit.Core.Services; +using Bit.Core.Settings; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; @@ -18,14 +19,16 @@ namespace Bit.Api.Controllers private readonly IProviderRepository _providerRepository; private readonly IProviderService _providerService; private readonly ICurrentContext _currentContext; + private readonly GlobalSettings _globalSettings; public ProvidersController(IUserService userService, IProviderRepository providerRepository, - IProviderService providerService, ICurrentContext currentContext) + IProviderService providerService, ICurrentContext currentContext, GlobalSettings globalSettings) { _userService = userService; _providerRepository = providerRepository; _providerService = providerService; _currentContext = currentContext; + _globalSettings = globalSettings; } [HttpGet("{id:guid}")] @@ -45,6 +48,25 @@ namespace Bit.Api.Controllers return new ProviderResponseModel(provider); } + [HttpPut("{id:guid}")] + [HttpPost("{id:guid}")] + public async Task Put(Guid id, [FromBody]ProviderUpdateRequestModel model) + { + if (!_currentContext.ProviderProviderAdmin(id)) + { + throw new NotFoundException(); + } + + var provider = await _providerRepository.GetByIdAsync(id); + if (provider == null) + { + throw new NotFoundException(); + } + + await _providerService.UpdateAsync(model.ToProvider(provider, _globalSettings)); + return new ProviderResponseModel(provider); + } + [HttpPost("{id:guid}/setup")] public async Task Setup(Guid id, [FromBody]ProviderSetupRequestModel model) { diff --git a/src/Core/Context/CurrentContext.cs b/src/Core/Context/CurrentContext.cs index bc27135be5..928c622ebf 100644 --- a/src/Core/Context/CurrentContext.cs +++ b/src/Core/Context/CurrentContext.cs @@ -12,15 +12,16 @@ using Bit.Core.Utilities; using Bit.Core.Models.Data; using Bit.Core.Models.Table.Provider; using Bit.Core.Settings; +using Microsoft.EntityFrameworkCore.Internal; namespace Bit.Core.Context { public class CurrentContext : ICurrentContext { - private readonly IProviderOrganizationRepository _providerOrganizationRepository; + private readonly IProviderUserRepository _providerUserRepository; private bool _builtHttpContext; private bool _builtClaimsPrincipal; - private ICollection _providerOrganizations; + private IEnumerable _providerUserOrganizations; public virtual HttpContext HttpContext { get; set; } public virtual Guid? UserId { get; set; } @@ -37,9 +38,9 @@ namespace Bit.Core.Context public virtual bool MaybeBot { get; set; } public virtual int? BotScore { get; set; } - public CurrentContext(IProviderOrganizationRepository providerOrganizationRepository) + public CurrentContext(IProviderUserRepository providerUserRepository) { - _providerOrganizationRepository = providerOrganizationRepository; + _providerUserRepository = providerUserRepository; } public async virtual Task BuildAsync(HttpContext httpContext, GlobalSettings globalSettings) @@ -343,7 +344,12 @@ namespace Bit.Core.Context return Providers?.Any(o => o.Id == providerId && o.Type == ProviderUserType.ProviderAdmin) ?? false; } - public bool ManageProviderUsers(Guid providerId) + public bool ProviderManageUsers(Guid providerId) + { + return ProviderProviderAdmin(providerId); + } + + public bool ProviderAccessEventLogs(Guid providerId) { return ProviderProviderAdmin(providerId); } @@ -363,6 +369,19 @@ namespace Bit.Core.Context return Providers?.Any(o => o.Id == providerId) ?? false; } + public async Task ProviderIdForOrg(Guid orgId) + { + if (Organizations.Any(org => org.Id == orgId)) + { + return null; + } + + var po = (await GetProviderOrganizations()) + .FirstOrDefault(po => po.OrganizationId == orgId); + + return po?.ProviderId; + } + public async Task> OrganizationMembershipAsync( IOrganizationUserRepository organizationUserRepository, Guid userId) { @@ -421,14 +440,14 @@ namespace Bit.Core.Context }; } - private async Task> GetProviderOrganizations() + private async Task> GetProviderOrganizations() { - if (_providerOrganizations == null) + if (_providerUserOrganizations == null) { - _providerOrganizations = await _providerOrganizationRepository.GetManyByUserIdAsync(UserId.Value); + _providerUserOrganizations = await _providerUserRepository.GetManyOrganizationDetailsByUserAsync(UserId.Value, ProviderUserStatusType.Confirmed); } - return _providerOrganizations; + return _providerUserOrganizations; } } } diff --git a/src/Core/Context/ICurrentContext.cs b/src/Core/Context/ICurrentContext.cs index b1dac61b0a..1479fea630 100644 --- a/src/Core/Context/ICurrentContext.cs +++ b/src/Core/Context/ICurrentContext.cs @@ -49,7 +49,8 @@ namespace Bit.Core.Context Task ManageResetPassword(Guid orgId); bool ProviderProviderAdmin(Guid providerId); bool ProviderUser(Guid providerId); - bool ManageProviderUsers(Guid providerId); + bool ProviderManageUsers(Guid providerId); + bool ProviderAccessEventLogs(Guid providerId); bool AccessProviderOrganizations(Guid providerId); bool ManageProviderOrganizations(Guid providerId); @@ -58,5 +59,7 @@ namespace Bit.Core.Context Task> ProviderMembershipAsync( IProviderUserRepository providerUserRepository, Guid userId); + + Task ProviderIdForOrg(Guid orgId); } } diff --git a/src/Core/Enums/Provider/ProviderOrganizationProviderUserType.cs b/src/Core/Enums/Provider/ProviderOrganizationProviderUserType.cs deleted file mode 100644 index b3ef442f45..0000000000 --- a/src/Core/Enums/Provider/ProviderOrganizationProviderUserType.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Bit.Core.Enums.Provider -{ - public enum ProviderOrganizationProviderUserType : byte - { - Administrator = 0, - ServiceAdmin = 1, - } -} diff --git a/src/Core/Models/Api/Request/Providers/ProviderUpdateRequestModel.cs b/src/Core/Models/Api/Request/Providers/ProviderUpdateRequestModel.cs new file mode 100644 index 0000000000..4b4ee5a60c --- /dev/null +++ b/src/Core/Models/Api/Request/Providers/ProviderUpdateRequestModel.cs @@ -0,0 +1,31 @@ +using Bit.Core.Settings; +using System.ComponentModel.DataAnnotations; +using Bit.Core.Models.Table.Provider; + +namespace Bit.Core.Models.Api +{ + public class ProviderUpdateRequestModel + { + [Required] + [StringLength(50)] + public string Name { get; set; } + [StringLength(50)] + public string BusinessName { get; set; } + [EmailAddress] + [Required] + [StringLength(256)] + public string BillingEmail { get; set; } + + public virtual Provider ToProvider(Provider existingProvider, GlobalSettings globalSettings) + { + if (!globalSettings.SelfHosted) + { + // These items come from the license file + existingProvider.Name = Name; + existingProvider.BusinessName = BusinessName; + existingProvider.BillingEmail = BillingEmail?.ToLowerInvariant()?.Trim(); + } + return existingProvider; + } + } +} diff --git a/src/Core/Models/Api/Response/EventResponseModel.cs b/src/Core/Models/Api/Response/EventResponseModel.cs index 87802ce808..768455dc90 100644 --- a/src/Core/Models/Api/Response/EventResponseModel.cs +++ b/src/Core/Models/Api/Response/EventResponseModel.cs @@ -17,11 +17,13 @@ namespace Bit.Core.Models.Api Type = ev.Type; UserId = ev.UserId; OrganizationId = ev.OrganizationId; + ProviderId = ev.ProviderId; CipherId = ev.CipherId; CollectionId = ev.CollectionId; GroupId = ev.GroupId; PolicyId = ev.PolicyId; OrganizationUserId = ev.OrganizationUserId; + ProviderUserId = ev.ProviderUserId; ActingUserId = ev.ActingUserId; Date = ev.Date; DeviceType = ev.DeviceType; @@ -31,11 +33,13 @@ namespace Bit.Core.Models.Api public EventType Type { get; set; } public Guid? UserId { get; set; } public Guid? OrganizationId { get; set; } + public Guid? ProviderId { get; set; } public Guid? CipherId { get; set; } public Guid? CollectionId { get; set; } public Guid? GroupId { get; set; } public Guid? PolicyId { get; set; } public Guid? OrganizationUserId { get; set; } + public Guid? ProviderUserId { get; set; } public Guid? ActingUserId { get; set; } public DateTime Date { get; set; } public DeviceType? DeviceType { get; set; } diff --git a/src/Core/Models/Api/Response/ProfileOrganizationResponseModel.cs b/src/Core/Models/Api/Response/ProfileOrganizationResponseModel.cs index b3728e812a..8cf083da50 100644 --- a/src/Core/Models/Api/Response/ProfileOrganizationResponseModel.cs +++ b/src/Core/Models/Api/Response/ProfileOrganizationResponseModel.cs @@ -1,12 +1,14 @@ using Bit.Core.Enums; using Bit.Core.Models.Data; using Bit.Core.Utilities; + namespace Bit.Core.Models.Api { public class ProfileOrganizationResponseModel : ResponseModel { - public ProfileOrganizationResponseModel(OrganizationUserOrganizationDetails organization) - : base("profileOrganization") + public ProfileOrganizationResponseModel(string str) : base(str) {} + + public ProfileOrganizationResponseModel(OrganizationUserOrganizationDetails organization) : this("profileOrganization") { Id = organization.OrganizationId.ToString(); Name = organization.Name; diff --git a/src/Core/Models/Api/Response/ProfileProviderOrganizationResponseModel.cs b/src/Core/Models/Api/Response/ProfileProviderOrganizationResponseModel.cs index 8be2db86e3..c877fc6352 100644 --- a/src/Core/Models/Api/Response/ProfileProviderOrganizationResponseModel.cs +++ b/src/Core/Models/Api/Response/ProfileProviderOrganizationResponseModel.cs @@ -1,10 +1,9 @@ using Bit.Core.Enums; using Bit.Core.Models.Data; -using Bit.Core.Utilities; namespace Bit.Core.Models.Api { - public class ProfileProviderOrganizationResponseModel : ResponseModel + public class ProfileProviderOrganizationResponseModel : ProfileOrganizationResponseModel { public ProfileProviderOrganizationResponseModel(ProviderUserOrganizationDetails organization) : base("profileProviderOrganization") @@ -27,46 +26,16 @@ namespace Bit.Core.Models.Api MaxStorageGb = organization.MaxStorageGb; Key = organization.Key; HasPublicAndPrivateKeys = organization.PublicKey != null && organization.PrivateKey != null; - Status = organization.Status; - Type = organization.Type; + Status = OrganizationUserStatusType.Confirmed; // Provider users are always confirmed + Type = OrganizationUserType.Owner; // Provider users behave like Owners Enabled = organization.Enabled; - SsoBound = !string.IsNullOrWhiteSpace(organization.SsoExternalId); + SsoBound = false; Identifier = organization.Identifier; - Permissions = CoreHelpers.LoadClassFromJsonData(organization.Permissions); - ResetPasswordEnrolled = organization.ResetPasswordKey != null; + Permissions = new Permissions(); + ResetPasswordEnrolled = false; UserId = organization.UserId?.ToString(); ProviderId = organization.ProviderId?.ToString(); ProviderName = organization.ProviderName; } - - public string Id { get; set; } - public string Name { get; set; } - public bool UsePolicies { get; set; } - public bool UseSso { get; set; } - public bool UseGroups { get; set; } - public bool UseDirectory { get; set; } - public bool UseEvents { get; set; } - public bool UseTotp { get; set; } - public bool Use2fa { get; set; } - public bool UseApi { get; set; } - public bool UseResetPassword { get; set; } - public bool UseBusinessPortal => UsePolicies || UseSso; // TODO add events if needed - public bool UsersGetPremium { get; set; } - public bool SelfHost { get; set; } - public int Seats { get; set; } - public int MaxCollections { get; set; } - public short? MaxStorageGb { get; set; } - public string Key { get; set; } - public OrganizationUserStatusType Status { get; set; } - public OrganizationUserType Type { get; set; } - public bool Enabled { get; set; } - public bool SsoBound { get; set; } - public string Identifier { get; set; } - public Permissions Permissions { get; set; } - public bool ResetPasswordEnrolled { get; set; } - public string UserId { get; set; } - public bool HasPublicAndPrivateKeys { get; set; } - public string ProviderId { get; set; } - public string ProviderName { get; set; } } } diff --git a/src/Core/Models/Api/Response/Providers/ProviderUserResponseModel.cs b/src/Core/Models/Api/Response/Providers/ProviderUserResponseModel.cs index df81b14670..f8125dbaf6 100644 --- a/src/Core/Models/Api/Response/Providers/ProviderUserResponseModel.cs +++ b/src/Core/Models/Api/Response/Providers/ProviderUserResponseModel.cs @@ -65,14 +65,16 @@ namespace Bit.Core.Models.Api public class ProviderUserPublicKeyResponseModel : ResponseModel { - public ProviderUserPublicKeyResponseModel(Guid id, string key, + public ProviderUserPublicKeyResponseModel(Guid id, Guid userId, string key, string obj = "providerUserPublicKeyResponseModel") : base(obj) { Id = id; + UserId = userId; Key = key; } public Guid Id { get; set; } + public Guid UserId { get; set; } public string Key { get; set; } } diff --git a/src/Core/Models/Data/EventTableEntity.cs b/src/Core/Models/Data/EventTableEntity.cs index f881e1cdf9..85de9859e1 100644 --- a/src/Core/Models/Data/EventTableEntity.cs +++ b/src/Core/Models/Data/EventTableEntity.cs @@ -16,11 +16,13 @@ namespace Bit.Core.Models.Data Type = e.Type; UserId = e.UserId; OrganizationId = e.OrganizationId; + ProviderId = e.ProviderId; CipherId = e.CipherId; CollectionId = e.CollectionId; PolicyId = e.PolicyId; GroupId = e.GroupId; OrganizationUserId = e.OrganizationUserId; + ProviderUserId = e.ProviderUserId; DeviceType = e.DeviceType; IpAddress = e.IpAddress; ActingUserId = e.ActingUserId; @@ -30,11 +32,13 @@ namespace Bit.Core.Models.Data public EventType Type { get; set; } public Guid? UserId { get; set; } public Guid? OrganizationId { get; set; } + public Guid? ProviderId { get; set; } public Guid? CipherId { get; set; } public Guid? CollectionId { get; set; } public Guid? PolicyId { get; set; } public Guid? GroupId { get; set; } public Guid? OrganizationUserId { get; set; } + public Guid? ProviderUserId { get; set; } public DeviceType? DeviceType { get; set; } public string IpAddress { get; set; } public Guid? ActingUserId { get; set; } @@ -87,7 +91,9 @@ namespace Bit.Core.Models.Data public static List IndexEvent(EventMessage e) { var uniquifier = e.IdempotencyId.GetValueOrDefault(Guid.NewGuid()); - var pKey = e.OrganizationId.HasValue ? $"OrganizationId={e.OrganizationId}" : $"UserId={e.UserId}"; + + var pKey = GetPartitionKey(e); + var dateKey = CoreHelpers.DateTimeToTableStorageKey(e.Date); var entities = new List @@ -95,7 +101,7 @@ namespace Bit.Core.Models.Data new EventTableEntity(e) { PartitionKey = pKey, - RowKey = string.Format("Date={0}__Uniquifier={1}", dateKey, uniquifier) + RowKey = $"Date={dateKey}__Uniquifier={uniquifier}" } }; @@ -104,8 +110,16 @@ namespace Bit.Core.Models.Data entities.Add(new EventTableEntity(e) { PartitionKey = pKey, - RowKey = string.Format("ActingUserId={0}__Date={1}__Uniquifier={2}", - e.ActingUserId, dateKey, uniquifier) + RowKey = $"ActingUserId={e.ActingUserId}__Date={dateKey}__Uniquifier={uniquifier}" + }); + } + + if (!e.OrganizationId.HasValue && e.ProviderId.HasValue && e.ActingUserId.HasValue) + { + entities.Add(new EventTableEntity(e) + { + PartitionKey = pKey, + RowKey = $"ActingUserId={e.ActingUserId}__Date={dateKey}__Uniquifier={uniquifier}" }); } @@ -114,12 +128,26 @@ namespace Bit.Core.Models.Data entities.Add(new EventTableEntity(e) { PartitionKey = pKey, - RowKey = string.Format("CipherId={0}__Date={1}__Uniquifier={2}", - e.CipherId, dateKey, uniquifier) + RowKey = $"CipherId={e.CipherId}__Date={dateKey}__Uniquifier={uniquifier}" }); } return entities; } + + private static string GetPartitionKey(EventMessage e) + { + if (e.OrganizationId.HasValue) + { + return $"OrganizationId={e.OrganizationId}"; + } + + if (e.ProviderId.HasValue) + { + return $"ProviderId={e.ProviderId}"; + } + + return $"UserId={e.UserId}"; + } } } diff --git a/src/Core/Models/Data/IEvent.cs b/src/Core/Models/Data/IEvent.cs index 8d8204c1a8..ba5a02276c 100644 --- a/src/Core/Models/Data/IEvent.cs +++ b/src/Core/Models/Data/IEvent.cs @@ -8,11 +8,13 @@ namespace Bit.Core.Models.Data EventType Type { get; set; } Guid? UserId { get; set; } Guid? OrganizationId { get; set; } + Guid? ProviderId { get; set; } Guid? CipherId { get; set; } Guid? CollectionId { get; set; } Guid? GroupId { get; set; } Guid? PolicyId { get; set; } Guid? OrganizationUserId { get; set; } + Guid? ProviderUserId { get; set; } Guid? ActingUserId { get; set; } DeviceType? DeviceType { get; set; } string IpAddress { get; set; } diff --git a/src/Core/Models/Data/Provider/ProviderUserOrganizationDetails.cs b/src/Core/Models/Data/Provider/ProviderUserOrganizationDetails.cs index f7f71f86ae..51e2bc96d5 100644 --- a/src/Core/Models/Data/Provider/ProviderUserOrganizationDetails.cs +++ b/src/Core/Models/Data/Provider/ProviderUserOrganizationDetails.cs @@ -1,4 +1,5 @@ using System; +using Bit.Core.Enums.Provider; namespace Bit.Core.Models.Data { @@ -19,20 +20,18 @@ namespace Bit.Core.Models.Data public bool UseBusinessPortal => UsePolicies || UseSso; public bool SelfHost { get; set; } public bool UsersGetPremium { get; set; } - public int Seats { get; set; } - public int MaxCollections { get; set; } + public int? Seats { get; set; } + public short? MaxCollections { get; set; } public short? MaxStorageGb { get; set; } public string Key { get; set; } - public Enums.OrganizationUserStatusType Status { get; set; } - public Enums.OrganizationUserType Type { get; set; } + public ProviderUserStatusType Status { get; set; } + public ProviderUserType Type { get; set; } public bool Enabled { get; set; } - public string SsoExternalId { get; set; } public string Identifier { get; set; } - public string Permissions { get; set; } - public string ResetPasswordKey { get; set; } public string PublicKey { get; set; } public string PrivateKey { get; set; } public Guid? ProviderId { get; set; } + public Guid? ProviderUserId { get; set; } public string ProviderName { get; set; } } } diff --git a/src/Core/Models/Data/Provider/ProviderUserPublicKey.cs b/src/Core/Models/Data/Provider/ProviderUserPublicKey.cs index 29bc305204..93d3346b6c 100644 --- a/src/Core/Models/Data/Provider/ProviderUserPublicKey.cs +++ b/src/Core/Models/Data/Provider/ProviderUserPublicKey.cs @@ -5,6 +5,7 @@ namespace Bit.Core.Models.Data public class ProviderUserPublicKey { public Guid Id { get; set; } + public Guid UserId { get; set; } public string PublicKey { get; set; } } } diff --git a/src/Core/Models/EntityFramework/Event.cs b/src/Core/Models/EntityFramework/Event.cs index 3e9faa2bc7..db66f3330b 100644 --- a/src/Core/Models/EntityFramework/Event.cs +++ b/src/Core/Models/EntityFramework/Event.cs @@ -1,5 +1,3 @@ -using System.Collections.Generic; -using System.Text.Json; using AutoMapper; namespace Bit.Core.Models.EntityFramework diff --git a/src/Core/Models/EntityFramework/Provider/ProviderOrganizationProviderUser.cs b/src/Core/Models/EntityFramework/Provider/ProviderOrganizationProviderUser.cs deleted file mode 100644 index 70db4fb7ed..0000000000 --- a/src/Core/Models/EntityFramework/Provider/ProviderOrganizationProviderUser.cs +++ /dev/null @@ -1,18 +0,0 @@ -using AutoMapper; - -namespace Bit.Core.Models.EntityFramework.Provider -{ - public class ProviderOrganizationProviderUser : Table.Provider.ProviderOrganizationProviderUser - { - public virtual ProviderOrganization ProviderOrganization { get; set; } - public virtual ProviderUser ProviderUser { get; set; } - } - - public class ProviderOrganizationProviderUserMapperProfile : Profile - { - public ProviderOrganizationProviderUserMapperProfile() - { - CreateMap().ReverseMap(); - } - } -} diff --git a/src/Core/Models/Table/Event.cs b/src/Core/Models/Table/Event.cs index eb68289fb8..165b5427cf 100644 --- a/src/Core/Models/Table/Event.cs +++ b/src/Core/Models/Table/Event.cs @@ -16,11 +16,13 @@ namespace Bit.Core.Models.Table Type = e.Type; UserId = e.UserId; OrganizationId = e.OrganizationId; + ProviderId = e.ProviderId; CipherId = e.CipherId; CollectionId = e.CollectionId; PolicyId = e.PolicyId; GroupId = e.GroupId; OrganizationUserId = e.OrganizationUserId; + ProviderUserId = e.ProviderUserId; DeviceType = e.DeviceType; IpAddress = e.IpAddress; ActingUserId = e.ActingUserId; @@ -31,11 +33,13 @@ namespace Bit.Core.Models.Table public EventType Type { get; set; } public Guid? UserId { get; set; } public Guid? OrganizationId { get; set; } + public Guid? ProviderId { get; set; } public Guid? CipherId { get; set; } public Guid? CollectionId { get; set; } public Guid? PolicyId { get; set; } public Guid? GroupId { get; set; } public Guid? OrganizationUserId { get; set; } + public Guid? ProviderUserId { get; set; } public DeviceType? DeviceType { get; set; } [MaxLength(50)] public string IpAddress { get; set; } diff --git a/src/Core/Models/Table/Provider/ProviderOrganizationProviderUser.cs b/src/Core/Models/Table/Provider/ProviderOrganizationProviderUser.cs deleted file mode 100644 index 1872d7b004..0000000000 --- a/src/Core/Models/Table/Provider/ProviderOrganizationProviderUser.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using Bit.Core.Enums.Provider; -using Bit.Core.Utilities; - -namespace Bit.Core.Models.Table.Provider -{ - public class ProviderOrganizationProviderUser : ITableObject - { - public Guid Id { get; set; } - public Guid ProviderOrganizationId { get; set; } - public Guid ProviderUserId { get; set; } - public ProviderOrganizationProviderUserType Type { get; set; } - public string Permissions { get; set; } - public DateTime CreationDate { get; internal set; } = DateTime.UtcNow; - public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow; - - public void SetNewId() - { - if (Id == default) - { - Id = CoreHelpers.GenerateComb(); - } - } - } -} diff --git a/src/Core/Repositories/EntityFramework/DatabaseContext.cs b/src/Core/Repositories/EntityFramework/DatabaseContext.cs index c0940d330b..fcc8275f99 100644 --- a/src/Core/Repositories/EntityFramework/DatabaseContext.cs +++ b/src/Core/Repositories/EntityFramework/DatabaseContext.cs @@ -31,7 +31,6 @@ namespace Bit.Core.Repositories.EntityFramework public DbSet Providers { get; set; } public DbSet ProviderUsers { get; set; } public DbSet ProviderOrganizations { get; set; } - public DbSet ProviderOrganizationProviderUsers { get; set; } public DbSet Sends { get; set; } public DbSet SsoConfigs { get; set; } public DbSet SsoUsers { get; set; } @@ -61,7 +60,6 @@ namespace Bit.Core.Repositories.EntityFramework var eProvider = builder.Entity(); var eProviderUser = builder.Entity(); var eProviderOrganization = builder.Entity(); - var eProviderOrganizationProviderUser = builder.Entity(); var eSend = builder.Entity(); var eSsoConfig = builder.Entity(); var eSsoUser = builder.Entity(); @@ -83,7 +81,6 @@ namespace Bit.Core.Repositories.EntityFramework eProvider.Property(c => c.Id).ValueGeneratedNever(); eProviderUser.Property(c => c.Id).ValueGeneratedNever(); eProviderOrganization.Property(c => c.Id).ValueGeneratedNever(); - eProviderOrganizationProviderUser.Property(c => c.Id).ValueGeneratedNever(); eSend.Property(c => c.Id).ValueGeneratedNever(); eTransaction.Property(c => c.Id).ValueGeneratedNever(); eUser.Property(c => c.Id).ValueGeneratedNever(); @@ -123,7 +120,6 @@ namespace Bit.Core.Repositories.EntityFramework eProvider.ToTable(nameof(Provider)); eProviderUser.ToTable(nameof(ProviderUser)); eProviderOrganization.ToTable(nameof(ProviderOrganization)); - eProviderOrganizationProviderUser.ToTable(nameof(ProviderOrganizationProviderUser)); eSend.ToTable(nameof(Send)); eSsoConfig.ToTable(nameof(SsoConfig)); eSsoUser.ToTable(nameof(SsoUser)); diff --git a/src/Core/Repositories/EntityFramework/EventRepository.cs b/src/Core/Repositories/EntityFramework/EventRepository.cs index bff7843b87..34cfba4fe7 100644 --- a/src/Core/Repositories/EntityFramework/EventRepository.cs +++ b/src/Core/Repositories/EntityFramework/EventRepository.cs @@ -49,6 +49,7 @@ namespace Bit.Core.Repositories.EntityFramework var dbContext = GetDatabaseContext(scope); var tableEvents = entities.Select(e => e as Event ?? new Event(e)); var entityEvents = Mapper.Map>(tableEvents); + entityEvents.ForEach(e => e.SetNewId()); await dbContext.BulkCopyAsync(entityEvents); } } @@ -103,6 +104,57 @@ namespace Bit.Core.Repositories.EntityFramework } } + public async Task> GetManyByProviderAsync(Guid providerId, DateTime startDate, DateTime endDate, PageOptions pageOptions) + { + DateTime? beforeDate = null; + if (!string.IsNullOrWhiteSpace(pageOptions.ContinuationToken) && + long.TryParse(pageOptions.ContinuationToken, out var binaryDate)) + { + beforeDate = DateTime.SpecifyKind(DateTime.FromBinary(binaryDate), DateTimeKind.Utc); + } + using (var scope = ServiceScopeFactory.CreateScope()) + { + var dbContext = GetDatabaseContext(scope); + var query = new EventReadPageByProviderIdQuery(providerId, startDate, + endDate, beforeDate, pageOptions); + var events = await query.Run(dbContext).ToListAsync(); + + var result = new PagedResult(); + if (events.Any() && events.Count >= pageOptions.PageSize) + { + result.ContinuationToken = events.Last().Date.ToBinary().ToString(); + } + result.Data.AddRange(events); + return result; + } + } + + public async Task> GetManyByProviderActingUserAsync(Guid providerId, Guid actingUserId, + DateTime startDate, DateTime endDate, PageOptions pageOptions) + { + DateTime? beforeDate = null; + if (!string.IsNullOrWhiteSpace(pageOptions.ContinuationToken) && + long.TryParse(pageOptions.ContinuationToken, out var binaryDate)) + { + beforeDate = DateTime.SpecifyKind(DateTime.FromBinary(binaryDate), DateTimeKind.Utc); + } + using (var scope = ServiceScopeFactory.CreateScope()) + { + var dbContext = GetDatabaseContext(scope); + var query = new EventReadPageByProviderIdActingUserIdQuery(providerId, actingUserId, + startDate, endDate, beforeDate, pageOptions); + var events = await query.Run(dbContext).ToListAsync(); + + var result = new PagedResult(); + if (events.Any() && events.Count >= pageOptions.PageSize) + { + result.ContinuationToken = events.Last().Date.ToBinary().ToString(); + } + result.Data.AddRange(events); + return result; + } + } + public async Task> GetManyByOrganizationAsync(Guid organizationId, DateTime startDate, DateTime endDate, PageOptions pageOptions) { DateTime? beforeDate = null; diff --git a/src/Core/Repositories/EntityFramework/ProviderOrganizationProviderUserRepository.cs b/src/Core/Repositories/EntityFramework/ProviderOrganizationProviderUserRepository.cs deleted file mode 100644 index a468c4e31c..0000000000 --- a/src/Core/Repositories/EntityFramework/ProviderOrganizationProviderUserRepository.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Bit.Core.Models.Table.Provider; -using Bit.Core.Repositories.EntityFramework; -using TableModel = Bit.Core.Models.Table; -using EfModel = Bit.Core.Models.EntityFramework; -using Microsoft.Extensions.DependencyInjection; -using AutoMapper; - -namespace Bit.Core.Repositories.EntityFramework -{ - public class ProviderOrganizationProviderUserRepository : - Repository, IProviderOrganizationProviderUserRepository - { - public ProviderOrganizationProviderUserRepository(IServiceScopeFactory serviceScopeFactory, IMapper mapper) - : base(serviceScopeFactory, mapper, (DatabaseContext context) => context.ProviderOrganizationProviderUsers) - { } - } -} diff --git a/src/Core/Repositories/EntityFramework/ProviderOrganizationRepository.cs b/src/Core/Repositories/EntityFramework/ProviderOrganizationRepository.cs index 814fbb891f..f4f93f7574 100644 --- a/src/Core/Repositories/EntityFramework/ProviderOrganizationRepository.cs +++ b/src/Core/Repositories/EntityFramework/ProviderOrganizationRepository.cs @@ -1,13 +1,13 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; -using Bit.Core.Models.Table.Provider; -using Bit.Core.Repositories.EntityFramework; +using System.Linq; using TableModel = Bit.Core.Models.Table; using EfModel = Bit.Core.Models.EntityFramework; using Microsoft.Extensions.DependencyInjection; using AutoMapper; using Bit.Core.Models.Data; +using Bit.Core.Models.Table.Provider; using Bit.Core.Repositories.EntityFramework.Queries; using Microsoft.EntityFrameworkCore; @@ -17,14 +17,9 @@ namespace Bit.Core.Repositories.EntityFramework Repository, IProviderOrganizationRepository { public ProviderOrganizationRepository(IServiceScopeFactory serviceScopeFactory, IMapper mapper) - : base(serviceScopeFactory, mapper, (DatabaseContext context) => context.ProviderOrganizations) + : base(serviceScopeFactory, mapper, context => context.ProviderOrganizations) { } - public Task> GetManyByUserIdAsync(Guid userId) - { - throw new NotImplementedException(); - } - public async Task> GetManyDetailsByProviderAsync(Guid providerId) { using (var scope = ServiceScopeFactory.CreateScope()) @@ -35,5 +30,12 @@ namespace Bit.Core.Repositories.EntityFramework return data; } } + + public async Task GetByOrganizationId(Guid organizationId) + { + using var scope = ServiceScopeFactory.CreateScope(); + var dbContext = GetDatabaseContext(scope); + return await GetDbSet(dbContext).Where(po => po.OrganizationId == organizationId).FirstOrDefaultAsync(); + } } } diff --git a/src/Core/Repositories/EntityFramework/ProviderRepository.cs b/src/Core/Repositories/EntityFramework/ProviderRepository.cs index 1cb261ad4c..2603d514f0 100644 --- a/src/Core/Repositories/EntityFramework/ProviderRepository.cs +++ b/src/Core/Repositories/EntityFramework/ProviderRepository.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Bit.Core.Models.Table.Provider; -using Bit.Core.Repositories.EntityFramework; using TableModel = Bit.Core.Models.Table; using EfModel = Bit.Core.Models.EntityFramework; using Microsoft.Extensions.DependencyInjection; @@ -13,15 +12,13 @@ using Bit.Core.Models.Data; namespace Bit.Core.Repositories.EntityFramework { - public class ProviderRepository : Repository, IProviderRepository + public class ProviderRepository : Repository, IProviderRepository { public ProviderRepository(IServiceScopeFactory serviceScopeFactory, IMapper mapper) - : base(serviceScopeFactory, mapper, (DatabaseContext context) => context.Providers) + : base(serviceScopeFactory, mapper, context => context.Providers) { } - public Task> GetManyAbilitiesAsync() => throw new NotImplementedException(); - public async Task> SearchAsync(string name, string userEmail, int skip, int take) { using (var scope = ServiceScopeFactory.CreateScope()) @@ -41,7 +38,23 @@ namespace Bit.Core.Repositories.EntityFramework where string.IsNullOrWhiteSpace(name) || p.Name.Contains(name) orderby p.CreationDate descending select new { p }).Skip(skip).Take(take).Select(x => x.p); - return await query.ToArrayAsync(); + var providers = await query.ToArrayAsync(); + return Mapper.Map>(providers); + } + } + + public async Task> GetManyAbilitiesAsync() + { + using (var scope = ServiceScopeFactory.CreateScope()) + { + var dbContext = GetDatabaseContext(scope); + return await GetDbSet(dbContext) + .Select(e => new ProviderAbility + { + Enabled = e.Enabled, + Id = e.Id, + UseEvents = e.UseEvents, + }).ToListAsync(); } } } diff --git a/src/Core/Repositories/EntityFramework/ProviderUserRepository.cs b/src/Core/Repositories/EntityFramework/ProviderUserRepository.cs index 40f100a33c..841c3f0f86 100644 --- a/src/Core/Repositories/EntityFramework/ProviderUserRepository.cs +++ b/src/Core/Repositories/EntityFramework/ProviderUserRepository.cs @@ -141,9 +141,19 @@ namespace Bit.Core.Repositories.EntityFramework } } - public Task> GetManyOrganizationDetailsByUserAsync(Guid userId, ProviderUserStatusType? status = null) + public async Task> GetManyOrganizationDetailsByUserAsync(Guid userId, ProviderUserStatusType? status = null) { - throw new NotImplementedException(); + using (var scope = ServiceScopeFactory.CreateScope()) + { + var dbContext = GetDatabaseContext(scope); + var view = new ProviderUserOrganizationDetailsViewQuery(); + var query = from ou in view.Run(dbContext) + where ou.UserId == userId && + (status == null || ou.Status == status) + select ou; + var organizationUsers = await query.ToListAsync(); + return organizationUsers; + } } } } diff --git a/src/Core/Repositories/EntityFramework/Queries/EventReadPageByProviderIdActingUserIdQuery.cs b/src/Core/Repositories/EntityFramework/Queries/EventReadPageByProviderIdActingUserIdQuery.cs new file mode 100644 index 0000000000..37c5e2b0ae --- /dev/null +++ b/src/Core/Repositories/EntityFramework/Queries/EventReadPageByProviderIdActingUserIdQuery.cs @@ -0,0 +1,41 @@ +using System.Linq; +using Bit.Core.Models.EntityFramework; +using System; +using Bit.Core.Models.Data; + +namespace Bit.Core.Repositories.EntityFramework.Queries +{ + public class EventReadPageByProviderIdActingUserIdQuery : IQuery + { + private readonly Guid _providerId; + private readonly Guid _actingUserId; + private readonly DateTime _startDate; + private readonly DateTime _endDate; + private readonly DateTime? _beforeDate; + private readonly PageOptions _pageOptions; + + public EventReadPageByProviderIdActingUserIdQuery(Guid providerId, Guid actingUserId, + DateTime startDate, DateTime endDate, DateTime? beforeDate, PageOptions pageOptions) + { + _providerId = providerId; + _actingUserId = actingUserId; + _startDate = startDate; + _endDate = endDate; + _beforeDate = beforeDate; + _pageOptions = pageOptions; + } + + public IQueryable Run(DatabaseContext dbContext) + { + var q = from e in dbContext.Events + where e.Date >= _startDate && + (_beforeDate != null || e.Date <= _endDate) && + (_beforeDate == null || e.Date < _beforeDate.Value) && + e.ProviderId == _providerId && + e.ActingUserId == _actingUserId + orderby e.Date descending + select e; + return q.Skip(0).Take(_pageOptions.PageSize); + } + } +} diff --git a/src/Core/Repositories/EntityFramework/Queries/EventReadPageByProviderIdQuery.cs b/src/Core/Repositories/EntityFramework/Queries/EventReadPageByProviderIdQuery.cs new file mode 100644 index 0000000000..12690b7b8e --- /dev/null +++ b/src/Core/Repositories/EntityFramework/Queries/EventReadPageByProviderIdQuery.cs @@ -0,0 +1,38 @@ +using System.Linq; +using Bit.Core.Models.EntityFramework; +using System; +using Bit.Core.Models.Data; + +namespace Bit.Core.Repositories.EntityFramework.Queries +{ + public class EventReadPageByProviderIdQuery: IQuery + { + private readonly Guid _providerId; + private readonly DateTime _startDate; + private readonly DateTime _endDate; + private readonly DateTime? _beforeDate; + private readonly PageOptions _pageOptions; + + public EventReadPageByProviderIdQuery(Guid providerId, DateTime startDate, + DateTime endDate, DateTime? beforeDate, PageOptions pageOptions) + { + _providerId = providerId; + _startDate = startDate; + _endDate = endDate; + _beforeDate = beforeDate; + _pageOptions = pageOptions; + } + + public IQueryable Run(DatabaseContext dbContext) + { + var q = from e in dbContext.Events + where e.Date >= _startDate && + (_beforeDate != null || e.Date <= _endDate) && + (_beforeDate == null || e.Date < _beforeDate.Value) && + e.ProviderId == _providerId && e.OrganizationId == null + orderby e.Date descending + select e; + return q.Skip(0).Take(_pageOptions.PageSize); + } + } +} diff --git a/src/Core/Repositories/EntityFramework/Queries/OrganizationUserOrganizationDetailsViewQuery.cs b/src/Core/Repositories/EntityFramework/Queries/OrganizationUserOrganizationDetailsViewQuery.cs index dd3e53d01c..1fff508518 100644 --- a/src/Core/Repositories/EntityFramework/Queries/OrganizationUserOrganizationDetailsViewQuery.cs +++ b/src/Core/Repositories/EntityFramework/Queries/OrganizationUserOrganizationDetailsViewQuery.cs @@ -12,8 +12,12 @@ namespace Bit.Core.Repositories.EntityFramework.Queries join o in dbContext.Organizations on ou.OrganizationId equals o.Id join su in dbContext.SsoUsers on ou.UserId equals su.UserId into su_g from su in su_g.DefaultIfEmpty() + join po in dbContext.ProviderOrganizations on o.Id equals po.OrganizationId into po_g + from po in po_g.DefaultIfEmpty() + join p in dbContext.Providers on po.ProviderId equals p.Id into p_g + from p in p_g.DefaultIfEmpty() where ((su == null || !su.OrganizationId.HasValue) || su.OrganizationId == ou.OrganizationId) - select new { ou, o, su }; + select new { ou, o, su, p }; return query.Select(x => new OrganizationUserOrganizationDetails { OrganizationId = x.ou.OrganizationId, @@ -42,6 +46,8 @@ namespace Bit.Core.Repositories.EntityFramework.Queries Permissions = x.ou.Permissions, PublicKey = x.o.PublicKey, PrivateKey = x.o.PrivateKey, + ProviderId = x.p.Id, + ProviderName = x.p.Name, }); } } diff --git a/src/Core/Repositories/EntityFramework/Queries/ProviderUserOrganizationDetailsViewQuery.cs b/src/Core/Repositories/EntityFramework/Queries/ProviderUserOrganizationDetailsViewQuery.cs new file mode 100644 index 0000000000..436f8ee339 --- /dev/null +++ b/src/Core/Repositories/EntityFramework/Queries/ProviderUserOrganizationDetailsViewQuery.cs @@ -0,0 +1,46 @@ +using System.Collections.Generic; +using System.Linq; +using Bit.Core.Models.Data; + +namespace Bit.Core.Repositories.EntityFramework.Queries +{ + public class ProviderUserOrganizationDetailsViewQuery : IQuery + { + public IQueryable Run(DatabaseContext dbContext) + { + var query = from pu in dbContext.ProviderUsers + join po in dbContext.ProviderOrganizations on pu.ProviderId equals po.ProviderId + join o in dbContext.Organizations on po.OrganizationId equals o.Id + join p in dbContext.Providers on pu.ProviderId equals p.Id + select new { pu, po, o, p }; + return query.Select(x => new ProviderUserOrganizationDetails + { + OrganizationId = x.po.OrganizationId, + UserId = x.pu.UserId, + Name = x.o.Name, + Enabled = x.o.Enabled, + UsePolicies = x.o.UsePolicies, + UseSso = x.o.UseSso, + UseGroups = x.o.UseGroups, + UseDirectory = x.o.UseDirectory, + UseEvents = x.o.UseEvents, + UseTotp = x.o.UseTotp, + Use2fa = x.o.Use2fa, + UseApi = x.o.UseApi, + SelfHost = x.o.SelfHost, + UsersGetPremium = x.o.UsersGetPremium, + Seats = x.o.Seats, + MaxCollections = x.o.MaxCollections, + MaxStorageGb = x.o.MaxStorageGb, + Identifier = x.o.Identifier, + Key = x.po.Key, + Status = x.pu.Status, + Type = x.pu.Type, + PublicKey = x.o.PublicKey, + PrivateKey = x.o.PrivateKey, + ProviderId = x.p.Id, + ProviderName = x.p.Name, + }); + } + } +} diff --git a/src/Core/Repositories/EntityFramework/Queries/ProviderUserProviderDetailsReadByUserIdStatusQuery.cs b/src/Core/Repositories/EntityFramework/Queries/ProviderUserProviderDetailsReadByUserIdStatusQuery.cs index 5188033191..803e578bbb 100644 --- a/src/Core/Repositories/EntityFramework/Queries/ProviderUserProviderDetailsReadByUserIdStatusQuery.cs +++ b/src/Core/Repositories/EntityFramework/Queries/ProviderUserProviderDetailsReadByUserIdStatusQuery.cs @@ -33,6 +33,7 @@ namespace Bit.Core.Repositories.EntityFramework.Queries Type = x.pu.Type, Enabled = x.p.Enabled, Permissions = x.pu.Permissions, + UseEvents = x.p.UseEvents, }); } } diff --git a/src/Core/Repositories/IEventRepository.cs b/src/Core/Repositories/IEventRepository.cs index 47a5e41469..aedd05cd0b 100644 --- a/src/Core/Repositories/IEventRepository.cs +++ b/src/Core/Repositories/IEventRepository.cs @@ -14,6 +14,10 @@ namespace Bit.Core.Repositories PageOptions pageOptions); Task> GetManyByOrganizationActingUserAsync(Guid organizationId, Guid actingUserId, DateTime startDate, DateTime endDate, PageOptions pageOptions); + Task> GetManyByProviderAsync(Guid providerId, DateTime startDate, DateTime endDate, + PageOptions pageOptions); + Task> GetManyByProviderActingUserAsync(Guid providerId, Guid actingUserId, + DateTime startDate, DateTime endDate, PageOptions pageOptions); Task> GetManyByCipherAsync(Cipher cipher, DateTime startDate, DateTime endDate, PageOptions pageOptions); Task CreateAsync(IEvent e); diff --git a/src/Core/Repositories/IProviderOrganizationProviderUserRepository.cs b/src/Core/Repositories/IProviderOrganizationProviderUserRepository.cs deleted file mode 100644 index 8a4f05245d..0000000000 --- a/src/Core/Repositories/IProviderOrganizationProviderUserRepository.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; -using Bit.Core.Models.Table.Provider; - -namespace Bit.Core.Repositories -{ - public interface IProviderOrganizationProviderUserRepository : IRepository - { - } -} diff --git a/src/Core/Repositories/IProviderOrganizationRepository.cs b/src/Core/Repositories/IProviderOrganizationRepository.cs index e8ecffe83a..66f1b231d0 100644 --- a/src/Core/Repositories/IProviderOrganizationRepository.cs +++ b/src/Core/Repositories/IProviderOrganizationRepository.cs @@ -9,6 +9,6 @@ namespace Bit.Core.Repositories public interface IProviderOrganizationRepository : IRepository { Task> GetManyDetailsByProviderAsync(Guid providerId); - Task> GetManyByUserIdAsync(Guid userId); + Task GetByOrganizationId(Guid organizationId); } } diff --git a/src/Core/Repositories/SqlServer/EventRepository.cs b/src/Core/Repositories/SqlServer/EventRepository.cs index dffe3915ea..b3cf43b114 100644 --- a/src/Core/Repositories/SqlServer/EventRepository.cs +++ b/src/Core/Repositories/SqlServer/EventRepository.cs @@ -52,6 +52,27 @@ namespace Bit.Core.Repositories.SqlServer }, startDate, endDate, pageOptions); } + public async Task> GetManyByProviderAsync(Guid providerId, + DateTime startDate, DateTime endDate, PageOptions pageOptions) + { + return await GetManyAsync($"[{Schema}].[Event_ReadPageByProviderId]", + new Dictionary + { + ["@ProviderId"] = providerId + }, startDate, endDate, pageOptions); + } + + public async Task> GetManyByProviderActingUserAsync(Guid providerId, Guid actingUserId, + DateTime startDate, DateTime endDate, PageOptions pageOptions) + { + return await GetManyAsync($"[{Schema}].[Event_ReadPageByProviderIdActingUserId]", + new Dictionary + { + ["@ProviderId"] = providerId, + ["@ActingUserId"] = actingUserId + }, startDate, endDate, pageOptions); + } + public async Task> GetManyByCipherAsync(Cipher cipher, DateTime startDate, DateTime endDate, PageOptions pageOptions) { diff --git a/src/Core/Repositories/SqlServer/ProviderOrganizationProviderUserRepository.cs b/src/Core/Repositories/SqlServer/ProviderOrganizationProviderUserRepository.cs deleted file mode 100644 index 8cac8b3658..0000000000 --- a/src/Core/Repositories/SqlServer/ProviderOrganizationProviderUserRepository.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using Bit.Core.Models.Table.Provider; -using Bit.Core.Settings; - -namespace Bit.Core.Repositories.SqlServer -{ - public class ProviderOrganizationProviderUserRepository : Repository, IProviderOrganizationProviderUserRepository - { - public ProviderOrganizationProviderUserRepository(GlobalSettings globalSettings) - : this(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString) - { } - - public ProviderOrganizationProviderUserRepository(string connectionString, string readOnlyConnectionString) - : base(connectionString, readOnlyConnectionString) - { } - } -} diff --git a/src/Core/Repositories/SqlServer/ProviderOrganizationRepository.cs b/src/Core/Repositories/SqlServer/ProviderOrganizationRepository.cs index ba9e61740a..f6f21d7912 100644 --- a/src/Core/Repositories/SqlServer/ProviderOrganizationRepository.cs +++ b/src/Core/Repositories/SqlServer/ProviderOrganizationRepository.cs @@ -34,16 +34,16 @@ namespace Bit.Core.Repositories.SqlServer } } - public async Task> GetManyByUserIdAsync(Guid userId) + public async Task GetByOrganizationId(Guid organizationId) { using (var connection = new SqlConnection(ConnectionString)) { var results = await connection.QueryAsync( - "[dbo].[ProviderOrganization_ReadByUserId]", - new { UserId = userId }, + "[dbo].[ProviderOrganization_ReadByOrganizationId]", + new { OrganizationId = organizationId }, commandType: CommandType.StoredProcedure); - return results.ToList(); + return results.SingleOrDefault(); } } } diff --git a/src/Core/Repositories/SqlServer/ProviderRepository.cs b/src/Core/Repositories/SqlServer/ProviderRepository.cs index 3d27363c10..61736ba9a8 100644 --- a/src/Core/Repositories/SqlServer/ProviderRepository.cs +++ b/src/Core/Repositories/SqlServer/ProviderRepository.cs @@ -1,5 +1,4 @@ using System; -using Bit.Core.Models.Table; using System.Threading.Tasks; using System.Data.SqlClient; using System.Data; diff --git a/src/Core/Repositories/TableStorage/EventRepository.cs b/src/Core/Repositories/TableStorage/EventRepository.cs index 62a77c8bba..5057e33e13 100644 --- a/src/Core/Repositories/TableStorage/EventRepository.cs +++ b/src/Core/Repositories/TableStorage/EventRepository.cs @@ -44,6 +44,19 @@ namespace Bit.Core.Repositories.TableStorage $"ActingUserId={actingUserId}__Date={{0}}", startDate, endDate, pageOptions); } + public async Task> GetManyByProviderAsync(Guid providerId, + DateTime startDate, DateTime endDate, PageOptions pageOptions) + { + return await GetManyAsync($"ProviderId={providerId}", "Date={0}", startDate, endDate, pageOptions); + } + + public async Task> GetManyByProviderActingUserAsync(Guid providerId, Guid actingUserId, + DateTime startDate, DateTime endDate, PageOptions pageOptions) + { + return await GetManyAsync($"ProviderId={providerId}", + $"ActingUserId={actingUserId}__Date={{0}}", startDate, endDate, pageOptions); + } + public async Task> GetManyByCipherAsync(Cipher cipher, DateTime startDate, DateTime endDate, PageOptions pageOptions) { diff --git a/src/Core/Services/IOrganizationService.cs b/src/Core/Services/IOrganizationService.cs index 415a78cbca..e0c68430af 100644 --- a/src/Core/Services/IOrganizationService.cs +++ b/src/Core/Services/IOrganizationService.cs @@ -59,5 +59,6 @@ namespace Bit.Core.Services Task RotateApiKeyAsync(Organization organization); Task DeleteSsoUserAsync(Guid userId, Guid? organizationId); Task UpdateOrganizationKeysAsync(Guid orgId, string publicKey, string privateKey); + Task HasConfirmedOwnersExceptAsync(Guid organizationId, IEnumerable organizationUsersId); } } diff --git a/src/Core/Services/IProviderService.cs b/src/Core/Services/IProviderService.cs index 5759833ced..28bb56080e 100644 --- a/src/Core/Services/IProviderService.cs +++ b/src/Core/Services/IProviderService.cs @@ -26,6 +26,6 @@ namespace Bit.Core.Services Task AddOrganization(Guid providerId, Guid organizationId, Guid addingUserId, string key); Task CreateOrganizationAsync(Guid providerId, OrganizationSignup organizationSignup, User user); - Task RemoveOrganization(Guid providerOrganizationId, Guid removingUserId); + Task RemoveOrganization(Guid providerId, Guid providerOrganizationId, Guid removingUserId); } } diff --git a/src/Core/Services/Implementations/EventService.cs b/src/Core/Services/Implementations/EventService.cs index 18c870fba9..06201e4b57 100644 --- a/src/Core/Services/Implementations/EventService.cs +++ b/src/Core/Services/Implementations/EventService.cs @@ -16,6 +16,7 @@ namespace Bit.Core.Services { private readonly IEventWriteService _eventWriteService; private readonly IOrganizationUserRepository _organizationUserRepository; + private readonly IProviderUserRepository _providerUserRepository; private readonly IApplicationCacheService _applicationCacheService; private readonly ICurrentContext _currentContext; private readonly GlobalSettings _globalSettings; @@ -23,12 +24,14 @@ namespace Bit.Core.Services public EventService( IEventWriteService eventWriteService, IOrganizationUserRepository organizationUserRepository, + IProviderUserRepository providerUserRepository, IApplicationCacheService applicationCacheService, ICurrentContext currentContext, GlobalSettings globalSettings) { _eventWriteService = eventWriteService; _organizationUserRepository = organizationUserRepository; + _providerUserRepository = providerUserRepository; _applicationCacheService = applicationCacheService; _currentContext = currentContext; _globalSettings = globalSettings; @@ -58,10 +61,23 @@ namespace Bit.Core.Services Type = type, Date = DateTime.UtcNow }); + + var providerAbilities = await _applicationCacheService.GetProviderAbilitiesAsync(); + var providers = await _currentContext.ProviderMembershipAsync(_providerUserRepository, userId); + var providerEvents = providers.Where(o => CanUseProviderEvents(providerAbilities, o.Id)) + .Select(p => new EventMessage(_currentContext) + { + ProviderId = p.Id, + UserId = userId, + ActingUserId = userId, + Type = type, + Date = DateTime.UtcNow + }); - if (orgEvents.Any()) + if (orgEvents.Any() || providerEvents.Any()) { events.AddRange(orgEvents); + events.AddRange(providerEvents); await _eventWriteService.CreateManyAsync(events); } else @@ -117,6 +133,7 @@ namespace Bit.Core.Services CipherId = cipher.Id, Type = type, ActingUserId = _currentContext?.UserId, + ProviderId = await GetProviderIdAsync(cipher.OrganizationId), Date = date.GetValueOrDefault(DateTime.UtcNow) }; } @@ -135,6 +152,7 @@ namespace Bit.Core.Services CollectionId = collection.Id, Type = type, ActingUserId = _currentContext?.UserId, + ProviderId = await GetProviderIdAsync(collection.OrganizationId), Date = date.GetValueOrDefault(DateTime.UtcNow) }; await _eventWriteService.CreateAsync(e); @@ -154,6 +172,7 @@ namespace Bit.Core.Services GroupId = group.Id, Type = type, ActingUserId = _currentContext?.UserId, + ProviderId = await GetProviderIdAsync(@group.OrganizationId), Date = date.GetValueOrDefault(DateTime.UtcNow) }; await _eventWriteService.CreateAsync(e); @@ -173,6 +192,7 @@ namespace Bit.Core.Services PolicyId = policy.Id, Type = type, ActingUserId = _currentContext?.UserId, + ProviderId = await GetProviderIdAsync(policy.OrganizationId), Date = date.GetValueOrDefault(DateTime.UtcNow) }; await _eventWriteService.CreateAsync(e); @@ -192,11 +212,13 @@ namespace Bit.Core.Services { continue; } + eventMessages.Add(new EventMessage { OrganizationId = organizationUser.OrganizationId, UserId = organizationUser.UserId, OrganizationUserId = organizationUser.Id, + ProviderId = await GetProviderIdAsync(organizationUser.OrganizationId), Type = type, ActingUserId = _currentContext?.UserId, Date = date.GetValueOrDefault(DateTime.UtcNow) @@ -216,6 +238,7 @@ namespace Bit.Core.Services var e = new EventMessage(_currentContext) { OrganizationId = organization.Id, + ProviderId = await GetProviderIdAsync(organization.Id), Type = type, ActingUserId = _currentContext?.UserId, Date = date.GetValueOrDefault(DateTime.UtcNow) @@ -251,6 +274,16 @@ namespace Bit.Core.Services await _eventWriteService.CreateManyAsync(eventMessages); } + + private async Task GetProviderIdAsync(Guid? orgId) + { + if (_currentContext == null || !orgId.HasValue) + { + return null; + } + + return await _currentContext.ProviderIdForOrg(orgId.Value); + } private bool CanUseEvents(IDictionary orgAbilities, Guid orgId) { diff --git a/src/Core/Services/Implementations/OrganizationService.cs b/src/Core/Services/Implementations/OrganizationService.cs index 8325c8a280..8e26646701 100644 --- a/src/Core/Services/Implementations/OrganizationService.cs +++ b/src/Core/Services/Implementations/OrganizationService.cs @@ -1685,7 +1685,7 @@ namespace Bit.Core.Services return result; } - private async Task HasConfirmedOwnersExceptAsync(Guid organizationId, IEnumerable organizationUsersId) + public async Task HasConfirmedOwnersExceptAsync(Guid organizationId, IEnumerable organizationUsersId) { var confirmedOwners = await GetConfirmedOwnersAsync(organizationId); var confirmedOwnersIds = confirmedOwners.Select(u => u.Id); diff --git a/src/Core/Services/NoopImplementations/NoopProviderService.cs b/src/Core/Services/NoopImplementations/NoopProviderService.cs index 51c46b714e..9605523b91 100644 --- a/src/Core/Services/NoopImplementations/NoopProviderService.cs +++ b/src/Core/Services/NoopImplementations/NoopProviderService.cs @@ -31,6 +31,6 @@ namespace Bit.Core.Services public Task AddOrganization(Guid providerId, Guid organizationId, Guid addingUserId, string key) => throw new NotImplementedException(); public Task CreateOrganizationAsync(Guid providerId, OrganizationSignup organizationSignup, User user) => throw new NotImplementedException(); - public Task RemoveOrganization(Guid providerOrganizationId, Guid removingUserId) => throw new NotImplementedException(); + public Task RemoveOrganization(Guid providerId, Guid providerOrganizationId, Guid removingUserId) => throw new NotImplementedException(); } } diff --git a/src/Core/Utilities/ServiceCollectionExtensions.cs b/src/Core/Utilities/ServiceCollectionExtensions.cs index 1590be802f..47893ead0c 100644 --- a/src/Core/Utilities/ServiceCollectionExtensions.cs +++ b/src/Core/Utilities/ServiceCollectionExtensions.cs @@ -113,7 +113,6 @@ namespace Bit.Core.Utilities services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); } else { @@ -138,7 +137,6 @@ namespace Bit.Core.Utilities services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); diff --git a/src/Notifications/NotificationsHub.cs b/src/Notifications/NotificationsHub.cs index b9a09a25a9..43969d7708 100644 --- a/src/Notifications/NotificationsHub.cs +++ b/src/Notifications/NotificationsHub.cs @@ -10,21 +10,21 @@ namespace Bit.Notifications [Authorize("Application")] public class NotificationsHub : Microsoft.AspNetCore.SignalR.Hub { - private readonly IProviderOrganizationRepository _providerOrganizationRepository; + private readonly IProviderUserRepository _providerUserRepository; private readonly ConnectionCounter _connectionCounter; private readonly GlobalSettings _globalSettings; - public NotificationsHub(IProviderOrganizationRepository providerOrganizationRepository, + public NotificationsHub(IProviderUserRepository providerUserRepository, ConnectionCounter connectionCounter, GlobalSettings globalSettings) { - _providerOrganizationRepository = providerOrganizationRepository; + _providerUserRepository = providerUserRepository; _connectionCounter = connectionCounter; _globalSettings = globalSettings; } public override async Task OnConnectedAsync() { - var currentContext = new CurrentContext(_providerOrganizationRepository); + var currentContext = new CurrentContext(_providerUserRepository); await currentContext.BuildAsync(Context.User, _globalSettings); if (currentContext.Organizations != null) { @@ -39,7 +39,7 @@ namespace Bit.Notifications public override async Task OnDisconnectedAsync(Exception exception) { - var currentContext = new CurrentContext(_providerOrganizationRepository); + var currentContext = new CurrentContext(_providerUserRepository); await currentContext.BuildAsync(Context.User, _globalSettings); if (currentContext.Organizations != null) { diff --git a/src/Sql/Sql.sqlproj b/src/Sql/Sql.sqlproj index 5769ee10af..4dda7402ef 100644 --- a/src/Sql/Sql.sqlproj +++ b/src/Sql/Sql.sqlproj @@ -70,7 +70,9 @@ - + + + @@ -363,10 +365,5 @@ - - - - - diff --git a/src/Sql/dbo/Stored Procedures/Event_Create.sql b/src/Sql/dbo/Stored Procedures/Event_Create.sql index 558e0339eb..dad922c35a 100644 --- a/src/Sql/dbo/Stored Procedures/Event_Create.sql +++ b/src/Sql/dbo/Stored Procedures/Event_Create.sql @@ -1,13 +1,15 @@ CREATE PROCEDURE [dbo].[Event_Create] - @Id UNIQUEIDENTIFIER, + @Id UNIQUEIDENTIFIER OUTPUT, @Type INT, @UserId UNIQUEIDENTIFIER, @OrganizationId UNIQUEIDENTIFIER, + @ProviderId UNIQUEIDENTIFIER, @CipherId UNIQUEIDENTIFIER, @CollectionId UNIQUEIDENTIFIER, @PolicyId UNIQUEIDENTIFIER, @GroupId UNIQUEIDENTIFIER, @OrganizationUserId UNIQUEIDENTIFIER, + @ProviderUserId UNIQUEIDENTIFIER, @ActingUserId UNIQUEIDENTIFIER, @DeviceType SMALLINT, @IpAddress VARCHAR(50), @@ -22,11 +24,13 @@ BEGIN [Type], [UserId], [OrganizationId], + [ProviderId], [CipherId], [CollectionId], [PolicyId], [GroupId], [OrganizationUserId], + [ProviderUserId], [ActingUserId], [DeviceType], [IpAddress], @@ -38,11 +42,13 @@ BEGIN @Type, @UserId, @OrganizationId, + @ProviderId, @CipherId, @CollectionId, @PolicyId, @GroupId, @OrganizationUserId, + @ProviderUserId, @ActingUserId, @DeviceType, @IpAddress, diff --git a/src/Sql/dbo/Stored Procedures/Event_ReadPageByProviderId.sql b/src/Sql/dbo/Stored Procedures/Event_ReadPageByProviderId.sql new file mode 100644 index 0000000000..58a5aca886 --- /dev/null +++ b/src/Sql/dbo/Stored Procedures/Event_ReadPageByProviderId.sql @@ -0,0 +1,23 @@ +CREATE PROCEDURE [dbo].[Event_ReadPageByProviderId] + @ProviderId UNIQUEIDENTIFIER, + @StartDate DATETIME2(7), + @EndDate DATETIME2(7), + @BeforeDate DATETIME2(7), + @PageSize INT +AS +BEGIN + SET NOCOUNT ON + + SELECT + * + FROM + [dbo].[EventView] + WHERE + [Date] >= @StartDate + AND (@BeforeDate IS NOT NULL OR [Date] <= @EndDate) + AND (@BeforeDate IS NULL OR [Date] < @BeforeDate) + AND [Providerid] = @ProviderId + ORDER BY [Date] DESC + OFFSET 0 ROWS + FETCH NEXT @PageSize ROWS ONLY +END diff --git a/src/Sql/dbo/Stored Procedures/Event_ReadPageByProviderIdActingUserId.sql b/src/Sql/dbo/Stored Procedures/Event_ReadPageByProviderIdActingUserId.sql new file mode 100644 index 0000000000..11b333c644 --- /dev/null +++ b/src/Sql/dbo/Stored Procedures/Event_ReadPageByProviderIdActingUserId.sql @@ -0,0 +1,25 @@ +CREATE PROCEDURE [dbo].[Event_ReadPageByProviderIdActingUserId] + @ProviderId UNIQUEIDENTIFIER, + @ActingUserId UNIQUEIDENTIFIER, + @StartDate DATETIME2(7), + @EndDate DATETIME2(7), + @BeforeDate DATETIME2(7), + @PageSize INT +AS +BEGIN + SET NOCOUNT ON + + SELECT + * + FROM + [dbo].[EventView] + WHERE + [Date] >= @StartDate + AND (@BeforeDate IS NOT NULL OR [Date] <= @EndDate) + AND (@BeforeDate IS NULL OR [Date] < @BeforeDate) + AND [ProviderId] = @ProviderId + AND [ActingUserId] = @ActingUserId + ORDER BY [Date] DESC + OFFSET 0 ROWS + FETCH NEXT @PageSize ROWS ONLY +END diff --git a/src/Sql/dbo/Stored Procedures/ProviderOrganizationProviderUser_Create.sql b/src/Sql/dbo/Stored Procedures/ProviderOrganizationProviderUser_Create.sql deleted file mode 100644 index 9391df78c9..0000000000 --- a/src/Sql/dbo/Stored Procedures/ProviderOrganizationProviderUser_Create.sql +++ /dev/null @@ -1,33 +0,0 @@ -CREATE PROCEDURE [dbo].[ProviderOrganizationProviderUser_Create] - @Id UNIQUEIDENTIFIER, - @ProviderOrganizationId UNIQUEIDENTIFIER, - @ProviderUserId UNIQUEIDENTIFIER, - @Type TINYINT, - @Permissions NVARCHAR(MAX), - @CreationDate DATETIME2(7), - @RevisionDate DATETIME2(7) -AS -BEGIN - SET NOCOUNT ON - - INSERT INTO [dbo].[ProviderOrganizationProviderUser] - ( - [Id], - [ProviderOrganizationId], - [ProviderUserId], - [Type], - [Permissions], - [CreationDate], - [RevisionDate] - ) - VALUES - ( - @Id, - @ProviderOrganizationId, - @ProviderUserId, - @Type, - @Permissions, - @CreationDate, - @RevisionDate - ) -END diff --git a/src/Sql/dbo/Stored Procedures/ProviderOrganizationProviderUser_DeleteById.sql b/src/Sql/dbo/Stored Procedures/ProviderOrganizationProviderUser_DeleteById.sql deleted file mode 100644 index 2d9bcf4ad4..0000000000 --- a/src/Sql/dbo/Stored Procedures/ProviderOrganizationProviderUser_DeleteById.sql +++ /dev/null @@ -1,27 +0,0 @@ -CREATE PROCEDURE [dbo].[ProviderOrganizationProviderUser_DeleteById] - @Id UNIQUEIDENTIFIER -AS -BEGIN - SET NOCOUNT ON - - BEGIN TRANSACTION POPU_DeleteById - - DECLARE @ProviderUserId UNIQUEIDENTIFIER - - SELECT - @ProviderUserId = [ProviderUserId] - FROM - [dbo].[ProviderOrganizationProviderUser] - WHERE - [Id] = @Id - - DELETE - FROM - [dbo].[ProviderOrganizationProviderUser] - WHERE - [Id] = @Id - - EXEC [dbo].[User_BumpAccountRevisionDateByProviderUserId] @ProviderUserId - - COMMIT TRANSACTION POPU_DeleteById -END diff --git a/src/Sql/dbo/Stored Procedures/ProviderOrganizationProviderUser_ReadById.sql b/src/Sql/dbo/Stored Procedures/ProviderOrganizationProviderUser_ReadById.sql deleted file mode 100644 index 6ce856338c..0000000000 --- a/src/Sql/dbo/Stored Procedures/ProviderOrganizationProviderUser_ReadById.sql +++ /dev/null @@ -1,13 +0,0 @@ -CREATE PROCEDURE [dbo].[ProviderOrganizationProviderUser_ReadById] - @Id UNIQUEIDENTIFIER -AS -BEGIN - SET NOCOUNT ON - - SELECT - * - FROM - [dbo].[ProviderOrganizationProviderUser] - WHERE - [Id] = @Id -END diff --git a/src/Sql/dbo/Stored Procedures/ProviderOrganizationProviderUser_Update.sql b/src/Sql/dbo/Stored Procedures/ProviderOrganizationProviderUser_Update.sql deleted file mode 100644 index d361c0c214..0000000000 --- a/src/Sql/dbo/Stored Procedures/ProviderOrganizationProviderUser_Update.sql +++ /dev/null @@ -1,26 +0,0 @@ -CREATE PROCEDURE [dbo].[ProviderOrganizationProviderUser_Update] - @Id UNIQUEIDENTIFIER, - @ProviderOrganizationId UNIQUEIDENTIFIER, - @ProviderUserId UNIQUEIDENTIFIER, - @Type TINYINT, - @Permissions NVARCHAR(MAX), - @CreationDate DATETIME2(7), - @RevisionDate DATETIME2(7) -AS -BEGIN - SET NOCOUNT ON - - UPDATE - [dbo].[ProviderOrganizationProviderUser] - SET - [ProviderOrganizationId] = @ProviderOrganizationId, - [ProviderUserId] = @ProviderUserId, - [Type] = @Type, - [Permissions] = @Permissions, - [CreationDate] = @CreationDate, - [RevisionDate] = @RevisionDate - WHERE - [Id] = @Id - - EXEC [dbo].[User_BumpAccountRevisionDateByProviderUserId] @ProviderUserId -END diff --git a/src/Sql/dbo/Stored Procedures/ProviderOrganization_Create.sql b/src/Sql/dbo/Stored Procedures/ProviderOrganization_Create.sql index 3d25f6b1ed..22f22971ff 100644 --- a/src/Sql/dbo/Stored Procedures/ProviderOrganization_Create.sql +++ b/src/Sql/dbo/Stored Procedures/ProviderOrganization_Create.sql @@ -1,5 +1,5 @@ CREATE PROCEDURE [dbo].[ProviderOrganization_Create] - @Id UNIQUEIDENTIFIER, + @Id UNIQUEIDENTIFIER OUTPUT, @ProviderId UNIQUEIDENTIFIER, @OrganizationId UNIQUEIDENTIFIER, @Key VARCHAR(MAX), diff --git a/src/Sql/dbo/Stored Procedures/ProviderOrganization_ReadByOrganizationId.sql b/src/Sql/dbo/Stored Procedures/ProviderOrganization_ReadByOrganizationId.sql new file mode 100644 index 0000000000..096d2b4778 --- /dev/null +++ b/src/Sql/dbo/Stored Procedures/ProviderOrganization_ReadByOrganizationId.sql @@ -0,0 +1,13 @@ +CREATE PROCEDURE [dbo].[ProviderOrganization_ReadByOrganizationId] + @OrganizationId UNIQUEIDENTIFIER +AS +BEGIN + SET NOCOUNT ON + + SELECT + * + FROM + [dbo].[ProviderOrganizationView] + WHERE + [OrganizationId] = @OrganizationId +END diff --git a/src/Sql/dbo/Stored Procedures/ProviderOrganization_ReadByUserId.sql b/src/Sql/dbo/Stored Procedures/ProviderOrganization_ReadByUserId.sql deleted file mode 100644 index b40e08458f..0000000000 --- a/src/Sql/dbo/Stored Procedures/ProviderOrganization_ReadByUserId.sql +++ /dev/null @@ -1,17 +0,0 @@ -CREATE PROCEDURE [dbo].[ProviderOrganization_ReadByUserId] - @UserId UNIQUEIDENTIFIER -AS -BEGIN - SET NOCOUNT ON - - SELECT - PO.* - FROM - [dbo].[ProviderOrganizationView] PO - INNER JOIN - [dbo].[Provider] P ON PO.[ProviderId] = P.[Id] - INNER JOIN - [dbo].[ProviderUser] PU ON P.[Id] = PU.[ProviderId] - WHERE - PU.[UserId] = @UserId -END diff --git a/src/Sql/dbo/Stored Procedures/ProviderUser_Create.sql b/src/Sql/dbo/Stored Procedures/ProviderUser_Create.sql index ad25680e78..e676a3c1eb 100644 --- a/src/Sql/dbo/Stored Procedures/ProviderUser_Create.sql +++ b/src/Sql/dbo/Stored Procedures/ProviderUser_Create.sql @@ -1,5 +1,5 @@ CREATE PROCEDURE [dbo].[ProviderUser_Create] - @Id UNIQUEIDENTIFIER, + @Id UNIQUEIDENTIFIER OUTPUT, @ProviderId UNIQUEIDENTIFIER, @UserId UNIQUEIDENTIFIER, @Email NVARCHAR(256), diff --git a/src/Sql/dbo/Stored Procedures/Provider_Create.sql b/src/Sql/dbo/Stored Procedures/Provider_Create.sql index 6cf46cae1b..2d0a8d4b42 100644 --- a/src/Sql/dbo/Stored Procedures/Provider_Create.sql +++ b/src/Sql/dbo/Stored Procedures/Provider_Create.sql @@ -1,5 +1,5 @@ CREATE PROCEDURE [dbo].[Provider_Create] - @Id UNIQUEIDENTIFIER, + @Id UNIQUEIDENTIFIER OUTPUT, @Name NVARCHAR(50), @BusinessName NVARCHAR(50), @BusinessAddress1 NVARCHAR(50), diff --git a/src/Sql/dbo/Stored Procedures/User_ReadPublicKeysByProviderUserIds.sql b/src/Sql/dbo/Stored Procedures/User_ReadPublicKeysByProviderUserIds.sql index b276d053e4..90ad6d0441 100644 --- a/src/Sql/dbo/Stored Procedures/User_ReadPublicKeysByProviderUserIds.sql +++ b/src/Sql/dbo/Stored Procedures/User_ReadPublicKeysByProviderUserIds.sql @@ -7,6 +7,7 @@ BEGIN SELECT PU.[Id], + PU.[UserId], U.[PublicKey] FROM @ProviderUserIds PUIDs diff --git a/src/Sql/dbo/Tables/Event.sql b/src/Sql/dbo/Tables/Event.sql index 7e53aaac67..409c947566 100644 --- a/src/Sql/dbo/Tables/Event.sql +++ b/src/Sql/dbo/Tables/Event.sql @@ -12,6 +12,8 @@ [DeviceType] SMALLINT NULL, [IpAddress] VARCHAR(50) NULL, [Date] DATETIME2 (7) NOT NULL, + [ProviderId] UNIQUEIDENTIFIER NULL, + [ProviderUserId] UNIQUEIDENTIFIER NULL, CONSTRAINT [PK_Event] PRIMARY KEY CLUSTERED ([Id] ASC) ); diff --git a/src/Sql/dbo/Tables/ProviderOrganizationProviderUser.sql b/src/Sql/dbo/Tables/ProviderOrganizationProviderUser.sql deleted file mode 100644 index f2a214a030..0000000000 --- a/src/Sql/dbo/Tables/ProviderOrganizationProviderUser.sql +++ /dev/null @@ -1,12 +0,0 @@ -CREATE TABLE [dbo].[ProviderOrganizationProviderUser] ( - [Id] UNIQUEIDENTIFIER NOT NULL, - [ProviderOrganizationId] UNIQUEIDENTIFIER NOT NULL, - [ProviderUserId] UNIQUEIDENTIFIER NULL, - [Type] TINYINT NOT NULL, - [Permissions] NVARCHAR (MAX) NULL, - [CreationDate] DATETIME2 (7) NOT NULL, - [RevisionDate] DATETIME2 (7) NOT NULL, - CONSTRAINT [PK_ProviderOrganizationProviderUser] PRIMARY KEY CLUSTERED ([Id] ASC), - CONSTRAINT [FK_ProviderOrganizationProviderUser_Provider] FOREIGN KEY ([ProviderOrganizationId]) REFERENCES [dbo].[ProviderOrganization] ([Id]) ON DELETE CASCADE, - CONSTRAINT [FK_ProviderOrganizationProviderUser_User] FOREIGN KEY ([ProviderUserId]) REFERENCES [dbo].[ProviderUser] ([Id]) -); diff --git a/src/Sql/dbo/Views/ProviderUserProviderOrganizationDetailsView.sql b/src/Sql/dbo/Views/ProviderUserProviderOrganizationDetailsView.sql index cd9d2d932b..94740127eb 100644 --- a/src/Sql/dbo/Views/ProviderUserProviderOrganizationDetailsView.sql +++ b/src/Sql/dbo/Views/ProviderUserProviderOrganizationDetailsView.sql @@ -26,6 +26,7 @@ SELECT PU.[Status], PU.[Type], PO.[ProviderId], + PU.[Id] ProviderUserId, P.[Name] ProviderName FROM [dbo].[ProviderUser] PU diff --git a/test/Core.Test/Services/EventServiceTests.cs b/test/Core.Test/Services/EventServiceTests.cs index aa29d272ca..3476a25652 100644 --- a/test/Core.Test/Services/EventServiceTests.cs +++ b/test/Core.Test/Services/EventServiceTests.cs @@ -14,6 +14,7 @@ namespace Bit.Core.Test.Services private readonly IEventWriteService _eventWriteService; private readonly IOrganizationUserRepository _organizationUserRepository; + private readonly IProviderUserRepository _providerUserRepository; private readonly IApplicationCacheService _applicationCacheService; private readonly CurrentContext _currentContext; private readonly GlobalSettings _globalSettings; @@ -22,6 +23,7 @@ namespace Bit.Core.Test.Services { _eventWriteService = Substitute.For(); _organizationUserRepository = Substitute.For(); + _providerUserRepository = Substitute.For(); _applicationCacheService = Substitute.For(); _currentContext = new CurrentContext(null); _globalSettings = new GlobalSettings(); @@ -29,6 +31,7 @@ namespace Bit.Core.Test.Services _sut = new EventService( _eventWriteService, _organizationUserRepository, + _providerUserRepository, _applicationCacheService, _currentContext, _globalSettings diff --git a/util/Migrator/DbScripts/2021-07-02_00_Provider.sql b/util/Migrator/DbScripts/2021-07-08_00_Provider.sql similarity index 86% rename from util/Migrator/DbScripts/2021-07-02_00_Provider.sql rename to util/Migrator/DbScripts/2021-07-08_00_Provider.sql index 9e2096df56..6f3f2707b9 100644 --- a/util/Migrator/DbScripts/2021-07-02_00_Provider.sql +++ b/util/Migrator/DbScripts/2021-07-08_00_Provider.sql @@ -146,7 +146,7 @@ END GO CREATE PROCEDURE [dbo].[Provider_Create] - @Id UNIQUEIDENTIFIER, + @Id UNIQUEIDENTIFIER OUTPUT, @Name NVARCHAR(50), @BusinessName NVARCHAR(50), @BusinessAddress1 NVARCHAR(50), @@ -341,7 +341,7 @@ END GO CREATE PROCEDURE [dbo].[ProviderUser_Create] - @Id UNIQUEIDENTIFIER, + @Id UNIQUEIDENTIFIER OUTPUT, @ProviderId UNIQUEIDENTIFIER, @UserId UNIQUEIDENTIFIER, @Email NVARCHAR(256), @@ -564,7 +564,7 @@ END GO CREATE PROCEDURE [dbo].[ProviderOrganization_Create] - @Id UNIQUEIDENTIFIER, + @Id UNIQUEIDENTIFIER OUTPUT, @ProviderId UNIQUEIDENTIFIER, @OrganizationId UNIQUEIDENTIFIER, @Key VARCHAR(MAX), @@ -687,154 +687,6 @@ BEGIN END GO -IF OBJECT_ID('[dbo].[ProviderOrganizationProviderUser]') IS NULL -BEGIN - CREATE TABLE [dbo].[ProviderOrganizationProviderUser] ( - [Id] UNIQUEIDENTIFIER NOT NULL, - [ProviderOrganizationId] UNIQUEIDENTIFIER NOT NULL, - [ProviderUserId] UNIQUEIDENTIFIER NULL, - [Type] TINYINT NOT NULL, - [Permissions] NVARCHAR (MAX) NULL, - [CreationDate] DATETIME2 (7) NOT NULL, - [RevisionDate] DATETIME2 (7) NOT NULL, - CONSTRAINT [PK_ProviderOrganizationProviderUser] PRIMARY KEY CLUSTERED ([Id] ASC), - CONSTRAINT [FK_ProviderOrganizationProviderUser_Provider] FOREIGN KEY ([ProviderOrganizationId]) REFERENCES [dbo].[ProviderOrganization] ([Id]) ON DELETE CASCADE, - CONSTRAINT [FK_ProviderOrganizationProviderUser_User] FOREIGN KEY ([ProviderUserId]) REFERENCES [dbo].[ProviderUser] ([Id]) - ); -END -GO - -IF OBJECT_ID('[dbo].[ProviderOrganizationProviderUser_Create]') IS NOT NULL -BEGIN - DROP PROCEDURE [dbo].[ProviderOrganizationProviderUser_Create] -END -GO - -CREATE PROCEDURE [dbo].[ProviderOrganizationProviderUser_Create] - @Id UNIQUEIDENTIFIER, - @ProviderOrganizationId UNIQUEIDENTIFIER, - @ProviderUserId UNIQUEIDENTIFIER, - @Type TINYINT, - @Permissions NVARCHAR(MAX), - @CreationDate DATETIME2(7), - @RevisionDate DATETIME2(7) -AS -BEGIN - SET NOCOUNT ON - - INSERT INTO [dbo].[ProviderOrganizationProviderUser] - ( - [Id], - [ProviderOrganizationId], - [ProviderUserId], - [Type], - [Permissions], - [CreationDate], - [RevisionDate] - ) - VALUES - ( - @Id, - @ProviderOrganizationId, - @ProviderUserId, - @Type, - @Permissions, - @CreationDate, - @RevisionDate - ) -END -GO - -IF OBJECT_ID('[dbo].[ProviderOrganizationProviderUser_DeleteById]') IS NOT NULL -BEGIN - DROP PROCEDURE [dbo].[ProviderOrganizationProviderUser_DeleteById] -END -GO - -CREATE PROCEDURE [dbo].[ProviderOrganizationProviderUser_DeleteById] -@Id UNIQUEIDENTIFIER -AS -BEGIN - SET NOCOUNT ON - - BEGIN TRANSACTION POPU_DeleteById - - DECLARE @ProviderUserId UNIQUEIDENTIFIER - - SELECT - @ProviderUserId = [ProviderUserId] - FROM - [dbo].[ProviderOrganizationProviderUser] - WHERE - [Id] = @Id - - DELETE - FROM - [dbo].[ProviderOrganizationProviderUser] - WHERE - [Id] = @Id - - EXEC [dbo].[User_BumpAccountRevisionDateByProviderUserId] @ProviderUserId - - COMMIT TRANSACTION POPU_DeleteById -END -GO - -IF OBJECT_ID('[dbo].[ProviderOrganizationProviderUser_ReadById]') IS NOT NULL -BEGIN - DROP PROCEDURE [dbo].[ProviderOrganizationProviderUser_ReadById] -END -GO - -CREATE PROCEDURE [dbo].[ProviderOrganizationProviderUser_ReadById] - @Id UNIQUEIDENTIFIER -AS -BEGIN - SET NOCOUNT ON - - SELECT - * - FROM - [dbo].[ProviderOrganizationProviderUser] - WHERE - [Id] = @Id -END -GO - -IF OBJECT_ID('[dbo].[ProviderOrganizationProviderUser_Update]') IS NOT NULL -BEGIN - DROP PROCEDURE [dbo].[ProviderOrganizationProviderUser_Update] -END -GO - -CREATE PROCEDURE [dbo].[ProviderOrganizationProviderUser_Update] - @Id UNIQUEIDENTIFIER, - @ProviderOrganizationId UNIQUEIDENTIFIER, - @ProviderUserId UNIQUEIDENTIFIER, - @Type TINYINT, - @Permissions NVARCHAR(MAX), - @CreationDate DATETIME2(7), - @RevisionDate DATETIME2(7) -AS -BEGIN - SET NOCOUNT ON - - UPDATE - [dbo].[ProviderOrganizationProviderUser] - SET - [ProviderOrganizationId] = @ProviderOrganizationId, - [ProviderUserId] = @ProviderUserId, - [Type] = @Type, - [Permissions] = @Permissions, - [CreationDate] = @CreationDate, - [RevisionDate] = @RevisionDate - WHERE - [Id] = @Id - - EXEC [dbo].[User_BumpAccountRevisionDateByProviderUserId] @ProviderUserId -END -GO - IF OBJECT_ID('[dbo].[ProviderUser_ReadCountByProviderIdEmail]') IS NOT NULL BEGIN DROP PROCEDURE [dbo].[ProviderUser_ReadCountByProviderIdEmail] @@ -1163,6 +1015,7 @@ BEGIN SELECT PU.[Id], + PU.[UserId], U.[PublicKey] FROM @ProviderUserIds PUIDs @@ -1269,31 +1122,6 @@ LEFT JOIN [dbo].[Provider] P ON P.[Id] = PO.[ProviderId] GO -IF OBJECT_ID('[dbo].[ProviderOrganization_ReadByUserId]') IS NOT NULL - BEGIN - DROP PROCEDURE [dbo].[ProviderOrganization_ReadByUserId] - END -GO - -CREATE PROCEDURE [dbo].[ProviderOrganization_ReadByUserId] -@UserId UNIQUEIDENTIFIER -AS -BEGIN - SET NOCOUNT ON - - SELECT - PO.* - FROM - [dbo].[ProviderOrganizationView] PO - INNER JOIN - [dbo].[Provider] P ON PO.[ProviderId] = P.[Id] - INNER JOIN - [dbo].[ProviderUser] PU ON P.[Id] = PU.[ProviderId] - WHERE - PU.[UserId] = @UserId -END -GO - IF EXISTS(SELECT * FROM sys.views WHERE [Name] = 'ProviderUserProviderOrganizationDetailsView') BEGIN DROP VIEW [dbo].[ProviderUserProviderOrganizationDetailsView]; @@ -1328,6 +1156,7 @@ SELECT PU.[Status], PU.[Type], PO.[ProviderId], + PU.[Id] ProviderUserId, P.[Name] ProviderName FROM [dbo].[ProviderUser] PU @@ -1360,3 +1189,222 @@ BEGIN [UserId] = @UserId AND (@Status IS NULL OR [Status] = @Status) END +GO + +IF OBJECT_ID('[dbo].[ProviderOrganizationProviderUser_Create]') IS NOT NULL + BEGIN + DROP PROCEDURE [dbo].[ProviderOrganizationProviderUser_Create] + END +GO + +IF OBJECT_ID('[dbo].[ProviderOrganizationProviderUser_Update]') IS NOT NULL + BEGIN + DROP PROCEDURE [dbo].[ProviderOrganizationProviderUser_Update] + END +GO + +IF OBJECT_ID('[dbo].[ProviderOrganizationProviderUser_DeleteById]') IS NOT NULL + BEGIN + DROP PROCEDURE [dbo].[ProviderOrganizationProviderUser_DeleteById] + END +GO + +IF OBJECT_ID('[dbo].[ProviderOrganizationProviderUser_ReadById]') IS NOT NULL + BEGIN + DROP PROCEDURE [dbo].[ProviderOrganizationProviderUser_ReadById] + END +GO + +IF OBJECT_ID('[dbo].[ProviderOrganizationProviderUser]') IS NOT NULL + BEGIN + DROP TABLE [dbo].[ProviderOrganizationProviderUser]; + END +GO + +IF OBJECT_ID('[dbo].[ProviderOrganization_ReadByUserId]') IS NOT NULL + BEGIN + DROP PROCEDURE [dbo].[ProviderOrganization_ReadByUserId] + END +GO + +IF COL_LENGTH('[dbo].[OrganizationUser]', 'ResetPasswordKey') IS NULL + BEGIN + ALTER TABLE + [dbo].[OrganizationUser] + ADD + [ResetPasswordKey] VARCHAR(MAX) NULL + END +GO + +IF COL_LENGTH('[dbo].[Event]', 'ProviderId') IS NULL + BEGIN + ALTER TABLE + [dbo].[Event] + ADD + [ProviderId] UNIQUEIDENTIFIER NULL + END +GO + +IF COL_LENGTH('[dbo].[Event]', 'ProviderUserId') IS NULL + BEGIN + ALTER TABLE + [dbo].[Event] + ADD + [ProviderUserId] UNIQUEIDENTIFIER NULL + END +GO + +IF OBJECT_ID('[dbo].[Event_Create]') IS NOT NULL + BEGIN + DROP PROCEDURE [dbo].[Event_Create] + END +GO + +CREATE PROCEDURE [dbo].[Event_Create] + @Id UNIQUEIDENTIFIER OUTPUT, + @Type INT, + @UserId UNIQUEIDENTIFIER, + @OrganizationId UNIQUEIDENTIFIER, + @ProviderId UNIQUEIDENTIFIER, + @CipherId UNIQUEIDENTIFIER, + @CollectionId UNIQUEIDENTIFIER, + @PolicyId UNIQUEIDENTIFIER, + @GroupId UNIQUEIDENTIFIER, + @OrganizationUserId UNIQUEIDENTIFIER, + @ProviderUserId UNIQUEIDENTIFIER, + @ActingUserId UNIQUEIDENTIFIER, + @DeviceType SMALLINT, + @IpAddress VARCHAR(50), + @Date DATETIME2(7) +AS +BEGIN + SET NOCOUNT ON + + INSERT INTO [dbo].[Event] + ( + [Id], + [Type], + [UserId], + [OrganizationId], + [ProviderId], + [CipherId], + [CollectionId], + [PolicyId], + [GroupId], + [OrganizationUserId], + [ProviderUserId], + [ActingUserId], + [DeviceType], + [IpAddress], + [Date] + ) + VALUES + ( + @Id, + @Type, + @UserId, + @OrganizationId, + @ProviderId, + @CipherId, + @CollectionId, + @PolicyId, + @GroupId, + @OrganizationUserId, + @ProviderUserId, + @ActingUserId, + @DeviceType, + @IpAddress, + @Date + ) +END +GO + +IF OBJECT_ID('[dbo].[EventView]') IS NOT NULL + BEGIN + EXECUTE sp_refreshview N'[dbo].[EventView]'; + END +GO + +IF OBJECT_ID('[dbo].[Event_ReadPageByProviderId]') IS NOT NULL + BEGIN + DROP PROCEDURE [dbo].[Event_ReadPageByProviderId] + END +GO + +CREATE PROCEDURE [dbo].[Event_ReadPageByProviderId] + @ProviderId UNIQUEIDENTIFIER, + @StartDate DATETIME2(7), + @EndDate DATETIME2(7), + @BeforeDate DATETIME2(7), + @PageSize INT +AS +BEGIN + SET NOCOUNT ON + + SELECT + * + FROM + [dbo].[EventView] + WHERE + [Date] >= @StartDate + AND (@BeforeDate IS NOT NULL OR [Date] <= @EndDate) + AND (@BeforeDate IS NULL OR [Date] < @BeforeDate) + AND [Providerid] = @ProviderId + ORDER BY [Date] DESC + OFFSET 0 ROWS + FETCH NEXT @PageSize ROWS ONLY +END +GO + +IF OBJECT_ID('[dbo].[Event_ReadPageByProviderIdActingUserId]') IS NOT NULL + BEGIN + DROP PROCEDURE [dbo].[Event_ReadPageByProviderIdActingUserId] + END +GO + +CREATE PROCEDURE [dbo].[Event_ReadPageByProviderIdActingUserId] + @ProviderId UNIQUEIDENTIFIER, + @ActingUserId UNIQUEIDENTIFIER, + @StartDate DATETIME2(7), + @EndDate DATETIME2(7), + @BeforeDate DATETIME2(7), + @PageSize INT +AS +BEGIN + SET NOCOUNT ON + + SELECT + * + FROM + [dbo].[EventView] + WHERE + [Date] >= @StartDate + AND (@BeforeDate IS NOT NULL OR [Date] <= @EndDate) + AND (@BeforeDate IS NULL OR [Date] < @BeforeDate) + AND [ProviderId] = @ProviderId + AND [ActingUserId] = @ActingUserId + ORDER BY [Date] DESC + OFFSET 0 ROWS + FETCH NEXT @PageSize ROWS ONLY +END +GO + +IF OBJECT_ID('[dbo].[ProviderOrganization_ReadByOrganizationId]') IS NOT NULL + BEGIN + DROP PROCEDURE [dbo].[ProviderOrganization_ReadByOrganizationId] + END +GO + +CREATE PROCEDURE [dbo].[ProviderOrganization_ReadByOrganizationId] +@OrganizationId UNIQUEIDENTIFIER +AS +BEGIN + SET NOCOUNT ON + + SELECT + * + FROM + [dbo].[ProviderOrganizationView] + WHERE + [OrganizationId] = @OrganizationId +END diff --git a/util/MySqlMigrations/Migrations/20210709095522_RemoveProviderOrganizationProviderUser.Designer.cs b/util/MySqlMigrations/Migrations/20210709095522_RemoveProviderOrganizationProviderUser.Designer.cs new file mode 100644 index 0000000000..0fc1de79a1 --- /dev/null +++ b/util/MySqlMigrations/Migrations/20210709095522_RemoveProviderOrganizationProviderUser.Designer.cs @@ -0,0 +1,1480 @@ +// +using System; +using Bit.Core.Repositories.EntityFramework; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace Bit.MySqlMigrations.Migrations +{ + [DbContext(typeof(DatabaseContext))] + [Migration("20210709095522_RemoveProviderOrganizationProviderUser")] + partial class RemoveProviderOrganizationProviderUser + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 64) + .HasAnnotation("ProductVersion", "5.0.5"); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Cipher", b => + { + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("Attachments") + .HasColumnType("longtext"); + + b.Property("CreationDate") + .HasColumnType("datetime(6)"); + + b.Property("Data") + .HasColumnType("longtext"); + + b.Property("DeletedDate") + .HasColumnType("datetime(6)"); + + b.Property("Favorites") + .HasColumnType("longtext"); + + b.Property("Folders") + .HasColumnType("longtext"); + + b.Property("OrganizationId") + .HasColumnType("char(36)"); + + b.Property("Reprompt") + .HasColumnType("tinyint unsigned"); + + b.Property("RevisionDate") + .HasColumnType("datetime(6)"); + + b.Property("Type") + .HasColumnType("tinyint unsigned"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("UserId"); + + b.ToTable("Cipher"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Collection", b => + { + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("CreationDate") + .HasColumnType("datetime(6)"); + + b.Property("ExternalId") + .HasMaxLength(300) + .HasColumnType("varchar(300)"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("OrganizationId") + .HasColumnType("char(36)"); + + b.Property("RevisionDate") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Collection"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.CollectionCipher", b => + { + b.Property("CollectionId") + .HasColumnType("char(36)"); + + b.Property("CipherId") + .HasColumnType("char(36)"); + + b.HasKey("CollectionId", "CipherId"); + + b.HasIndex("CipherId"); + + b.ToTable("CollectionCipher"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.CollectionGroup", b => + { + b.Property("CollectionId") + .HasColumnType("char(36)"); + + b.Property("GroupId") + .HasColumnType("char(36)"); + + b.Property("HidePasswords") + .HasColumnType("tinyint(1)"); + + b.Property("ReadOnly") + .HasColumnType("tinyint(1)"); + + b.HasKey("CollectionId", "GroupId"); + + b.HasIndex("GroupId"); + + b.ToTable("CollectionGroups"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.CollectionUser", b => + { + b.Property("CollectionId") + .HasColumnType("char(36)"); + + b.Property("OrganizationUserId") + .HasColumnType("char(36)"); + + b.Property("HidePasswords") + .HasColumnType("tinyint(1)"); + + b.Property("ReadOnly") + .HasColumnType("tinyint(1)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("CollectionId", "OrganizationUserId"); + + b.HasIndex("OrganizationUserId"); + + b.HasIndex("UserId"); + + b.ToTable("CollectionUsers"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Device", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreationDate") + .HasColumnType("datetime(6)"); + + b.Property("Identifier") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("Name") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("PushToken") + .HasMaxLength(255) + .HasColumnType("varchar(255)"); + + b.Property("RevisionDate") + .HasColumnType("datetime(6)"); + + b.Property("Type") + .HasColumnType("tinyint unsigned"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Device"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.EmergencyAccess", b => + { + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("CreationDate") + .HasColumnType("datetime(6)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("GranteeId") + .HasColumnType("char(36)"); + + b.Property("GrantorId") + .HasColumnType("char(36)"); + + b.Property("KeyEncrypted") + .HasColumnType("longtext"); + + b.Property("LastNotificationDate") + .HasColumnType("datetime(6)"); + + b.Property("RecoveryInitiatedDate") + .HasColumnType("datetime(6)"); + + b.Property("RevisionDate") + .HasColumnType("datetime(6)"); + + b.Property("Status") + .HasColumnType("tinyint unsigned"); + + b.Property("Type") + .HasColumnType("tinyint unsigned"); + + b.Property("WaitTimeDays") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("GranteeId"); + + b.HasIndex("GrantorId"); + + b.ToTable("EmergencyAccess"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Event", b => + { + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("ActingUserId") + .HasColumnType("char(36)"); + + b.Property("CipherId") + .HasColumnType("char(36)"); + + b.Property("CollectionId") + .HasColumnType("char(36)"); + + b.Property("Date") + .HasColumnType("datetime(6)"); + + b.Property("DeviceType") + .HasColumnType("tinyint unsigned"); + + b.Property("GroupId") + .HasColumnType("char(36)"); + + b.Property("IpAddress") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("OrganizationId") + .HasColumnType("char(36)"); + + b.Property("OrganizationUserId") + .HasColumnType("char(36)"); + + b.Property("PolicyId") + .HasColumnType("char(36)"); + + b.Property("ProviderId") + .HasColumnType("char(36)"); + + b.Property("ProviderUserId") + .HasColumnType("char(36)"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.ToTable("Event"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Folder", b => + { + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("CreationDate") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("RevisionDate") + .HasColumnType("datetime(6)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Folder"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Grant", b => + { + b.Property("Key") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("ClientId") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("ConsumedDate") + .HasColumnType("datetime(6)"); + + b.Property("CreationDate") + .HasColumnType("datetime(6)"); + + b.Property("Data") + .HasColumnType("longtext"); + + b.Property("Description") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("ExpirationDate") + .HasColumnType("datetime(6)"); + + b.Property("SessionId") + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.Property("SubjectId") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("Type") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.HasKey("Key"); + + b.ToTable("Grant"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Group", b => + { + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("AccessAll") + .HasColumnType("tinyint(1)"); + + b.Property("CreationDate") + .HasColumnType("datetime(6)"); + + b.Property("ExternalId") + .HasMaxLength(300) + .HasColumnType("varchar(300)"); + + b.Property("Name") + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.Property("OrganizationId") + .HasColumnType("char(36)"); + + b.Property("RevisionDate") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Group"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.GroupUser", b => + { + b.Property("GroupId") + .HasColumnType("char(36)"); + + b.Property("OrganizationUserId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("GroupId", "OrganizationUserId"); + + b.HasIndex("OrganizationUserId"); + + b.HasIndex("UserId"); + + b.ToTable("GroupUser"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Installation", b => + { + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("CreationDate") + .HasColumnType("datetime(6)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("Key") + .HasMaxLength(150) + .HasColumnType("varchar(150)"); + + b.HasKey("Id"); + + b.ToTable("Installation"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Organization", b => + { + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("ApiKey") + .HasMaxLength(30) + .HasColumnType("varchar(30)"); + + b.Property("BillingEmail") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("BusinessAddress1") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("BusinessAddress2") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("BusinessAddress3") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("BusinessCountry") + .HasMaxLength(2) + .HasColumnType("varchar(2)"); + + b.Property("BusinessName") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("BusinessTaxNumber") + .HasMaxLength(30) + .HasColumnType("varchar(30)"); + + b.Property("CreationDate") + .HasColumnType("datetime(6)"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("ExpirationDate") + .HasColumnType("datetime(6)"); + + b.Property("Gateway") + .HasColumnType("tinyint unsigned"); + + b.Property("GatewayCustomerId") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("GatewaySubscriptionId") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("Identifier") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("LicenseKey") + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.Property("MaxCollections") + .HasColumnType("smallint"); + + b.Property("MaxStorageGb") + .HasColumnType("smallint"); + + b.Property("Name") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("Plan") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("PlanType") + .HasColumnType("tinyint unsigned"); + + b.Property("PrivateKey") + .HasColumnType("longtext"); + + b.Property("PublicKey") + .HasColumnType("longtext"); + + b.Property("ReferenceData") + .HasColumnType("longtext"); + + b.Property("RevisionDate") + .HasColumnType("datetime(6)"); + + b.Property("Seats") + .HasColumnType("int"); + + b.Property("SelfHost") + .HasColumnType("tinyint(1)"); + + b.Property("Storage") + .HasColumnType("bigint"); + + b.Property("TwoFactorProviders") + .HasColumnType("longtext"); + + b.Property("Use2fa") + .HasColumnType("tinyint(1)"); + + b.Property("UseApi") + .HasColumnType("tinyint(1)"); + + b.Property("UseDirectory") + .HasColumnType("tinyint(1)"); + + b.Property("UseEvents") + .HasColumnType("tinyint(1)"); + + b.Property("UseGroups") + .HasColumnType("tinyint(1)"); + + b.Property("UsePolicies") + .HasColumnType("tinyint(1)"); + + b.Property("UseResetPassword") + .HasColumnType("tinyint(1)"); + + b.Property("UseSso") + .HasColumnType("tinyint(1)"); + + b.Property("UseTotp") + .HasColumnType("tinyint(1)"); + + b.Property("UsersGetPremium") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("Organization"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.OrganizationUser", b => + { + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("AccessAll") + .HasColumnType("tinyint(1)"); + + b.Property("CreationDate") + .HasColumnType("datetime(6)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("ExternalId") + .HasMaxLength(300) + .HasColumnType("varchar(300)"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.Property("OrganizationId") + .HasColumnType("char(36)"); + + b.Property("Permissions") + .HasColumnType("longtext"); + + b.Property("ResetPasswordKey") + .HasColumnType("longtext"); + + b.Property("RevisionDate") + .HasColumnType("datetime(6)"); + + b.Property("Status") + .HasColumnType("tinyint unsigned"); + + b.Property("Type") + .HasColumnType("tinyint unsigned"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("UserId"); + + b.ToTable("OrganizationUser"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Policy", b => + { + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("CreationDate") + .HasColumnType("datetime(6)"); + + b.Property("Data") + .HasColumnType("longtext"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("OrganizationId") + .HasColumnType("char(36)"); + + b.Property("RevisionDate") + .HasColumnType("datetime(6)"); + + b.Property("Type") + .HasColumnType("tinyint unsigned"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Policy"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Provider.Provider", b => + { + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("BillingEmail") + .HasColumnType("longtext"); + + b.Property("BusinessAddress1") + .HasColumnType("longtext"); + + b.Property("BusinessAddress2") + .HasColumnType("longtext"); + + b.Property("BusinessAddress3") + .HasColumnType("longtext"); + + b.Property("BusinessCountry") + .HasColumnType("longtext"); + + b.Property("BusinessName") + .HasColumnType("longtext"); + + b.Property("BusinessTaxNumber") + .HasColumnType("longtext"); + + b.Property("CreationDate") + .HasColumnType("datetime(6)"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("RevisionDate") + .HasColumnType("datetime(6)"); + + b.Property("Status") + .HasColumnType("tinyint unsigned"); + + b.Property("UseEvents") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("Provider"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Provider.ProviderOrganization", b => + { + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("CreationDate") + .HasColumnType("datetime(6)"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.Property("OrganizationId") + .HasColumnType("char(36)"); + + b.Property("ProviderId") + .HasColumnType("char(36)"); + + b.Property("RevisionDate") + .HasColumnType("datetime(6)"); + + b.Property("Settings") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("ProviderId"); + + b.ToTable("ProviderOrganization"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Provider.ProviderUser", b => + { + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("CreationDate") + .HasColumnType("datetime(6)"); + + b.Property("Email") + .HasColumnType("longtext"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.Property("Permissions") + .HasColumnType("longtext"); + + b.Property("ProviderId") + .HasColumnType("char(36)"); + + b.Property("RevisionDate") + .HasColumnType("datetime(6)"); + + b.Property("Status") + .HasColumnType("tinyint unsigned"); + + b.Property("Type") + .HasColumnType("tinyint unsigned"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("ProviderId"); + + b.HasIndex("UserId"); + + b.ToTable("ProviderUser"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Send", b => + { + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("AccessCount") + .HasColumnType("int"); + + b.Property("CreationDate") + .HasColumnType("datetime(6)"); + + b.Property("Data") + .HasColumnType("longtext"); + + b.Property("DeletionDate") + .HasColumnType("datetime(6)"); + + b.Property("Disabled") + .HasColumnType("tinyint(1)"); + + b.Property("ExpirationDate") + .HasColumnType("datetime(6)"); + + b.Property("HideEmail") + .HasColumnType("tinyint(1)"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.Property("MaxAccessCount") + .HasColumnType("int"); + + b.Property("OrganizationId") + .HasColumnType("char(36)"); + + b.Property("Password") + .HasMaxLength(300) + .HasColumnType("varchar(300)"); + + b.Property("RevisionDate") + .HasColumnType("datetime(6)"); + + b.Property("Type") + .HasColumnType("tinyint unsigned"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("UserId"); + + b.ToTable("Send"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.SsoConfig", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime(6)"); + + b.Property("Data") + .HasColumnType("longtext"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("OrganizationId") + .HasColumnType("char(36)"); + + b.Property("RevisionDate") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.ToTable("SsoConfig"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.SsoUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreationDate") + .HasColumnType("datetime(6)"); + + b.Property("ExternalId") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("OrganizationId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("UserId"); + + b.ToTable("SsoUser"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.TaxRate", b => + { + b.Property("Id") + .HasMaxLength(40) + .HasColumnType("varchar(40)"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("Country") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("PostalCode") + .HasMaxLength(10) + .HasColumnType("varchar(10)"); + + b.Property("Rate") + .HasColumnType("decimal(65,30)"); + + b.Property("State") + .HasMaxLength(2) + .HasColumnType("varchar(2)"); + + b.HasKey("Id"); + + b.ToTable("TaxRate"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Transaction", b => + { + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("Amount") + .HasColumnType("decimal(65,30)"); + + b.Property("CreationDate") + .HasColumnType("datetime(6)"); + + b.Property("Details") + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.Property("Gateway") + .HasColumnType("tinyint unsigned"); + + b.Property("GatewayId") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("OrganizationId") + .HasColumnType("char(36)"); + + b.Property("PaymentMethodType") + .HasColumnType("tinyint unsigned"); + + b.Property("Refunded") + .HasColumnType("tinyint(1)"); + + b.Property("RefundedAmount") + .HasColumnType("decimal(65,30)"); + + b.Property("Type") + .HasColumnType("tinyint unsigned"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("UserId"); + + b.ToTable("Transaction"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.U2f", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AppId") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("Challenge") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("CreationDate") + .HasColumnType("datetime(6)"); + + b.Property("KeyHandle") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.Property("Version") + .HasMaxLength(20) + .HasColumnType("varchar(20)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("U2f"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.User", b => + { + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("AccountRevisionDate") + .HasColumnType("datetime(6)"); + + b.Property("ApiKey") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("varchar(30)"); + + b.Property("CreationDate") + .HasColumnType("datetime(6)"); + + b.Property("Culture") + .HasMaxLength(10) + .HasColumnType("varchar(10)"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("EmailVerified") + .HasColumnType("tinyint(1)"); + + b.Property("EquivalentDomains") + .HasColumnType("longtext"); + + b.Property("ExcludedGlobalEquivalentDomains") + .HasColumnType("longtext"); + + b.Property("Gateway") + .HasColumnType("tinyint unsigned"); + + b.Property("GatewayCustomerId") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("GatewaySubscriptionId") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("Kdf") + .HasColumnType("tinyint unsigned"); + + b.Property("KdfIterations") + .HasColumnType("int"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.Property("LicenseKey") + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.Property("MasterPassword") + .HasMaxLength(300) + .HasColumnType("varchar(300)"); + + b.Property("MasterPasswordHint") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("MaxStorageGb") + .HasColumnType("smallint"); + + b.Property("Name") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("Premium") + .HasColumnType("tinyint(1)"); + + b.Property("PremiumExpirationDate") + .HasColumnType("datetime(6)"); + + b.Property("PrivateKey") + .HasColumnType("longtext"); + + b.Property("PublicKey") + .HasColumnType("longtext"); + + b.Property("ReferenceData") + .HasColumnType("longtext"); + + b.Property("RenewalReminderDate") + .HasColumnType("datetime(6)"); + + b.Property("RevisionDate") + .HasColumnType("datetime(6)"); + + b.Property("SecurityStamp") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("Storage") + .HasColumnType("bigint"); + + b.Property("TwoFactorProviders") + .HasColumnType("longtext"); + + b.Property("TwoFactorRecoveryCode") + .HasMaxLength(32) + .HasColumnType("varchar(32)"); + + b.HasKey("Id"); + + b.ToTable("User"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Cipher", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Organization", "Organization") + .WithMany("Ciphers") + .HasForeignKey("OrganizationId"); + + b.HasOne("Bit.Core.Models.EntityFramework.User", "User") + .WithMany("Ciphers") + .HasForeignKey("UserId"); + + b.Navigation("Organization"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Collection", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.CollectionCipher", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Cipher", "Cipher") + .WithMany("CollectionCiphers") + .HasForeignKey("CipherId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Bit.Core.Models.EntityFramework.Collection", "Collection") + .WithMany("CollectionCiphers") + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Cipher"); + + b.Navigation("Collection"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.CollectionGroup", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Collection", "Collection") + .WithMany("CollectionGroups") + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Bit.Core.Models.EntityFramework.Group", "Group") + .WithMany() + .HasForeignKey("GroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Collection"); + + b.Navigation("Group"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.CollectionUser", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Collection", "Collection") + .WithMany("CollectionUsers") + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Bit.Core.Models.EntityFramework.OrganizationUser", "OrganizationUser") + .WithMany("CollectionUsers") + .HasForeignKey("OrganizationUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Bit.Core.Models.EntityFramework.User", null) + .WithMany("CollectionUsers") + .HasForeignKey("UserId"); + + b.Navigation("Collection"); + + b.Navigation("OrganizationUser"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Device", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.EmergencyAccess", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.User", "Grantee") + .WithMany() + .HasForeignKey("GranteeId"); + + b.HasOne("Bit.Core.Models.EntityFramework.User", "Grantor") + .WithMany() + .HasForeignKey("GrantorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Grantee"); + + b.Navigation("Grantor"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Folder", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.User", "User") + .WithMany("Folders") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Group", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Organization", "Organization") + .WithMany("Groups") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.GroupUser", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Group", "Group") + .WithMany("GroupUsers") + .HasForeignKey("GroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Bit.Core.Models.EntityFramework.OrganizationUser", "OrganizationUser") + .WithMany() + .HasForeignKey("OrganizationUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Bit.Core.Models.EntityFramework.User", null) + .WithMany("GroupUsers") + .HasForeignKey("UserId"); + + b.Navigation("Group"); + + b.Navigation("OrganizationUser"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.OrganizationUser", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Organization", "Organization") + .WithMany("OrganizationUsers") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Bit.Core.Models.EntityFramework.User", "User") + .WithMany("OrganizationUsers") + .HasForeignKey("UserId"); + + b.Navigation("Organization"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Policy", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Organization", "Organization") + .WithMany("Policies") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Provider.ProviderOrganization", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Bit.Core.Models.EntityFramework.Provider.Provider", "Provider") + .WithMany() + .HasForeignKey("ProviderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + + b.Navigation("Provider"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Provider.ProviderUser", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Provider.Provider", "Provider") + .WithMany() + .HasForeignKey("ProviderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Bit.Core.Models.EntityFramework.User", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("Provider"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Send", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId"); + + b.HasOne("Bit.Core.Models.EntityFramework.User", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("Organization"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.SsoConfig", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Organization", "Organization") + .WithMany("SsoConfigs") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.SsoUser", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Organization", "Organization") + .WithMany("SsoUsers") + .HasForeignKey("OrganizationId"); + + b.HasOne("Bit.Core.Models.EntityFramework.User", "User") + .WithMany("SsoUsers") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Transaction", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Organization", "Organization") + .WithMany("Transactions") + .HasForeignKey("OrganizationId"); + + b.HasOne("Bit.Core.Models.EntityFramework.User", "User") + .WithMany("Transactions") + .HasForeignKey("UserId"); + + b.Navigation("Organization"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.U2f", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.User", "User") + .WithMany("U2fs") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Cipher", b => + { + b.Navigation("CollectionCiphers"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Collection", b => + { + b.Navigation("CollectionCiphers"); + + b.Navigation("CollectionGroups"); + + b.Navigation("CollectionUsers"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Group", b => + { + b.Navigation("GroupUsers"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Organization", b => + { + b.Navigation("Ciphers"); + + b.Navigation("Groups"); + + b.Navigation("OrganizationUsers"); + + b.Navigation("Policies"); + + b.Navigation("SsoConfigs"); + + b.Navigation("SsoUsers"); + + b.Navigation("Transactions"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.OrganizationUser", b => + { + b.Navigation("CollectionUsers"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.User", b => + { + b.Navigation("Ciphers"); + + b.Navigation("CollectionUsers"); + + b.Navigation("Folders"); + + b.Navigation("GroupUsers"); + + b.Navigation("OrganizationUsers"); + + b.Navigation("SsoUsers"); + + b.Navigation("Transactions"); + + b.Navigation("U2fs"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/util/MySqlMigrations/Migrations/20210709095522_RemoveProviderOrganizationProviderUser.cs b/util/MySqlMigrations/Migrations/20210709095522_RemoveProviderOrganizationProviderUser.cs new file mode 100644 index 0000000000..0fcbe231c0 --- /dev/null +++ b/util/MySqlMigrations/Migrations/20210709095522_RemoveProviderOrganizationProviderUser.cs @@ -0,0 +1,91 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Bit.MySqlMigrations.Migrations +{ + public partial class RemoveProviderOrganizationProviderUser : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "ProviderOrganizationProviderUser"); + + migrationBuilder.AddColumn( + name: "UseEvents", + table: "Provider", + type: "tinyint(1)", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "ProviderId", + table: "Event", + type: "char(36)", + nullable: true, + collation: "ascii_general_ci"); + + migrationBuilder.AddColumn( + name: "ProviderUserId", + table: "Event", + type: "char(36)", + nullable: true, + collation: "ascii_general_ci"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "UseEvents", + table: "Provider"); + + migrationBuilder.DropColumn( + name: "ProviderId", + table: "Event"); + + migrationBuilder.DropColumn( + name: "ProviderUserId", + table: "Event"); + + migrationBuilder.CreateTable( + name: "ProviderOrganizationProviderUser", + columns: table => new + { + Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + CreationDate = table.Column(type: "datetime(6)", nullable: false), + Permissions = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + ProviderOrganizationId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + ProviderUserId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + RevisionDate = table.Column(type: "datetime(6)", nullable: false), + Type = table.Column(type: "tinyint unsigned", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ProviderOrganizationProviderUser", x => x.Id); + table.ForeignKey( + name: "FK_ProviderOrganizationProviderUser_ProviderOrganization_Provid~", + column: x => x.ProviderOrganizationId, + principalTable: "ProviderOrganization", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_ProviderOrganizationProviderUser_ProviderUser_ProviderUserId", + column: x => x.ProviderUserId, + principalTable: "ProviderUser", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateIndex( + name: "IX_ProviderOrganizationProviderUser_ProviderOrganizationId", + table: "ProviderOrganizationProviderUser", + column: "ProviderOrganizationId"); + + migrationBuilder.CreateIndex( + name: "IX_ProviderOrganizationProviderUser_ProviderUserId", + table: "ProviderOrganizationProviderUser", + column: "ProviderUserId"); + } + } +} diff --git a/util/MySqlMigrations/Migrations/DatabaseContextModelSnapshot.cs b/util/MySqlMigrations/Migrations/DatabaseContextModelSnapshot.cs index 244f0865df..43dcc89284 100644 --- a/util/MySqlMigrations/Migrations/DatabaseContextModelSnapshot.cs +++ b/util/MySqlMigrations/Migrations/DatabaseContextModelSnapshot.cs @@ -275,6 +275,12 @@ namespace Bit.MySqlMigrations.Migrations b.Property("PolicyId") .HasColumnType("char(36)"); + b.Property("ProviderId") + .HasColumnType("char(36)"); + + b.Property("ProviderUserId") + .HasColumnType("char(36)"); + b.Property("Type") .HasColumnType("int"); @@ -693,6 +699,9 @@ namespace Bit.MySqlMigrations.Migrations b.Property("Status") .HasColumnType("tinyint unsigned"); + b.Property("UseEvents") + .HasColumnType("tinyint(1)"); + b.HasKey("Id"); b.ToTable("Provider"); @@ -730,38 +739,6 @@ namespace Bit.MySqlMigrations.Migrations b.ToTable("ProviderOrganization"); }); - modelBuilder.Entity("Bit.Core.Models.EntityFramework.Provider.ProviderOrganizationProviderUser", b => - { - b.Property("Id") - .HasColumnType("char(36)"); - - b.Property("CreationDate") - .HasColumnType("datetime(6)"); - - b.Property("Permissions") - .HasColumnType("longtext"); - - b.Property("ProviderOrganizationId") - .HasColumnType("char(36)"); - - b.Property("ProviderUserId") - .HasColumnType("char(36)"); - - b.Property("RevisionDate") - .HasColumnType("datetime(6)"); - - b.Property("Type") - .HasColumnType("tinyint unsigned"); - - b.HasKey("Id"); - - b.HasIndex("ProviderOrganizationId"); - - b.HasIndex("ProviderUserId"); - - b.ToTable("ProviderOrganizationProviderUser"); - }); - modelBuilder.Entity("Bit.Core.Models.EntityFramework.Provider.ProviderUser", b => { b.Property("Id") @@ -1350,25 +1327,6 @@ namespace Bit.MySqlMigrations.Migrations b.Navigation("Provider"); }); - modelBuilder.Entity("Bit.Core.Models.EntityFramework.Provider.ProviderOrganizationProviderUser", b => - { - b.HasOne("Bit.Core.Models.EntityFramework.Provider.ProviderOrganization", "ProviderOrganization") - .WithMany() - .HasForeignKey("ProviderOrganizationId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Bit.Core.Models.EntityFramework.Provider.ProviderUser", "ProviderUser") - .WithMany() - .HasForeignKey("ProviderUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("ProviderOrganization"); - - b.Navigation("ProviderUser"); - }); - modelBuilder.Entity("Bit.Core.Models.EntityFramework.Provider.ProviderUser", b => { b.HasOne("Bit.Core.Models.EntityFramework.Provider.Provider", "Provider") diff --git a/util/PostgresMigrations/Migrations/20210709092227_RemoveProviderOrganizationProviderUser.Designer.cs b/util/PostgresMigrations/Migrations/20210709092227_RemoveProviderOrganizationProviderUser.Designer.cs new file mode 100644 index 0000000000..cce294ced5 --- /dev/null +++ b/util/PostgresMigrations/Migrations/20210709092227_RemoveProviderOrganizationProviderUser.Designer.cs @@ -0,0 +1,1489 @@ +// +using System; +using Bit.Core.Repositories.EntityFramework; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +namespace Bit.PostgresMigrations.Migrations +{ + [DbContext(typeof(DatabaseContext))] + [Migration("20210709092227_RemoveProviderOrganizationProviderUser")] + partial class RemoveProviderOrganizationProviderUser + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:CollationDefinition:postgresIndetermanisticCollation", "en-u-ks-primary,en-u-ks-primary,icu,False") + .HasAnnotation("Relational:MaxIdentifierLength", 63) + .HasAnnotation("ProductVersion", "5.0.5") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Cipher", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("Attachments") + .HasColumnType("text"); + + b.Property("CreationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Data") + .HasColumnType("text"); + + b.Property("DeletedDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Favorites") + .HasColumnType("text"); + + b.Property("Folders") + .HasColumnType("text"); + + b.Property("OrganizationId") + .HasColumnType("uuid"); + + b.Property("Reprompt") + .HasColumnType("smallint"); + + b.Property("RevisionDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Type") + .HasColumnType("smallint"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("UserId"); + + b.ToTable("Cipher"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Collection", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("CreationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("ExternalId") + .HasMaxLength(300) + .HasColumnType("character varying(300)"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("OrganizationId") + .HasColumnType("uuid"); + + b.Property("RevisionDate") + .HasColumnType("timestamp without time zone"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Collection"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.CollectionCipher", b => + { + b.Property("CollectionId") + .HasColumnType("uuid"); + + b.Property("CipherId") + .HasColumnType("uuid"); + + b.HasKey("CollectionId", "CipherId"); + + b.HasIndex("CipherId"); + + b.ToTable("CollectionCipher"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.CollectionGroup", b => + { + b.Property("CollectionId") + .HasColumnType("uuid"); + + b.Property("GroupId") + .HasColumnType("uuid"); + + b.Property("HidePasswords") + .HasColumnType("boolean"); + + b.Property("ReadOnly") + .HasColumnType("boolean"); + + b.HasKey("CollectionId", "GroupId"); + + b.HasIndex("GroupId"); + + b.ToTable("CollectionGroups"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.CollectionUser", b => + { + b.Property("CollectionId") + .HasColumnType("uuid"); + + b.Property("OrganizationUserId") + .HasColumnType("uuid"); + + b.Property("HidePasswords") + .HasColumnType("boolean"); + + b.Property("ReadOnly") + .HasColumnType("boolean"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("CollectionId", "OrganizationUserId"); + + b.HasIndex("OrganizationUserId"); + + b.HasIndex("UserId"); + + b.ToTable("CollectionUsers"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Device", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Identifier") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Name") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("PushToken") + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.Property("RevisionDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Type") + .HasColumnType("smallint"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Device"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.EmergencyAccess", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("CreationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("GranteeId") + .HasColumnType("uuid"); + + b.Property("GrantorId") + .HasColumnType("uuid"); + + b.Property("KeyEncrypted") + .HasColumnType("text"); + + b.Property("LastNotificationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("RecoveryInitiatedDate") + .HasColumnType("timestamp without time zone"); + + b.Property("RevisionDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("Type") + .HasColumnType("smallint"); + + b.Property("WaitTimeDays") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("GranteeId"); + + b.HasIndex("GrantorId"); + + b.ToTable("EmergencyAccess"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Event", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("ActingUserId") + .HasColumnType("uuid"); + + b.Property("CipherId") + .HasColumnType("uuid"); + + b.Property("CollectionId") + .HasColumnType("uuid"); + + b.Property("Date") + .HasColumnType("timestamp without time zone"); + + b.Property("DeviceType") + .HasColumnType("smallint"); + + b.Property("GroupId") + .HasColumnType("uuid"); + + b.Property("IpAddress") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("OrganizationId") + .HasColumnType("uuid"); + + b.Property("OrganizationUserId") + .HasColumnType("uuid"); + + b.Property("PolicyId") + .HasColumnType("uuid"); + + b.Property("ProviderId") + .HasColumnType("uuid"); + + b.Property("ProviderUserId") + .HasColumnType("uuid"); + + b.Property("Type") + .HasColumnType("integer"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.ToTable("Event"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Folder", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("CreationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("RevisionDate") + .HasColumnType("timestamp without time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Folder"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Grant", b => + { + b.Property("Key") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("ClientId") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("ConsumedDate") + .HasColumnType("timestamp without time zone"); + + b.Property("CreationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Data") + .HasColumnType("text"); + + b.Property("Description") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("ExpirationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("SessionId") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("SubjectId") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("Type") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Key"); + + b.ToTable("Grant"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Group", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("AccessAll") + .HasColumnType("boolean"); + + b.Property("CreationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("ExternalId") + .HasMaxLength(300) + .HasColumnType("character varying(300)"); + + b.Property("Name") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("OrganizationId") + .HasColumnType("uuid"); + + b.Property("RevisionDate") + .HasColumnType("timestamp without time zone"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Group"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.GroupUser", b => + { + b.Property("GroupId") + .HasColumnType("uuid"); + + b.Property("OrganizationUserId") + .HasColumnType("uuid"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("GroupId", "OrganizationUserId"); + + b.HasIndex("OrganizationUserId"); + + b.HasIndex("UserId"); + + b.ToTable("GroupUser"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Installation", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("CreationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("Key") + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.HasKey("Id"); + + b.ToTable("Installation"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Organization", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("ApiKey") + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.Property("BillingEmail") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("BusinessAddress1") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("BusinessAddress2") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("BusinessAddress3") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("BusinessCountry") + .HasMaxLength(2) + .HasColumnType("character varying(2)"); + + b.Property("BusinessName") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("BusinessTaxNumber") + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.Property("CreationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("ExpirationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Gateway") + .HasColumnType("smallint"); + + b.Property("GatewayCustomerId") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("GatewaySubscriptionId") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Identifier") + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .UseCollation("postgresIndetermanisticCollation"); + + b.Property("LicenseKey") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("MaxCollections") + .HasColumnType("smallint"); + + b.Property("MaxStorageGb") + .HasColumnType("smallint"); + + b.Property("Name") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Plan") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("PlanType") + .HasColumnType("smallint"); + + b.Property("PrivateKey") + .HasColumnType("text"); + + b.Property("PublicKey") + .HasColumnType("text"); + + b.Property("ReferenceData") + .HasColumnType("text"); + + b.Property("RevisionDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Seats") + .HasColumnType("integer"); + + b.Property("SelfHost") + .HasColumnType("boolean"); + + b.Property("Storage") + .HasColumnType("bigint"); + + b.Property("TwoFactorProviders") + .HasColumnType("text"); + + b.Property("Use2fa") + .HasColumnType("boolean"); + + b.Property("UseApi") + .HasColumnType("boolean"); + + b.Property("UseDirectory") + .HasColumnType("boolean"); + + b.Property("UseEvents") + .HasColumnType("boolean"); + + b.Property("UseGroups") + .HasColumnType("boolean"); + + b.Property("UsePolicies") + .HasColumnType("boolean"); + + b.Property("UseResetPassword") + .HasColumnType("boolean"); + + b.Property("UseSso") + .HasColumnType("boolean"); + + b.Property("UseTotp") + .HasColumnType("boolean"); + + b.Property("UsersGetPremium") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.ToTable("Organization"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.OrganizationUser", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("AccessAll") + .HasColumnType("boolean"); + + b.Property("CreationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ExternalId") + .HasMaxLength(300) + .HasColumnType("character varying(300)"); + + b.Property("Key") + .HasColumnType("text"); + + b.Property("OrganizationId") + .HasColumnType("uuid"); + + b.Property("Permissions") + .HasColumnType("text"); + + b.Property("ResetPasswordKey") + .HasColumnType("text"); + + b.Property("RevisionDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("Type") + .HasColumnType("smallint"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("UserId"); + + b.ToTable("OrganizationUser"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Policy", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("CreationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Data") + .HasColumnType("text"); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("OrganizationId") + .HasColumnType("uuid"); + + b.Property("RevisionDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Type") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Policy"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Provider.Provider", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("BillingEmail") + .HasColumnType("text"); + + b.Property("BusinessAddress1") + .HasColumnType("text"); + + b.Property("BusinessAddress2") + .HasColumnType("text"); + + b.Property("BusinessAddress3") + .HasColumnType("text"); + + b.Property("BusinessCountry") + .HasColumnType("text"); + + b.Property("BusinessName") + .HasColumnType("text"); + + b.Property("BusinessTaxNumber") + .HasColumnType("text"); + + b.Property("CreationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("RevisionDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("UseEvents") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.ToTable("Provider"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Provider.ProviderOrganization", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("CreationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Key") + .HasColumnType("text"); + + b.Property("OrganizationId") + .HasColumnType("uuid"); + + b.Property("ProviderId") + .HasColumnType("uuid"); + + b.Property("RevisionDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Settings") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("ProviderId"); + + b.ToTable("ProviderOrganization"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Provider.ProviderUser", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("CreationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Email") + .HasColumnType("text"); + + b.Property("Key") + .HasColumnType("text"); + + b.Property("Permissions") + .HasColumnType("text"); + + b.Property("ProviderId") + .HasColumnType("uuid"); + + b.Property("RevisionDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.Property("Type") + .HasColumnType("smallint"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ProviderId"); + + b.HasIndex("UserId"); + + b.ToTable("ProviderUser"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Send", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("AccessCount") + .HasColumnType("integer"); + + b.Property("CreationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Data") + .HasColumnType("text"); + + b.Property("DeletionDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Disabled") + .HasColumnType("boolean"); + + b.Property("ExpirationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("HideEmail") + .HasColumnType("boolean"); + + b.Property("Key") + .HasColumnType("text"); + + b.Property("MaxAccessCount") + .HasColumnType("integer"); + + b.Property("OrganizationId") + .HasColumnType("uuid"); + + b.Property("Password") + .HasMaxLength(300) + .HasColumnType("character varying(300)"); + + b.Property("RevisionDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Type") + .HasColumnType("smallint"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("UserId"); + + b.ToTable("Send"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.SsoConfig", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("CreationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Data") + .HasColumnType("text"); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("OrganizationId") + .HasColumnType("uuid"); + + b.Property("RevisionDate") + .HasColumnType("timestamp without time zone"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.ToTable("SsoConfig"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.SsoUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("CreationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("ExternalId") + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .UseCollation("postgresIndetermanisticCollation"); + + b.Property("OrganizationId") + .HasColumnType("uuid"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("UserId"); + + b.ToTable("SsoUser"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.TaxRate", b => + { + b.Property("Id") + .HasMaxLength(40) + .HasColumnType("character varying(40)"); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("Country") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("PostalCode") + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.Property("Rate") + .HasColumnType("numeric"); + + b.Property("State") + .HasMaxLength(2) + .HasColumnType("character varying(2)"); + + b.HasKey("Id"); + + b.ToTable("TaxRate"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Transaction", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("Amount") + .HasColumnType("numeric"); + + b.Property("CreationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Details") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Gateway") + .HasColumnType("smallint"); + + b.Property("GatewayId") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("OrganizationId") + .HasColumnType("uuid"); + + b.Property("PaymentMethodType") + .HasColumnType("smallint"); + + b.Property("Refunded") + .HasColumnType("boolean"); + + b.Property("RefundedAmount") + .HasColumnType("numeric"); + + b.Property("Type") + .HasColumnType("smallint"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("UserId"); + + b.ToTable("Transaction"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.U2f", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("AppId") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Challenge") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("CreationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("KeyHandle") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("Version") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("U2f"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.User", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("AccountRevisionDate") + .HasColumnType("timestamp without time zone"); + + b.Property("ApiKey") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.Property("CreationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("Culture") + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .UseCollation("postgresIndetermanisticCollation"); + + b.Property("EmailVerified") + .HasColumnType("boolean"); + + b.Property("EquivalentDomains") + .HasColumnType("text"); + + b.Property("ExcludedGlobalEquivalentDomains") + .HasColumnType("text"); + + b.Property("Gateway") + .HasColumnType("smallint"); + + b.Property("GatewayCustomerId") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("GatewaySubscriptionId") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Kdf") + .HasColumnType("smallint"); + + b.Property("KdfIterations") + .HasColumnType("integer"); + + b.Property("Key") + .HasColumnType("text"); + + b.Property("LicenseKey") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("MasterPassword") + .HasMaxLength(300) + .HasColumnType("character varying(300)"); + + b.Property("MasterPasswordHint") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("MaxStorageGb") + .HasColumnType("smallint"); + + b.Property("Name") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Premium") + .HasColumnType("boolean"); + + b.Property("PremiumExpirationDate") + .HasColumnType("timestamp without time zone"); + + b.Property("PrivateKey") + .HasColumnType("text"); + + b.Property("PublicKey") + .HasColumnType("text"); + + b.Property("ReferenceData") + .HasColumnType("text"); + + b.Property("RenewalReminderDate") + .HasColumnType("timestamp without time zone"); + + b.Property("RevisionDate") + .HasColumnType("timestamp without time zone"); + + b.Property("SecurityStamp") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Storage") + .HasColumnType("bigint"); + + b.Property("TwoFactorProviders") + .HasColumnType("text"); + + b.Property("TwoFactorRecoveryCode") + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.HasKey("Id"); + + b.ToTable("User"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Cipher", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Organization", "Organization") + .WithMany("Ciphers") + .HasForeignKey("OrganizationId"); + + b.HasOne("Bit.Core.Models.EntityFramework.User", "User") + .WithMany("Ciphers") + .HasForeignKey("UserId"); + + b.Navigation("Organization"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Collection", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.CollectionCipher", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Cipher", "Cipher") + .WithMany("CollectionCiphers") + .HasForeignKey("CipherId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Bit.Core.Models.EntityFramework.Collection", "Collection") + .WithMany("CollectionCiphers") + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Cipher"); + + b.Navigation("Collection"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.CollectionGroup", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Collection", "Collection") + .WithMany("CollectionGroups") + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Bit.Core.Models.EntityFramework.Group", "Group") + .WithMany() + .HasForeignKey("GroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Collection"); + + b.Navigation("Group"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.CollectionUser", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Collection", "Collection") + .WithMany("CollectionUsers") + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Bit.Core.Models.EntityFramework.OrganizationUser", "OrganizationUser") + .WithMany("CollectionUsers") + .HasForeignKey("OrganizationUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Bit.Core.Models.EntityFramework.User", null) + .WithMany("CollectionUsers") + .HasForeignKey("UserId"); + + b.Navigation("Collection"); + + b.Navigation("OrganizationUser"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Device", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.EmergencyAccess", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.User", "Grantee") + .WithMany() + .HasForeignKey("GranteeId"); + + b.HasOne("Bit.Core.Models.EntityFramework.User", "Grantor") + .WithMany() + .HasForeignKey("GrantorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Grantee"); + + b.Navigation("Grantor"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Folder", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.User", "User") + .WithMany("Folders") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Group", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Organization", "Organization") + .WithMany("Groups") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.GroupUser", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Group", "Group") + .WithMany("GroupUsers") + .HasForeignKey("GroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Bit.Core.Models.EntityFramework.OrganizationUser", "OrganizationUser") + .WithMany() + .HasForeignKey("OrganizationUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Bit.Core.Models.EntityFramework.User", null) + .WithMany("GroupUsers") + .HasForeignKey("UserId"); + + b.Navigation("Group"); + + b.Navigation("OrganizationUser"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.OrganizationUser", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Organization", "Organization") + .WithMany("OrganizationUsers") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Bit.Core.Models.EntityFramework.User", "User") + .WithMany("OrganizationUsers") + .HasForeignKey("UserId"); + + b.Navigation("Organization"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Policy", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Organization", "Organization") + .WithMany("Policies") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Provider.ProviderOrganization", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Bit.Core.Models.EntityFramework.Provider.Provider", "Provider") + .WithMany() + .HasForeignKey("ProviderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + + b.Navigation("Provider"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Provider.ProviderUser", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Provider.Provider", "Provider") + .WithMany() + .HasForeignKey("ProviderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Bit.Core.Models.EntityFramework.User", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("Provider"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Send", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId"); + + b.HasOne("Bit.Core.Models.EntityFramework.User", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("Organization"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.SsoConfig", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Organization", "Organization") + .WithMany("SsoConfigs") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.SsoUser", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Organization", "Organization") + .WithMany("SsoUsers") + .HasForeignKey("OrganizationId"); + + b.HasOne("Bit.Core.Models.EntityFramework.User", "User") + .WithMany("SsoUsers") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Transaction", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.Organization", "Organization") + .WithMany("Transactions") + .HasForeignKey("OrganizationId"); + + b.HasOne("Bit.Core.Models.EntityFramework.User", "User") + .WithMany("Transactions") + .HasForeignKey("UserId"); + + b.Navigation("Organization"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.U2f", b => + { + b.HasOne("Bit.Core.Models.EntityFramework.User", "User") + .WithMany("U2fs") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Cipher", b => + { + b.Navigation("CollectionCiphers"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Collection", b => + { + b.Navigation("CollectionCiphers"); + + b.Navigation("CollectionGroups"); + + b.Navigation("CollectionUsers"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Group", b => + { + b.Navigation("GroupUsers"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.Organization", b => + { + b.Navigation("Ciphers"); + + b.Navigation("Groups"); + + b.Navigation("OrganizationUsers"); + + b.Navigation("Policies"); + + b.Navigation("SsoConfigs"); + + b.Navigation("SsoUsers"); + + b.Navigation("Transactions"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.OrganizationUser", b => + { + b.Navigation("CollectionUsers"); + }); + + modelBuilder.Entity("Bit.Core.Models.EntityFramework.User", b => + { + b.Navigation("Ciphers"); + + b.Navigation("CollectionUsers"); + + b.Navigation("Folders"); + + b.Navigation("GroupUsers"); + + b.Navigation("OrganizationUsers"); + + b.Navigation("SsoUsers"); + + b.Navigation("Transactions"); + + b.Navigation("U2fs"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/util/PostgresMigrations/Migrations/20210709092227_RemoveProviderOrganizationProviderUser.cs b/util/PostgresMigrations/Migrations/20210709092227_RemoveProviderOrganizationProviderUser.cs new file mode 100644 index 0000000000..f094fdbd01 --- /dev/null +++ b/util/PostgresMigrations/Migrations/20210709092227_RemoveProviderOrganizationProviderUser.cs @@ -0,0 +1,76 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Bit.PostgresMigrations.Migrations +{ + public partial class RemoveProviderOrganizationProviderUser : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "ProviderOrganizationProviderUser"); + + migrationBuilder.AddColumn( + name: "ProviderId", + table: "Event", + type: "uuid", + nullable: true); + + migrationBuilder.AddColumn( + name: "ProviderUserId", + table: "Event", + type: "uuid", + nullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "ProviderId", + table: "Event"); + + migrationBuilder.DropColumn( + name: "ProviderUserId", + table: "Event"); + + migrationBuilder.CreateTable( + name: "ProviderOrganizationProviderUser", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + CreationDate = table.Column(type: "timestamp without time zone", nullable: false), + Permissions = table.Column(type: "text", nullable: true), + ProviderOrganizationId = table.Column(type: "uuid", nullable: false), + ProviderUserId = table.Column(type: "uuid", nullable: false), + RevisionDate = table.Column(type: "timestamp without time zone", nullable: false), + Type = table.Column(type: "smallint", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ProviderOrganizationProviderUser", x => x.Id); + table.ForeignKey( + name: "FK_ProviderOrganizationProviderUser_ProviderOrganization_Provi~", + column: x => x.ProviderOrganizationId, + principalTable: "ProviderOrganization", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_ProviderOrganizationProviderUser_ProviderUser_ProviderUserId", + column: x => x.ProviderUserId, + principalTable: "ProviderUser", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_ProviderOrganizationProviderUser_ProviderOrganizationId", + table: "ProviderOrganizationProviderUser", + column: "ProviderOrganizationId"); + + migrationBuilder.CreateIndex( + name: "IX_ProviderOrganizationProviderUser_ProviderUserId", + table: "ProviderOrganizationProviderUser", + column: "ProviderUserId"); + } + } +} diff --git a/util/PostgresMigrations/Migrations/DatabaseContextModelSnapshot.cs b/util/PostgresMigrations/Migrations/DatabaseContextModelSnapshot.cs index 8e81d55fdd..cfcfa5fc61 100644 --- a/util/PostgresMigrations/Migrations/DatabaseContextModelSnapshot.cs +++ b/util/PostgresMigrations/Migrations/DatabaseContextModelSnapshot.cs @@ -278,6 +278,12 @@ namespace Bit.PostgresMigrations.Migrations b.Property("PolicyId") .HasColumnType("uuid"); + b.Property("ProviderId") + .HasColumnType("uuid"); + + b.Property("ProviderUserId") + .HasColumnType("uuid"); + b.Property("Type") .HasColumnType("integer"); @@ -737,38 +743,6 @@ namespace Bit.PostgresMigrations.Migrations b.ToTable("ProviderOrganization"); }); - modelBuilder.Entity("Bit.Core.Models.EntityFramework.Provider.ProviderOrganizationProviderUser", b => - { - b.Property("Id") - .HasColumnType("uuid"); - - b.Property("CreationDate") - .HasColumnType("timestamp without time zone"); - - b.Property("Permissions") - .HasColumnType("text"); - - b.Property("ProviderOrganizationId") - .HasColumnType("uuid"); - - b.Property("ProviderUserId") - .HasColumnType("uuid"); - - b.Property("RevisionDate") - .HasColumnType("timestamp without time zone"); - - b.Property("Type") - .HasColumnType("smallint"); - - b.HasKey("Id"); - - b.HasIndex("ProviderOrganizationId"); - - b.HasIndex("ProviderUserId"); - - b.ToTable("ProviderOrganizationProviderUser"); - }); - modelBuilder.Entity("Bit.Core.Models.EntityFramework.Provider.ProviderUser", b => { b.Property("Id") @@ -1362,25 +1336,6 @@ namespace Bit.PostgresMigrations.Migrations b.Navigation("Provider"); }); - modelBuilder.Entity("Bit.Core.Models.EntityFramework.Provider.ProviderOrganizationProviderUser", b => - { - b.HasOne("Bit.Core.Models.EntityFramework.Provider.ProviderOrganization", "ProviderOrganization") - .WithMany() - .HasForeignKey("ProviderOrganizationId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Bit.Core.Models.EntityFramework.Provider.ProviderUser", "ProviderUser") - .WithMany() - .HasForeignKey("ProviderUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("ProviderOrganization"); - - b.Navigation("ProviderUser"); - }); - modelBuilder.Entity("Bit.Core.Models.EntityFramework.Provider.ProviderUser", b => { b.HasOne("Bit.Core.Models.EntityFramework.Provider.Provider", "Provider") diff --git a/util/PostgresMigrations/RemoveProviderOrganizationProviderUser.psql b/util/PostgresMigrations/RemoveProviderOrganizationProviderUser.psql new file mode 100644 index 0000000000000000000000000000000000000000..42fa884f78d29f7cd6d0fc0172b393931d54b6e8 GIT binary patch literal 674 zcmb`FK}*9x5QX2l(Eku}NeiWDK#KH~wh;rVku>eKlr|I(8ZfP(KVJQIqEw6r1sP^{ zXF8qt=1tyS7b+Af=k)NL_l*{uQ=&u}(O6w|%xCDDSEO_VC;?UQ*_r6=8Kr;>Mu z@3qkbnHTN@cSZEQZmHVp{Vy01T?_i=EtD99k}d}jJs8fgpU@LnxQZj@7fZKSwl?_JO$Ty316^nc U%8)yN)#(eHqRSjhP^ihi13nOE1ONa4 literal 0 HcmV?d00001