mirror of
https://github.com/bitwarden/server.git
synced 2025-07-01 08:02:49 -05:00
[Provider] Add support for events (#1447)
This commit is contained in:
@ -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<ProviderOrganization> _providerOrganizations;
|
||||
private IEnumerable<ProviderUserOrganizationDetails> _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<Guid?> 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<ICollection<CurrentContentOrganization>> OrganizationMembershipAsync(
|
||||
IOrganizationUserRepository organizationUserRepository, Guid userId)
|
||||
{
|
||||
@ -421,14 +440,14 @@ namespace Bit.Core.Context
|
||||
};
|
||||
}
|
||||
|
||||
private async Task<ICollection<ProviderOrganization>> GetProviderOrganizations()
|
||||
private async Task<IEnumerable<ProviderUserOrganizationDetails>> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,8 @@ namespace Bit.Core.Context
|
||||
Task<bool> 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<ICollection<CurrentContentProvider>> ProviderMembershipAsync(
|
||||
IProviderUserRepository providerUserRepository, Guid userId);
|
||||
|
||||
Task<Guid?> ProviderIdForOrg(Guid orgId);
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
namespace Bit.Core.Enums.Provider
|
||||
{
|
||||
public enum ProviderOrganizationProviderUserType : byte
|
||||
{
|
||||
Administrator = 0,
|
||||
ServiceAdmin = 1,
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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; }
|
||||
|
@ -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;
|
||||
|
@ -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<Permissions>(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; }
|
||||
}
|
||||
}
|
||||
|
@ -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; }
|
||||
}
|
||||
|
||||
|
@ -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<EventTableEntity> 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<EventTableEntity>
|
||||
@ -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}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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; }
|
||||
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,3 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using AutoMapper;
|
||||
|
||||
namespace Bit.Core.Models.EntityFramework
|
||||
|
@ -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<Table.Provider.ProviderOrganizationProviderUser, ProviderOrganizationProviderUser>().ReverseMap();
|
||||
}
|
||||
}
|
||||
}
|
@ -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; }
|
||||
|
@ -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<Guid>
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -31,7 +31,6 @@ namespace Bit.Core.Repositories.EntityFramework
|
||||
public DbSet<Provider> Providers { get; set; }
|
||||
public DbSet<ProviderUser> ProviderUsers { get; set; }
|
||||
public DbSet<ProviderOrganization> ProviderOrganizations { get; set; }
|
||||
public DbSet<ProviderOrganizationProviderUser> ProviderOrganizationProviderUsers { get; set; }
|
||||
public DbSet<Send> Sends { get; set; }
|
||||
public DbSet<SsoConfig> SsoConfigs { get; set; }
|
||||
public DbSet<SsoUser> SsoUsers { get; set; }
|
||||
@ -61,7 +60,6 @@ namespace Bit.Core.Repositories.EntityFramework
|
||||
var eProvider = builder.Entity<Provider>();
|
||||
var eProviderUser = builder.Entity<ProviderUser>();
|
||||
var eProviderOrganization = builder.Entity<ProviderOrganization>();
|
||||
var eProviderOrganizationProviderUser = builder.Entity<ProviderOrganizationProviderUser>();
|
||||
var eSend = builder.Entity<Send>();
|
||||
var eSsoConfig = builder.Entity<SsoConfig>();
|
||||
var eSsoUser = builder.Entity<SsoUser>();
|
||||
@ -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));
|
||||
|
@ -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<List<EfModel.Event>>(tableEvents);
|
||||
entityEvents.ForEach(e => e.SetNewId());
|
||||
await dbContext.BulkCopyAsync(entityEvents);
|
||||
}
|
||||
}
|
||||
@ -103,6 +104,57 @@ namespace Bit.Core.Repositories.EntityFramework
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<PagedResult<IEvent>> 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<IEvent>();
|
||||
if (events.Any() && events.Count >= pageOptions.PageSize)
|
||||
{
|
||||
result.ContinuationToken = events.Last().Date.ToBinary().ToString();
|
||||
}
|
||||
result.Data.AddRange(events);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<PagedResult<IEvent>> 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<IEvent>();
|
||||
if (events.Any() && events.Count >= pageOptions.PageSize)
|
||||
{
|
||||
result.ContinuationToken = events.Last().Date.ToBinary().ToString();
|
||||
}
|
||||
result.Data.AddRange(events);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<PagedResult<IEvent>> GetManyByOrganizationAsync(Guid organizationId, DateTime startDate, DateTime endDate, PageOptions pageOptions)
|
||||
{
|
||||
DateTime? beforeDate = 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<TableModel.Provider.ProviderOrganizationProviderUser, EfModel.Provider.ProviderOrganizationProviderUser, Guid>, IProviderOrganizationProviderUserRepository
|
||||
{
|
||||
public ProviderOrganizationProviderUserRepository(IServiceScopeFactory serviceScopeFactory, IMapper mapper)
|
||||
: base(serviceScopeFactory, mapper, (DatabaseContext context) => context.ProviderOrganizationProviderUsers)
|
||||
{ }
|
||||
}
|
||||
}
|
@ -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<TableModel.Provider.ProviderOrganization, EfModel.Provider.ProviderOrganization, Guid>, IProviderOrganizationRepository
|
||||
{
|
||||
public ProviderOrganizationRepository(IServiceScopeFactory serviceScopeFactory, IMapper mapper)
|
||||
: base(serviceScopeFactory, mapper, (DatabaseContext context) => context.ProviderOrganizations)
|
||||
: base(serviceScopeFactory, mapper, context => context.ProviderOrganizations)
|
||||
{ }
|
||||
|
||||
public Task<ICollection<ProviderOrganization>> GetManyByUserIdAsync(Guid userId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public async Task<ICollection<ProviderOrganizationOrganizationDetails>> GetManyDetailsByProviderAsync(Guid providerId)
|
||||
{
|
||||
using (var scope = ServiceScopeFactory.CreateScope())
|
||||
@ -35,5 +30,12 @@ namespace Bit.Core.Repositories.EntityFramework
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ProviderOrganization> GetByOrganizationId(Guid organizationId)
|
||||
{
|
||||
using var scope = ServiceScopeFactory.CreateScope();
|
||||
var dbContext = GetDatabaseContext(scope);
|
||||
return await GetDbSet(dbContext).Where(po => po.OrganizationId == organizationId).FirstOrDefaultAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<TableModel.Provider.Provider, EfModel.Provider.Provider, Guid>, IProviderRepository
|
||||
public class ProviderRepository : Repository<Provider, EfModel.Provider.Provider, Guid>, IProviderRepository
|
||||
{
|
||||
|
||||
public ProviderRepository(IServiceScopeFactory serviceScopeFactory, IMapper mapper)
|
||||
: base(serviceScopeFactory, mapper, (DatabaseContext context) => context.Providers)
|
||||
: base(serviceScopeFactory, mapper, context => context.Providers)
|
||||
{ }
|
||||
|
||||
public Task<ICollection<ProviderAbility>> GetManyAbilitiesAsync() => throw new NotImplementedException();
|
||||
|
||||
public async Task<ICollection<Provider>> 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<List<Provider>>(providers);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ICollection<ProviderAbility>> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -141,9 +141,19 @@ namespace Bit.Core.Repositories.EntityFramework
|
||||
}
|
||||
}
|
||||
|
||||
public Task<IEnumerable<ProviderUserOrganizationDetails>> GetManyOrganizationDetailsByUserAsync(Guid userId, ProviderUserStatusType? status = null)
|
||||
public async Task<IEnumerable<ProviderUserOrganizationDetails>> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<Event>
|
||||
{
|
||||
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<Event> 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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<Event>
|
||||
{
|
||||
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<Event> 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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<ProviderUserOrganizationDetails>
|
||||
{
|
||||
public IQueryable<ProviderUserOrganizationDetails> 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,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -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,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,10 @@ namespace Bit.Core.Repositories
|
||||
PageOptions pageOptions);
|
||||
Task<PagedResult<IEvent>> GetManyByOrganizationActingUserAsync(Guid organizationId, Guid actingUserId,
|
||||
DateTime startDate, DateTime endDate, PageOptions pageOptions);
|
||||
Task<PagedResult<IEvent>> GetManyByProviderAsync(Guid providerId, DateTime startDate, DateTime endDate,
|
||||
PageOptions pageOptions);
|
||||
Task<PagedResult<IEvent>> GetManyByProviderActingUserAsync(Guid providerId, Guid actingUserId,
|
||||
DateTime startDate, DateTime endDate, PageOptions pageOptions);
|
||||
Task<PagedResult<IEvent>> GetManyByCipherAsync(Cipher cipher, DateTime startDate, DateTime endDate,
|
||||
PageOptions pageOptions);
|
||||
Task CreateAsync(IEvent e);
|
||||
|
@ -1,9 +0,0 @@
|
||||
using System;
|
||||
using Bit.Core.Models.Table.Provider;
|
||||
|
||||
namespace Bit.Core.Repositories
|
||||
{
|
||||
public interface IProviderOrganizationProviderUserRepository : IRepository<ProviderOrganizationProviderUser, Guid>
|
||||
{
|
||||
}
|
||||
}
|
@ -9,6 +9,6 @@ namespace Bit.Core.Repositories
|
||||
public interface IProviderOrganizationRepository : IRepository<ProviderOrganization, Guid>
|
||||
{
|
||||
Task<ICollection<ProviderOrganizationOrganizationDetails>> GetManyDetailsByProviderAsync(Guid providerId);
|
||||
Task<ICollection<ProviderOrganization>> GetManyByUserIdAsync(Guid userId);
|
||||
Task<ProviderOrganization> GetByOrganizationId(Guid organizationId);
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +52,27 @@ namespace Bit.Core.Repositories.SqlServer
|
||||
}, startDate, endDate, pageOptions);
|
||||
}
|
||||
|
||||
public async Task<PagedResult<IEvent>> GetManyByProviderAsync(Guid providerId,
|
||||
DateTime startDate, DateTime endDate, PageOptions pageOptions)
|
||||
{
|
||||
return await GetManyAsync($"[{Schema}].[Event_ReadPageByProviderId]",
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
["@ProviderId"] = providerId
|
||||
}, startDate, endDate, pageOptions);
|
||||
}
|
||||
|
||||
public async Task<PagedResult<IEvent>> GetManyByProviderActingUserAsync(Guid providerId, Guid actingUserId,
|
||||
DateTime startDate, DateTime endDate, PageOptions pageOptions)
|
||||
{
|
||||
return await GetManyAsync($"[{Schema}].[Event_ReadPageByProviderIdActingUserId]",
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
["@ProviderId"] = providerId,
|
||||
["@ActingUserId"] = actingUserId
|
||||
}, startDate, endDate, pageOptions);
|
||||
}
|
||||
|
||||
public async Task<PagedResult<IEvent>> GetManyByCipherAsync(Cipher cipher, DateTime startDate, DateTime endDate,
|
||||
PageOptions pageOptions)
|
||||
{
|
||||
|
@ -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<ProviderOrganizationProviderUser, Guid>, IProviderOrganizationProviderUserRepository
|
||||
{
|
||||
public ProviderOrganizationProviderUserRepository(GlobalSettings globalSettings)
|
||||
: this(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString)
|
||||
{ }
|
||||
|
||||
public ProviderOrganizationProviderUserRepository(string connectionString, string readOnlyConnectionString)
|
||||
: base(connectionString, readOnlyConnectionString)
|
||||
{ }
|
||||
}
|
||||
}
|
@ -34,16 +34,16 @@ namespace Bit.Core.Repositories.SqlServer
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ICollection<ProviderOrganization>> GetManyByUserIdAsync(Guid userId)
|
||||
public async Task<ProviderOrganization> GetByOrganizationId(Guid organizationId)
|
||||
{
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
var results = await connection.QueryAsync<ProviderOrganization>(
|
||||
"[dbo].[ProviderOrganization_ReadByUserId]",
|
||||
new { UserId = userId },
|
||||
"[dbo].[ProviderOrganization_ReadByOrganizationId]",
|
||||
new { OrganizationId = organizationId },
|
||||
commandType: CommandType.StoredProcedure);
|
||||
|
||||
return results.ToList();
|
||||
return results.SingleOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using Bit.Core.Models.Table;
|
||||
using System.Threading.Tasks;
|
||||
using System.Data.SqlClient;
|
||||
using System.Data;
|
||||
|
@ -44,6 +44,19 @@ namespace Bit.Core.Repositories.TableStorage
|
||||
$"ActingUserId={actingUserId}__Date={{0}}", startDate, endDate, pageOptions);
|
||||
}
|
||||
|
||||
public async Task<PagedResult<IEvent>> GetManyByProviderAsync(Guid providerId,
|
||||
DateTime startDate, DateTime endDate, PageOptions pageOptions)
|
||||
{
|
||||
return await GetManyAsync($"ProviderId={providerId}", "Date={0}", startDate, endDate, pageOptions);
|
||||
}
|
||||
|
||||
public async Task<PagedResult<IEvent>> 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<PagedResult<IEvent>> GetManyByCipherAsync(Cipher cipher, DateTime startDate, DateTime endDate,
|
||||
PageOptions pageOptions)
|
||||
{
|
||||
|
@ -59,5 +59,6 @@ namespace Bit.Core.Services
|
||||
Task RotateApiKeyAsync(Organization organization);
|
||||
Task DeleteSsoUserAsync(Guid userId, Guid? organizationId);
|
||||
Task<Organization> UpdateOrganizationKeysAsync(Guid orgId, string publicKey, string privateKey);
|
||||
Task<bool> HasConfirmedOwnersExceptAsync(Guid organizationId, IEnumerable<Guid> organizationUsersId);
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,6 @@ namespace Bit.Core.Services
|
||||
|
||||
Task AddOrganization(Guid providerId, Guid organizationId, Guid addingUserId, string key);
|
||||
Task<ProviderOrganization> CreateOrganizationAsync(Guid providerId, OrganizationSignup organizationSignup, User user);
|
||||
Task RemoveOrganization(Guid providerOrganizationId, Guid removingUserId);
|
||||
Task RemoveOrganization(Guid providerId, Guid providerOrganizationId, Guid removingUserId);
|
||||
}
|
||||
}
|
||||
|
@ -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<Guid?> GetProviderIdAsync(Guid? orgId)
|
||||
{
|
||||
if (_currentContext == null || !orgId.HasValue)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return await _currentContext.ProviderIdForOrg(orgId.Value);
|
||||
}
|
||||
|
||||
private bool CanUseEvents(IDictionary<Guid, OrganizationAbility> orgAbilities, Guid orgId)
|
||||
{
|
||||
|
@ -1685,7 +1685,7 @@ namespace Bit.Core.Services
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<bool> HasConfirmedOwnersExceptAsync(Guid organizationId, IEnumerable<Guid> organizationUsersId)
|
||||
public async Task<bool> HasConfirmedOwnersExceptAsync(Guid organizationId, IEnumerable<Guid> organizationUsersId)
|
||||
{
|
||||
var confirmedOwners = await GetConfirmedOwnersAsync(organizationId);
|
||||
var confirmedOwnersIds = confirmedOwners.Select(u => u.Id);
|
||||
|
@ -31,6 +31,6 @@ namespace Bit.Core.Services
|
||||
public Task AddOrganization(Guid providerId, Guid organizationId, Guid addingUserId, string key) => throw new NotImplementedException();
|
||||
public Task<ProviderOrganization> 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();
|
||||
}
|
||||
}
|
||||
|
@ -113,7 +113,6 @@ namespace Bit.Core.Utilities
|
||||
services.AddSingleton<IProviderRepository, EntityFrameworkRepos.ProviderRepository>();
|
||||
services.AddSingleton<IProviderUserRepository, EntityFrameworkRepos.ProviderUserRepository>();
|
||||
services.AddSingleton<IProviderOrganizationRepository, EntityFrameworkRepos.ProviderOrganizationRepository>();
|
||||
services.AddSingleton<IProviderOrganizationProviderUserRepository, EntityFrameworkRepos.ProviderOrganizationProviderUserRepository>();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -138,7 +137,6 @@ namespace Bit.Core.Utilities
|
||||
services.AddSingleton<IProviderRepository, SqlServerRepos.ProviderRepository>();
|
||||
services.AddSingleton<IProviderUserRepository, SqlServerRepos.ProviderUserRepository>();
|
||||
services.AddSingleton<IProviderOrganizationRepository, SqlServerRepos.ProviderOrganizationRepository>();
|
||||
services.AddSingleton<IProviderOrganizationProviderUserRepository, SqlServerRepos.ProviderOrganizationProviderUserRepository>();
|
||||
services.AddSingleton<ITransactionRepository, SqlServerRepos.TransactionRepository>();
|
||||
services.AddSingleton<IU2fRepository, SqlServerRepos.U2fRepository>();
|
||||
services.AddSingleton<IUserRepository, SqlServerRepos.UserRepository>();
|
||||
|
Reference in New Issue
Block a user