1
0
mirror of https://github.com/bitwarden/server.git synced 2025-06-30 23:52:50 -05:00

Revert filescoped (#2227)

* Revert "Add git blame entry (#2226)"

This reverts commit 239286737d.

* Revert "Turn on file scoped namespaces (#2225)"

This reverts commit 34fb4cca2a.
This commit is contained in:
Justin Baur
2022-08-29 15:53:48 -04:00
committed by GitHub
parent 239286737d
commit bae03feffe
1208 changed files with 74317 additions and 73126 deletions

View File

@ -1,22 +1,23 @@
namespace Bit.Core;
public static class Constants
namespace Bit.Core
{
public const int BypassFiltersEventId = 12482444;
public static class Constants
{
public const int BypassFiltersEventId = 12482444;
// File size limits - give 1 MB extra for cushion.
// Note: if request size limits are changed, 'client_max_body_size'
// in nginx/proxy.conf may also need to be updated accordingly.
public const long FileSize101mb = 101L * 1024L * 1024L;
public const long FileSize501mb = 501L * 1024L * 1024L;
}
// File size limits - give 1 MB extra for cushion.
// Note: if request size limits are changed, 'client_max_body_size'
// in nginx/proxy.conf may also need to be updated accordingly.
public const long FileSize101mb = 101L * 1024L * 1024L;
public const long FileSize501mb = 501L * 1024L * 1024L;
}
public static class TokenPurposes
{
public const string LinkSso = "LinkSso";
}
public static class TokenPurposes
{
public const string LinkSso = "LinkSso";
}
public static class AuthenticationSchemes
{
public const string BitwardenExternalCookieAuthenticationScheme = "bw.external";
public static class AuthenticationSchemes
{
public const string BitwardenExternalCookieAuthenticationScheme = "bw.external";
}
}

View File

@ -3,20 +3,21 @@ using Bit.Core.Enums;
using Bit.Core.Models.Data;
using Bit.Core.Utilities;
namespace Bit.Core.Context;
public class CurrentContentOrganization
namespace Bit.Core.Context
{
public CurrentContentOrganization() { }
public CurrentContentOrganization(OrganizationUser orgUser)
public class CurrentContentOrganization
{
Id = orgUser.OrganizationId;
Type = orgUser.Type;
Permissions = CoreHelpers.LoadClassFromJsonData<Permissions>(orgUser.Permissions);
}
public CurrentContentOrganization() { }
public Guid Id { get; set; }
public OrganizationUserType Type { get; set; }
public Permissions Permissions { get; set; }
public CurrentContentOrganization(OrganizationUser orgUser)
{
Id = orgUser.OrganizationId;
Type = orgUser.Type;
Permissions = CoreHelpers.LoadClassFromJsonData<Permissions>(orgUser.Permissions);
}
public Guid Id { get; set; }
public OrganizationUserType Type { get; set; }
public Permissions Permissions { get; set; }
}
}

View File

@ -3,20 +3,21 @@ using Bit.Core.Enums.Provider;
using Bit.Core.Models.Data;
using Bit.Core.Utilities;
namespace Bit.Core.Context;
public class CurrentContentProvider
namespace Bit.Core.Context
{
public CurrentContentProvider() { }
public CurrentContentProvider(ProviderUser providerUser)
public class CurrentContentProvider
{
Id = providerUser.ProviderId;
Type = providerUser.Type;
Permissions = CoreHelpers.LoadClassFromJsonData<Permissions>(providerUser.Permissions);
}
public CurrentContentProvider() { }
public Guid Id { get; set; }
public ProviderUserType Type { get; set; }
public Permissions Permissions { get; set; }
public CurrentContentProvider(ProviderUser providerUser)
{
Id = providerUser.ProviderId;
Type = providerUser.Type;
Permissions = CoreHelpers.LoadClassFromJsonData<Permissions>(providerUser.Permissions);
}
public Guid Id { get; set; }
public ProviderUserType Type { get; set; }
public Permissions Permissions { get; set; }
}
}

View File

@ -8,485 +8,486 @@ using Bit.Core.Settings;
using Bit.Core.Utilities;
using Microsoft.AspNetCore.Http;
namespace Bit.Core.Context;
public class CurrentContext : ICurrentContext
namespace Bit.Core.Context
{
private readonly IProviderUserRepository _providerUserRepository;
private bool _builtHttpContext;
private bool _builtClaimsPrincipal;
private IEnumerable<ProviderUserOrganizationDetails> _providerUserOrganizations;
public virtual HttpContext HttpContext { get; set; }
public virtual Guid? UserId { get; set; }
public virtual User User { get; set; }
public virtual string DeviceIdentifier { get; set; }
public virtual DeviceType? DeviceType { get; set; }
public virtual string IpAddress { get; set; }
public virtual List<CurrentContentOrganization> Organizations { get; set; }
public virtual List<CurrentContentProvider> Providers { get; set; }
public virtual Guid? InstallationId { get; set; }
public virtual Guid? OrganizationId { get; set; }
public virtual bool CloudflareWorkerProxied { get; set; }
public virtual bool IsBot { get; set; }
public virtual bool MaybeBot { get; set; }
public virtual int? BotScore { get; set; }
public virtual string ClientId { get; set; }
public CurrentContext(IProviderUserRepository providerUserRepository)
public class CurrentContext : ICurrentContext
{
_providerUserRepository = providerUserRepository;
}
private readonly IProviderUserRepository _providerUserRepository;
private bool _builtHttpContext;
private bool _builtClaimsPrincipal;
private IEnumerable<ProviderUserOrganizationDetails> _providerUserOrganizations;
public async virtual Task BuildAsync(HttpContext httpContext, GlobalSettings globalSettings)
{
if (_builtHttpContext)
public virtual HttpContext HttpContext { get; set; }
public virtual Guid? UserId { get; set; }
public virtual User User { get; set; }
public virtual string DeviceIdentifier { get; set; }
public virtual DeviceType? DeviceType { get; set; }
public virtual string IpAddress { get; set; }
public virtual List<CurrentContentOrganization> Organizations { get; set; }
public virtual List<CurrentContentProvider> Providers { get; set; }
public virtual Guid? InstallationId { get; set; }
public virtual Guid? OrganizationId { get; set; }
public virtual bool CloudflareWorkerProxied { get; set; }
public virtual bool IsBot { get; set; }
public virtual bool MaybeBot { get; set; }
public virtual int? BotScore { get; set; }
public virtual string ClientId { get; set; }
public CurrentContext(IProviderUserRepository providerUserRepository)
{
return;
_providerUserRepository = providerUserRepository;
}
_builtHttpContext = true;
HttpContext = httpContext;
await BuildAsync(httpContext.User, globalSettings);
if (DeviceIdentifier == null && httpContext.Request.Headers.ContainsKey("Device-Identifier"))
public async virtual Task BuildAsync(HttpContext httpContext, GlobalSettings globalSettings)
{
DeviceIdentifier = httpContext.Request.Headers["Device-Identifier"];
if (_builtHttpContext)
{
return;
}
_builtHttpContext = true;
HttpContext = httpContext;
await BuildAsync(httpContext.User, globalSettings);
if (DeviceIdentifier == null && httpContext.Request.Headers.ContainsKey("Device-Identifier"))
{
DeviceIdentifier = httpContext.Request.Headers["Device-Identifier"];
}
if (httpContext.Request.Headers.ContainsKey("Device-Type") &&
Enum.TryParse(httpContext.Request.Headers["Device-Type"].ToString(), out DeviceType dType))
{
DeviceType = dType;
}
if (!BotScore.HasValue && httpContext.Request.Headers.ContainsKey("X-Cf-Bot-Score") &&
int.TryParse(httpContext.Request.Headers["X-Cf-Bot-Score"], out var parsedBotScore))
{
BotScore = parsedBotScore;
}
if (httpContext.Request.Headers.ContainsKey("X-Cf-Worked-Proxied"))
{
CloudflareWorkerProxied = httpContext.Request.Headers["X-Cf-Worked-Proxied"] == "1";
}
if (httpContext.Request.Headers.ContainsKey("X-Cf-Is-Bot"))
{
IsBot = httpContext.Request.Headers["X-Cf-Is-Bot"] == "1";
}
if (httpContext.Request.Headers.ContainsKey("X-Cf-Maybe-Bot"))
{
MaybeBot = httpContext.Request.Headers["X-Cf-Maybe-Bot"] == "1";
}
}
if (httpContext.Request.Headers.ContainsKey("Device-Type") &&
Enum.TryParse(httpContext.Request.Headers["Device-Type"].ToString(), out DeviceType dType))
public async virtual Task BuildAsync(ClaimsPrincipal user, GlobalSettings globalSettings)
{
DeviceType = dType;
if (_builtClaimsPrincipal)
{
return;
}
_builtClaimsPrincipal = true;
IpAddress = HttpContext.GetIpAddress(globalSettings);
await SetContextAsync(user);
}
if (!BotScore.HasValue && httpContext.Request.Headers.ContainsKey("X-Cf-Bot-Score") &&
int.TryParse(httpContext.Request.Headers["X-Cf-Bot-Score"], out var parsedBotScore))
public virtual Task SetContextAsync(ClaimsPrincipal user)
{
BotScore = parsedBotScore;
}
if (user == null || !user.Claims.Any())
{
return Task.FromResult(0);
}
if (httpContext.Request.Headers.ContainsKey("X-Cf-Worked-Proxied"))
{
CloudflareWorkerProxied = httpContext.Request.Headers["X-Cf-Worked-Proxied"] == "1";
}
var claimsDict = user.Claims.GroupBy(c => c.Type).ToDictionary(c => c.Key, c => c.Select(v => v));
if (httpContext.Request.Headers.ContainsKey("X-Cf-Is-Bot"))
{
IsBot = httpContext.Request.Headers["X-Cf-Is-Bot"] == "1";
}
var subject = GetClaimValue(claimsDict, "sub");
if (Guid.TryParse(subject, out var subIdGuid))
{
UserId = subIdGuid;
}
if (httpContext.Request.Headers.ContainsKey("X-Cf-Maybe-Bot"))
{
MaybeBot = httpContext.Request.Headers["X-Cf-Maybe-Bot"] == "1";
}
}
ClientId = GetClaimValue(claimsDict, "client_id");
var clientSubject = GetClaimValue(claimsDict, "client_sub");
var orgApi = false;
if (clientSubject != null)
{
if (ClientId?.StartsWith("installation.") ?? false)
{
if (Guid.TryParse(clientSubject, out var idGuid))
{
InstallationId = idGuid;
}
}
else if (ClientId?.StartsWith("organization.") ?? false)
{
if (Guid.TryParse(clientSubject, out var idGuid))
{
OrganizationId = idGuid;
orgApi = true;
}
}
}
public async virtual Task BuildAsync(ClaimsPrincipal user, GlobalSettings globalSettings)
{
if (_builtClaimsPrincipal)
{
return;
}
DeviceIdentifier = GetClaimValue(claimsDict, "device");
_builtClaimsPrincipal = true;
IpAddress = HttpContext.GetIpAddress(globalSettings);
await SetContextAsync(user);
}
Organizations = GetOrganizations(claimsDict, orgApi);
Providers = GetProviders(claimsDict);
public virtual Task SetContextAsync(ClaimsPrincipal user)
{
if (user == null || !user.Claims.Any())
{
return Task.FromResult(0);
}
var claimsDict = user.Claims.GroupBy(c => c.Type).ToDictionary(c => c.Key, c => c.Select(v => v));
var subject = GetClaimValue(claimsDict, "sub");
if (Guid.TryParse(subject, out var subIdGuid))
private List<CurrentContentOrganization> GetOrganizations(Dictionary<string, IEnumerable<Claim>> claimsDict, bool orgApi)
{
UserId = subIdGuid;
}
ClientId = GetClaimValue(claimsDict, "client_id");
var clientSubject = GetClaimValue(claimsDict, "client_sub");
var orgApi = false;
if (clientSubject != null)
{
if (ClientId?.StartsWith("installation.") ?? false)
var organizations = new List<CurrentContentOrganization>();
if (claimsDict.ContainsKey("orgowner"))
{
if (Guid.TryParse(clientSubject, out var idGuid))
{
InstallationId = idGuid;
}
organizations.AddRange(claimsDict["orgowner"].Select(c =>
new CurrentContentOrganization
{
Id = new Guid(c.Value),
Type = OrganizationUserType.Owner
}));
}
else if (ClientId?.StartsWith("organization.") ?? false)
else if (orgApi && OrganizationId.HasValue)
{
if (Guid.TryParse(clientSubject, out var idGuid))
organizations.Add(new CurrentContentOrganization
{
OrganizationId = idGuid;
orgApi = true;
}
}
}
DeviceIdentifier = GetClaimValue(claimsDict, "device");
Organizations = GetOrganizations(claimsDict, orgApi);
Providers = GetProviders(claimsDict);
return Task.FromResult(0);
}
private List<CurrentContentOrganization> GetOrganizations(Dictionary<string, IEnumerable<Claim>> claimsDict, bool orgApi)
{
var organizations = new List<CurrentContentOrganization>();
if (claimsDict.ContainsKey("orgowner"))
{
organizations.AddRange(claimsDict["orgowner"].Select(c =>
new CurrentContentOrganization
{
Id = new Guid(c.Value),
Id = OrganizationId.Value,
Type = OrganizationUserType.Owner
}));
}
else if (orgApi && OrganizationId.HasValue)
{
organizations.Add(new CurrentContentOrganization
});
}
if (claimsDict.ContainsKey("orgadmin"))
{
Id = OrganizationId.Value,
Type = OrganizationUserType.Owner
});
organizations.AddRange(claimsDict["orgadmin"].Select(c =>
new CurrentContentOrganization
{
Id = new Guid(c.Value),
Type = OrganizationUserType.Admin
}));
}
if (claimsDict.ContainsKey("orguser"))
{
organizations.AddRange(claimsDict["orguser"].Select(c =>
new CurrentContentOrganization
{
Id = new Guid(c.Value),
Type = OrganizationUserType.User
}));
}
if (claimsDict.ContainsKey("orgmanager"))
{
organizations.AddRange(claimsDict["orgmanager"].Select(c =>
new CurrentContentOrganization
{
Id = new Guid(c.Value),
Type = OrganizationUserType.Manager
}));
}
if (claimsDict.ContainsKey("orgcustom"))
{
organizations.AddRange(claimsDict["orgcustom"].Select(c =>
new CurrentContentOrganization
{
Id = new Guid(c.Value),
Type = OrganizationUserType.Custom,
Permissions = SetOrganizationPermissionsFromClaims(c.Value, claimsDict)
}));
}
return organizations;
}
if (claimsDict.ContainsKey("orgadmin"))
private List<CurrentContentProvider> GetProviders(Dictionary<string, IEnumerable<Claim>> claimsDict)
{
organizations.AddRange(claimsDict["orgadmin"].Select(c =>
new CurrentContentOrganization
{
Id = new Guid(c.Value),
Type = OrganizationUserType.Admin
}));
var providers = new List<CurrentContentProvider>();
if (claimsDict.ContainsKey("providerprovideradmin"))
{
providers.AddRange(claimsDict["providerprovideradmin"].Select(c =>
new CurrentContentProvider
{
Id = new Guid(c.Value),
Type = ProviderUserType.ProviderAdmin
}));
}
if (claimsDict.ContainsKey("providerserviceuser"))
{
providers.AddRange(claimsDict["providerserviceuser"].Select(c =>
new CurrentContentProvider
{
Id = new Guid(c.Value),
Type = ProviderUserType.ServiceUser
}));
}
return providers;
}
if (claimsDict.ContainsKey("orguser"))
public async Task<bool> OrganizationUser(Guid orgId)
{
organizations.AddRange(claimsDict["orguser"].Select(c =>
new CurrentContentOrganization
{
Id = new Guid(c.Value),
Type = OrganizationUserType.User
}));
return (Organizations?.Any(o => o.Id == orgId) ?? false) || await OrganizationOwner(orgId);
}
if (claimsDict.ContainsKey("orgmanager"))
public async Task<bool> OrganizationManager(Guid orgId)
{
organizations.AddRange(claimsDict["orgmanager"].Select(c =>
new CurrentContentOrganization
{
Id = new Guid(c.Value),
Type = OrganizationUserType.Manager
}));
return await OrganizationAdmin(orgId) ||
(Organizations?.Any(o => o.Id == orgId && o.Type == OrganizationUserType.Manager) ?? false);
}
if (claimsDict.ContainsKey("orgcustom"))
public async Task<bool> OrganizationAdmin(Guid orgId)
{
organizations.AddRange(claimsDict["orgcustom"].Select(c =>
new CurrentContentOrganization
{
Id = new Guid(c.Value),
Type = OrganizationUserType.Custom,
Permissions = SetOrganizationPermissionsFromClaims(c.Value, claimsDict)
}));
return await OrganizationOwner(orgId) ||
(Organizations?.Any(o => o.Id == orgId && o.Type == OrganizationUserType.Admin) ?? false);
}
return organizations;
}
private List<CurrentContentProvider> GetProviders(Dictionary<string, IEnumerable<Claim>> claimsDict)
{
var providers = new List<CurrentContentProvider>();
if (claimsDict.ContainsKey("providerprovideradmin"))
public async Task<bool> OrganizationOwner(Guid orgId)
{
providers.AddRange(claimsDict["providerprovideradmin"].Select(c =>
new CurrentContentProvider
{
Id = new Guid(c.Value),
Type = ProviderUserType.ProviderAdmin
}));
if (Organizations?.Any(o => o.Id == orgId && o.Type == OrganizationUserType.Owner) ?? false)
{
return true;
}
if (Providers.Any())
{
return await ProviderUserForOrgAsync(orgId);
}
return false;
}
if (claimsDict.ContainsKey("providerserviceuser"))
public Task<bool> OrganizationCustom(Guid orgId)
{
providers.AddRange(claimsDict["providerserviceuser"].Select(c =>
new CurrentContentProvider
{
Id = new Guid(c.Value),
Type = ProviderUserType.ServiceUser
}));
return Task.FromResult(Organizations?.Any(o => o.Id == orgId && o.Type == OrganizationUserType.Custom) ?? false);
}
return providers;
}
public async Task<bool> OrganizationUser(Guid orgId)
{
return (Organizations?.Any(o => o.Id == orgId) ?? false) || await OrganizationOwner(orgId);
}
public async Task<bool> OrganizationManager(Guid orgId)
{
return await OrganizationAdmin(orgId) ||
(Organizations?.Any(o => o.Id == orgId && o.Type == OrganizationUserType.Manager) ?? false);
}
public async Task<bool> OrganizationAdmin(Guid orgId)
{
return await OrganizationOwner(orgId) ||
(Organizations?.Any(o => o.Id == orgId && o.Type == OrganizationUserType.Admin) ?? false);
}
public async Task<bool> OrganizationOwner(Guid orgId)
{
if (Organizations?.Any(o => o.Id == orgId && o.Type == OrganizationUserType.Owner) ?? false)
public async Task<bool> AccessEventLogs(Guid orgId)
{
return true;
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.AccessEventLogs ?? false)) ?? false);
}
if (Providers.Any())
public async Task<bool> AccessImportExport(Guid orgId)
{
return await ProviderUserForOrgAsync(orgId);
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.AccessImportExport ?? false)) ?? false);
}
return false;
}
public Task<bool> OrganizationCustom(Guid orgId)
{
return Task.FromResult(Organizations?.Any(o => o.Id == orgId && o.Type == OrganizationUserType.Custom) ?? false);
}
public async Task<bool> AccessEventLogs(Guid orgId)
{
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.AccessEventLogs ?? false)) ?? false);
}
public async Task<bool> AccessImportExport(Guid orgId)
{
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.AccessImportExport ?? false)) ?? false);
}
public async Task<bool> AccessReports(Guid orgId)
{
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.AccessReports ?? false)) ?? false);
}
public async Task<bool> CreateNewCollections(Guid orgId)
{
return await OrganizationManager(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.CreateNewCollections ?? false)) ?? false);
}
public async Task<bool> EditAnyCollection(Guid orgId)
{
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.EditAnyCollection ?? false)) ?? false);
}
public async Task<bool> DeleteAnyCollection(Guid orgId)
{
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.DeleteAnyCollection ?? false)) ?? false);
}
public async Task<bool> ViewAllCollections(Guid orgId)
{
return await CreateNewCollections(orgId) || await EditAnyCollection(orgId) || await DeleteAnyCollection(orgId);
}
public async Task<bool> EditAssignedCollections(Guid orgId)
{
return await OrganizationManager(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.EditAssignedCollections ?? false)) ?? false);
}
public async Task<bool> DeleteAssignedCollections(Guid orgId)
{
return await OrganizationManager(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.DeleteAssignedCollections ?? false)) ?? false);
}
public async Task<bool> ViewAssignedCollections(Guid orgId)
{
return await EditAssignedCollections(orgId) || await DeleteAssignedCollections(orgId);
}
public async Task<bool> ManageGroups(Guid orgId)
{
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.ManageGroups ?? false)) ?? false);
}
public async Task<bool> ManagePolicies(Guid orgId)
{
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.ManagePolicies ?? false)) ?? false);
}
public async Task<bool> ManageSso(Guid orgId)
{
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.ManageSso ?? false)) ?? false);
}
public async Task<bool> ManageScim(Guid orgId)
{
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.ManageScim ?? false)) ?? false);
}
public async Task<bool> ManageUsers(Guid orgId)
{
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.ManageUsers ?? false)) ?? false);
}
public async Task<bool> ManageResetPassword(Guid orgId)
{
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.ManageResetPassword ?? false)) ?? false);
}
public async Task<bool> ManageBilling(Guid orgId)
{
var orgManagedByProvider = await ProviderIdForOrg(orgId) != null;
return orgManagedByProvider
? await ProviderUserForOrgAsync(orgId)
: await OrganizationOwner(orgId);
}
public bool ProviderProviderAdmin(Guid providerId)
{
return Providers?.Any(o => o.Id == providerId && o.Type == ProviderUserType.ProviderAdmin) ?? false;
}
public bool ProviderManageUsers(Guid providerId)
{
return ProviderProviderAdmin(providerId);
}
public bool ProviderAccessEventLogs(Guid providerId)
{
return ProviderProviderAdmin(providerId);
}
public bool AccessProviderOrganizations(Guid providerId)
{
return ProviderUser(providerId);
}
public bool ManageProviderOrganizations(Guid providerId)
{
return ProviderProviderAdmin(providerId);
}
public bool ProviderUser(Guid providerId)
{
return Providers?.Any(o => o.Id == providerId) ?? false;
}
public async Task<bool> ProviderUserForOrgAsync(Guid orgId)
{
return (await GetProviderOrganizations()).Any(po => po.OrganizationId == orgId);
}
public async Task<Guid?> ProviderIdForOrg(Guid orgId)
{
if (Organizations?.Any(org => org.Id == orgId) ?? false)
public async Task<bool> AccessReports(Guid orgId)
{
return null;
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.AccessReports ?? false)) ?? false);
}
var po = (await GetProviderOrganizations())
?.FirstOrDefault(po => po.OrganizationId == orgId);
return po?.ProviderId;
}
public async Task<ICollection<CurrentContentOrganization>> OrganizationMembershipAsync(
IOrganizationUserRepository organizationUserRepository, Guid userId)
{
if (Organizations == null)
public async Task<bool> CreateNewCollections(Guid orgId)
{
var userOrgs = await organizationUserRepository.GetManyByUserAsync(userId);
Organizations = userOrgs.Where(ou => ou.Status == OrganizationUserStatusType.Confirmed)
.Select(ou => new CurrentContentOrganization(ou)).ToList();
}
return Organizations;
}
public async Task<ICollection<CurrentContentProvider>> ProviderMembershipAsync(
IProviderUserRepository providerUserRepository, Guid userId)
{
if (Providers == null)
{
var userProviders = await providerUserRepository.GetManyByUserAsync(userId);
Providers = userProviders.Where(ou => ou.Status == ProviderUserStatusType.Confirmed)
.Select(ou => new CurrentContentProvider(ou)).ToList();
}
return Providers;
}
private string GetClaimValue(Dictionary<string, IEnumerable<Claim>> claims, string type)
{
if (!claims.ContainsKey(type))
{
return null;
return await OrganizationManager(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.CreateNewCollections ?? false)) ?? false);
}
return claims[type].FirstOrDefault()?.Value;
}
private Permissions SetOrganizationPermissionsFromClaims(string organizationId, Dictionary<string, IEnumerable<Claim>> claimsDict)
{
bool hasClaim(string claimKey)
public async Task<bool> EditAnyCollection(Guid orgId)
{
return claimsDict.ContainsKey(claimKey) ?
claimsDict[claimKey].Any(x => x.Value == organizationId) : false;
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.EditAnyCollection ?? false)) ?? false);
}
return new Permissions
public async Task<bool> DeleteAnyCollection(Guid orgId)
{
AccessEventLogs = hasClaim("accesseventlogs"),
AccessImportExport = hasClaim("accessimportexport"),
AccessReports = hasClaim("accessreports"),
CreateNewCollections = hasClaim("createnewcollections"),
EditAnyCollection = hasClaim("editanycollection"),
DeleteAnyCollection = hasClaim("deleteanycollection"),
EditAssignedCollections = hasClaim("editassignedcollections"),
DeleteAssignedCollections = hasClaim("deleteassignedcollections"),
ManageGroups = hasClaim("managegroups"),
ManagePolicies = hasClaim("managepolicies"),
ManageSso = hasClaim("managesso"),
ManageUsers = hasClaim("manageusers"),
ManageResetPassword = hasClaim("manageresetpassword"),
ManageScim = hasClaim("managescim"),
};
}
protected async Task<IEnumerable<ProviderUserOrganizationDetails>> GetProviderOrganizations()
{
if (_providerUserOrganizations == null && UserId.HasValue)
{
_providerUserOrganizations = await _providerUserRepository.GetManyOrganizationDetailsByUserAsync(UserId.Value, ProviderUserStatusType.Confirmed);
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.DeleteAnyCollection ?? false)) ?? false);
}
return _providerUserOrganizations;
public async Task<bool> ViewAllCollections(Guid orgId)
{
return await CreateNewCollections(orgId) || await EditAnyCollection(orgId) || await DeleteAnyCollection(orgId);
}
public async Task<bool> EditAssignedCollections(Guid orgId)
{
return await OrganizationManager(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.EditAssignedCollections ?? false)) ?? false);
}
public async Task<bool> DeleteAssignedCollections(Guid orgId)
{
return await OrganizationManager(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.DeleteAssignedCollections ?? false)) ?? false);
}
public async Task<bool> ViewAssignedCollections(Guid orgId)
{
return await EditAssignedCollections(orgId) || await DeleteAssignedCollections(orgId);
}
public async Task<bool> ManageGroups(Guid orgId)
{
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.ManageGroups ?? false)) ?? false);
}
public async Task<bool> ManagePolicies(Guid orgId)
{
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.ManagePolicies ?? false)) ?? false);
}
public async Task<bool> ManageSso(Guid orgId)
{
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.ManageSso ?? false)) ?? false);
}
public async Task<bool> ManageScim(Guid orgId)
{
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.ManageScim ?? false)) ?? false);
}
public async Task<bool> ManageUsers(Guid orgId)
{
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.ManageUsers ?? false)) ?? false);
}
public async Task<bool> ManageResetPassword(Guid orgId)
{
return await OrganizationAdmin(orgId) || (Organizations?.Any(o => o.Id == orgId
&& (o.Permissions?.ManageResetPassword ?? false)) ?? false);
}
public async Task<bool> ManageBilling(Guid orgId)
{
var orgManagedByProvider = await ProviderIdForOrg(orgId) != null;
return orgManagedByProvider
? await ProviderUserForOrgAsync(orgId)
: await OrganizationOwner(orgId);
}
public bool ProviderProviderAdmin(Guid providerId)
{
return Providers?.Any(o => o.Id == providerId && o.Type == ProviderUserType.ProviderAdmin) ?? false;
}
public bool ProviderManageUsers(Guid providerId)
{
return ProviderProviderAdmin(providerId);
}
public bool ProviderAccessEventLogs(Guid providerId)
{
return ProviderProviderAdmin(providerId);
}
public bool AccessProviderOrganizations(Guid providerId)
{
return ProviderUser(providerId);
}
public bool ManageProviderOrganizations(Guid providerId)
{
return ProviderProviderAdmin(providerId);
}
public bool ProviderUser(Guid providerId)
{
return Providers?.Any(o => o.Id == providerId) ?? false;
}
public async Task<bool> ProviderUserForOrgAsync(Guid orgId)
{
return (await GetProviderOrganizations()).Any(po => po.OrganizationId == orgId);
}
public async Task<Guid?> ProviderIdForOrg(Guid orgId)
{
if (Organizations?.Any(org => org.Id == orgId) ?? false)
{
return null;
}
var po = (await GetProviderOrganizations())
?.FirstOrDefault(po => po.OrganizationId == orgId);
return po?.ProviderId;
}
public async Task<ICollection<CurrentContentOrganization>> OrganizationMembershipAsync(
IOrganizationUserRepository organizationUserRepository, Guid userId)
{
if (Organizations == null)
{
var userOrgs = await organizationUserRepository.GetManyByUserAsync(userId);
Organizations = userOrgs.Where(ou => ou.Status == OrganizationUserStatusType.Confirmed)
.Select(ou => new CurrentContentOrganization(ou)).ToList();
}
return Organizations;
}
public async Task<ICollection<CurrentContentProvider>> ProviderMembershipAsync(
IProviderUserRepository providerUserRepository, Guid userId)
{
if (Providers == null)
{
var userProviders = await providerUserRepository.GetManyByUserAsync(userId);
Providers = userProviders.Where(ou => ou.Status == ProviderUserStatusType.Confirmed)
.Select(ou => new CurrentContentProvider(ou)).ToList();
}
return Providers;
}
private string GetClaimValue(Dictionary<string, IEnumerable<Claim>> claims, string type)
{
if (!claims.ContainsKey(type))
{
return null;
}
return claims[type].FirstOrDefault()?.Value;
}
private Permissions SetOrganizationPermissionsFromClaims(string organizationId, Dictionary<string, IEnumerable<Claim>> claimsDict)
{
bool hasClaim(string claimKey)
{
return claimsDict.ContainsKey(claimKey) ?
claimsDict[claimKey].Any(x => x.Value == organizationId) : false;
}
return new Permissions
{
AccessEventLogs = hasClaim("accesseventlogs"),
AccessImportExport = hasClaim("accessimportexport"),
AccessReports = hasClaim("accessreports"),
CreateNewCollections = hasClaim("createnewcollections"),
EditAnyCollection = hasClaim("editanycollection"),
DeleteAnyCollection = hasClaim("deleteanycollection"),
EditAssignedCollections = hasClaim("editassignedcollections"),
DeleteAssignedCollections = hasClaim("deleteassignedcollections"),
ManageGroups = hasClaim("managegroups"),
ManagePolicies = hasClaim("managepolicies"),
ManageSso = hasClaim("managesso"),
ManageUsers = hasClaim("manageusers"),
ManageResetPassword = hasClaim("manageresetpassword"),
ManageScim = hasClaim("managescim"),
};
}
protected async Task<IEnumerable<ProviderUserOrganizationDetails>> GetProviderOrganizations()
{
if (_providerUserOrganizations == null && UserId.HasValue)
{
_providerUserOrganizations = await _providerUserRepository.GetManyOrganizationDetailsByUserAsync(UserId.Value, ProviderUserStatusType.Confirmed);
}
return _providerUserOrganizations;
}
}
}

View File

@ -5,64 +5,65 @@ using Bit.Core.Repositories;
using Bit.Core.Settings;
using Microsoft.AspNetCore.Http;
namespace Bit.Core.Context;
public interface ICurrentContext
namespace Bit.Core.Context
{
HttpContext HttpContext { get; set; }
Guid? UserId { get; set; }
User User { get; set; }
string DeviceIdentifier { get; set; }
DeviceType? DeviceType { get; set; }
string IpAddress { get; set; }
List<CurrentContentOrganization> Organizations { get; set; }
Guid? InstallationId { get; set; }
Guid? OrganizationId { get; set; }
bool IsBot { get; set; }
bool MaybeBot { get; set; }
int? BotScore { get; set; }
string ClientId { get; set; }
Task BuildAsync(HttpContext httpContext, GlobalSettings globalSettings);
Task BuildAsync(ClaimsPrincipal user, GlobalSettings globalSettings);
public interface ICurrentContext
{
HttpContext HttpContext { get; set; }
Guid? UserId { get; set; }
User User { get; set; }
string DeviceIdentifier { get; set; }
DeviceType? DeviceType { get; set; }
string IpAddress { get; set; }
List<CurrentContentOrganization> Organizations { get; set; }
Guid? InstallationId { get; set; }
Guid? OrganizationId { get; set; }
bool IsBot { get; set; }
bool MaybeBot { get; set; }
int? BotScore { get; set; }
string ClientId { get; set; }
Task BuildAsync(HttpContext httpContext, GlobalSettings globalSettings);
Task BuildAsync(ClaimsPrincipal user, GlobalSettings globalSettings);
Task SetContextAsync(ClaimsPrincipal user);
Task SetContextAsync(ClaimsPrincipal user);
Task<bool> OrganizationUser(Guid orgId);
Task<bool> OrganizationManager(Guid orgId);
Task<bool> OrganizationAdmin(Guid orgId);
Task<bool> OrganizationOwner(Guid orgId);
Task<bool> OrganizationCustom(Guid orgId);
Task<bool> AccessEventLogs(Guid orgId);
Task<bool> AccessImportExport(Guid orgId);
Task<bool> AccessReports(Guid orgId);
Task<bool> CreateNewCollections(Guid orgId);
Task<bool> EditAnyCollection(Guid orgId);
Task<bool> DeleteAnyCollection(Guid orgId);
Task<bool> ViewAllCollections(Guid orgId);
Task<bool> EditAssignedCollections(Guid orgId);
Task<bool> DeleteAssignedCollections(Guid orgId);
Task<bool> ViewAssignedCollections(Guid orgId);
Task<bool> ManageGroups(Guid orgId);
Task<bool> ManagePolicies(Guid orgId);
Task<bool> ManageSso(Guid orgId);
Task<bool> ManageUsers(Guid orgId);
Task<bool> ManageScim(Guid orgId);
Task<bool> ManageResetPassword(Guid orgId);
Task<bool> ManageBilling(Guid orgId);
Task<bool> ProviderUserForOrgAsync(Guid orgId);
bool ProviderProviderAdmin(Guid providerId);
bool ProviderUser(Guid providerId);
bool ProviderManageUsers(Guid providerId);
bool ProviderAccessEventLogs(Guid providerId);
bool AccessProviderOrganizations(Guid providerId);
bool ManageProviderOrganizations(Guid providerId);
Task<bool> OrganizationUser(Guid orgId);
Task<bool> OrganizationManager(Guid orgId);
Task<bool> OrganizationAdmin(Guid orgId);
Task<bool> OrganizationOwner(Guid orgId);
Task<bool> OrganizationCustom(Guid orgId);
Task<bool> AccessEventLogs(Guid orgId);
Task<bool> AccessImportExport(Guid orgId);
Task<bool> AccessReports(Guid orgId);
Task<bool> CreateNewCollections(Guid orgId);
Task<bool> EditAnyCollection(Guid orgId);
Task<bool> DeleteAnyCollection(Guid orgId);
Task<bool> ViewAllCollections(Guid orgId);
Task<bool> EditAssignedCollections(Guid orgId);
Task<bool> DeleteAssignedCollections(Guid orgId);
Task<bool> ViewAssignedCollections(Guid orgId);
Task<bool> ManageGroups(Guid orgId);
Task<bool> ManagePolicies(Guid orgId);
Task<bool> ManageSso(Guid orgId);
Task<bool> ManageUsers(Guid orgId);
Task<bool> ManageScim(Guid orgId);
Task<bool> ManageResetPassword(Guid orgId);
Task<bool> ManageBilling(Guid orgId);
Task<bool> ProviderUserForOrgAsync(Guid orgId);
bool ProviderProviderAdmin(Guid providerId);
bool ProviderUser(Guid providerId);
bool ProviderManageUsers(Guid providerId);
bool ProviderAccessEventLogs(Guid providerId);
bool AccessProviderOrganizations(Guid providerId);
bool ManageProviderOrganizations(Guid providerId);
Task<ICollection<CurrentContentOrganization>> OrganizationMembershipAsync(
IOrganizationUserRepository organizationUserRepository, Guid userId);
Task<ICollection<CurrentContentOrganization>> OrganizationMembershipAsync(
IOrganizationUserRepository organizationUserRepository, Guid userId);
Task<ICollection<CurrentContentProvider>> ProviderMembershipAsync(
IProviderUserRepository providerUserRepository, Guid userId);
Task<ICollection<CurrentContentProvider>> ProviderMembershipAsync(
IProviderUserRepository providerUserRepository, Guid userId);
Task<Guid?> ProviderIdForOrg(Guid orgId);
Task<Guid?> ProviderIdForOrg(Guid orgId);
}
}

View File

@ -2,107 +2,108 @@
using Bit.Core.Models.Data;
using Bit.Core.Utilities;
namespace Bit.Core.Entities;
public class Cipher : ITableObject<Guid>, ICloneable
namespace Bit.Core.Entities
{
private Dictionary<string, CipherAttachment.MetaData> _attachmentData;
public Guid Id { get; set; }
public Guid? UserId { get; set; }
public Guid? OrganizationId { get; set; }
public Enums.CipherType Type { get; set; }
public string Data { get; set; }
public string Favorites { get; set; }
public string Folders { get; set; }
public string Attachments { get; set; }
public DateTime CreationDate { get; set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; set; } = DateTime.UtcNow;
public DateTime? DeletedDate { get; set; }
public Enums.CipherRepromptType? Reprompt { get; set; }
public void SetNewId()
public class Cipher : ITableObject<Guid>, ICloneable
{
Id = CoreHelpers.GenerateComb();
}
private Dictionary<string, CipherAttachment.MetaData> _attachmentData;
public Dictionary<string, CipherAttachment.MetaData> GetAttachments()
{
if (string.IsNullOrWhiteSpace(Attachments))
public Guid Id { get; set; }
public Guid? UserId { get; set; }
public Guid? OrganizationId { get; set; }
public Enums.CipherType Type { get; set; }
public string Data { get; set; }
public string Favorites { get; set; }
public string Folders { get; set; }
public string Attachments { get; set; }
public DateTime CreationDate { get; set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; set; } = DateTime.UtcNow;
public DateTime? DeletedDate { get; set; }
public Enums.CipherRepromptType? Reprompt { get; set; }
public void SetNewId()
{
return null;
Id = CoreHelpers.GenerateComb();
}
if (_attachmentData != null)
public Dictionary<string, CipherAttachment.MetaData> GetAttachments()
{
return _attachmentData;
}
try
{
_attachmentData = JsonSerializer.Deserialize<Dictionary<string, CipherAttachment.MetaData>>(Attachments);
foreach (var kvp in _attachmentData)
if (string.IsNullOrWhiteSpace(Attachments))
{
kvp.Value.AttachmentId = kvp.Key;
return null;
}
if (_attachmentData != null)
{
return _attachmentData;
}
try
{
_attachmentData = JsonSerializer.Deserialize<Dictionary<string, CipherAttachment.MetaData>>(Attachments);
foreach (var kvp in _attachmentData)
{
kvp.Value.AttachmentId = kvp.Key;
}
return _attachmentData;
}
catch
{
return null;
}
return _attachmentData;
}
catch
public void SetAttachments(Dictionary<string, CipherAttachment.MetaData> data)
{
return null;
}
}
if (data == null || data.Count == 0)
{
_attachmentData = null;
Attachments = null;
return;
}
public void SetAttachments(Dictionary<string, CipherAttachment.MetaData> data)
{
if (data == null || data.Count == 0)
_attachmentData = data;
Attachments = JsonSerializer.Serialize(_attachmentData);
}
public void AddAttachment(string id, CipherAttachment.MetaData data)
{
_attachmentData = null;
Attachments = null;
return;
var attachments = GetAttachments();
if (attachments == null)
{
attachments = new Dictionary<string, CipherAttachment.MetaData>();
}
attachments.Add(id, data);
SetAttachments(attachments);
}
_attachmentData = data;
Attachments = JsonSerializer.Serialize(_attachmentData);
}
public void AddAttachment(string id, CipherAttachment.MetaData data)
{
var attachments = GetAttachments();
if (attachments == null)
public void DeleteAttachment(string id)
{
attachments = new Dictionary<string, CipherAttachment.MetaData>();
var attachments = GetAttachments();
if (!attachments?.ContainsKey(id) ?? true)
{
return;
}
attachments.Remove(id);
SetAttachments(attachments);
}
attachments.Add(id, data);
SetAttachments(attachments);
}
public void DeleteAttachment(string id)
{
var attachments = GetAttachments();
if (!attachments?.ContainsKey(id) ?? true)
public bool ContainsAttachment(string id)
{
return;
var attachments = GetAttachments();
return attachments?.ContainsKey(id) ?? false;
}
attachments.Remove(id);
SetAttachments(attachments);
}
object ICloneable.Clone() => Clone();
public Cipher Clone()
{
var clone = CoreHelpers.CloneObject(this);
clone.CreationDate = CreationDate;
clone.RevisionDate = RevisionDate;
public bool ContainsAttachment(string id)
{
var attachments = GetAttachments();
return attachments?.ContainsKey(id) ?? false;
}
object ICloneable.Clone() => Clone();
public Cipher Clone()
{
var clone = CoreHelpers.CloneObject(this);
clone.CreationDate = CreationDate;
clone.RevisionDate = RevisionDate;
return clone;
return clone;
}
}
}

View File

@ -1,20 +1,21 @@
using System.ComponentModel.DataAnnotations;
using Bit.Core.Utilities;
namespace Bit.Core.Entities;
public class Collection : ITableObject<Guid>
namespace Bit.Core.Entities
{
public Guid Id { get; set; }
public Guid OrganizationId { get; set; }
public string Name { get; set; }
[MaxLength(300)]
public string ExternalId { get; set; }
public DateTime CreationDate { get; set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; set; } = DateTime.UtcNow;
public void SetNewId()
public class Collection : ITableObject<Guid>
{
Id = CoreHelpers.GenerateComb();
public Guid Id { get; set; }
public Guid OrganizationId { get; set; }
public string Name { get; set; }
[MaxLength(300)]
public string ExternalId { get; set; }
public DateTime CreationDate { get; set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; set; } = DateTime.UtcNow;
public void SetNewId()
{
Id = CoreHelpers.GenerateComb();
}
}
}

View File

@ -1,7 +1,8 @@
namespace Bit.Core.Entities;
public class CollectionCipher
namespace Bit.Core.Entities
{
public Guid CollectionId { get; set; }
public Guid CipherId { get; set; }
public class CollectionCipher
{
public Guid CollectionId { get; set; }
public Guid CipherId { get; set; }
}
}

View File

@ -1,9 +1,10 @@
namespace Bit.Core.Entities;
public class CollectionGroup
namespace Bit.Core.Entities
{
public Guid CollectionId { get; set; }
public Guid GroupId { get; set; }
public bool ReadOnly { get; set; }
public bool HidePasswords { get; set; }
public class CollectionGroup
{
public Guid CollectionId { get; set; }
public Guid GroupId { get; set; }
public bool ReadOnly { get; set; }
public bool HidePasswords { get; set; }
}
}

View File

@ -1,9 +1,10 @@
namespace Bit.Core.Entities;
public class CollectionUser
namespace Bit.Core.Entities
{
public Guid CollectionId { get; set; }
public Guid OrganizationUserId { get; set; }
public bool ReadOnly { get; set; }
public bool HidePasswords { get; set; }
public class CollectionUser
{
public Guid CollectionId { get; set; }
public Guid OrganizationUserId { get; set; }
public bool ReadOnly { get; set; }
public bool HidePasswords { get; set; }
}
}

View File

@ -1,24 +1,25 @@
using System.ComponentModel.DataAnnotations;
using Bit.Core.Utilities;
namespace Bit.Core.Entities;
public class Device : ITableObject<Guid>
namespace Bit.Core.Entities
{
public Guid Id { get; set; }
public Guid UserId { get; set; }
[MaxLength(50)]
public string Name { get; set; }
public Enums.DeviceType Type { get; set; }
[MaxLength(50)]
public string Identifier { get; set; }
[MaxLength(255)]
public string PushToken { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
public void SetNewId()
public class Device : ITableObject<Guid>
{
Id = CoreHelpers.GenerateComb();
public Guid Id { get; set; }
public Guid UserId { get; set; }
[MaxLength(50)]
public string Name { get; set; }
public Enums.DeviceType Type { get; set; }
[MaxLength(50)]
public string Identifier { get; set; }
[MaxLength(255)]
public string PushToken { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
public void SetNewId()
{
Id = CoreHelpers.GenerateComb();
}
}
}

View File

@ -2,45 +2,46 @@
using Bit.Core.Enums;
using Bit.Core.Utilities;
namespace Bit.Core.Entities;
public class EmergencyAccess : ITableObject<Guid>
namespace Bit.Core.Entities
{
public Guid Id { get; set; }
public Guid GrantorId { get; set; }
public Guid? GranteeId { get; set; }
[MaxLength(256)]
public string Email { get; set; }
public string KeyEncrypted { get; set; }
public EmergencyAccessType Type { get; set; }
public EmergencyAccessStatusType Status { get; set; }
public int WaitTimeDays { get; set; }
public DateTime? RecoveryInitiatedDate { get; set; }
public DateTime? LastNotificationDate { get; set; }
public DateTime CreationDate { get; set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; set; } = DateTime.UtcNow;
public void SetNewId()
public class EmergencyAccess : ITableObject<Guid>
{
Id = CoreHelpers.GenerateComb();
}
public Guid Id { get; set; }
public Guid GrantorId { get; set; }
public Guid? GranteeId { get; set; }
[MaxLength(256)]
public string Email { get; set; }
public string KeyEncrypted { get; set; }
public EmergencyAccessType Type { get; set; }
public EmergencyAccessStatusType Status { get; set; }
public int WaitTimeDays { get; set; }
public DateTime? RecoveryInitiatedDate { get; set; }
public DateTime? LastNotificationDate { get; set; }
public DateTime CreationDate { get; set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; set; } = DateTime.UtcNow;
public EmergencyAccess ToEmergencyAccess()
{
return new EmergencyAccess
public void SetNewId()
{
Id = Id,
GrantorId = GrantorId,
GranteeId = GranteeId,
Email = Email,
KeyEncrypted = KeyEncrypted,
Type = Type,
Status = Status,
WaitTimeDays = WaitTimeDays,
RecoveryInitiatedDate = RecoveryInitiatedDate,
LastNotificationDate = LastNotificationDate,
CreationDate = CreationDate,
RevisionDate = RevisionDate,
};
Id = CoreHelpers.GenerateComb();
}
public EmergencyAccess ToEmergencyAccess()
{
return new EmergencyAccess
{
Id = Id,
GrantorId = GrantorId,
GranteeId = GranteeId,
Email = Email,
KeyEncrypted = KeyEncrypted,
Type = Type,
Status = Status,
WaitTimeDays = WaitTimeDays,
RecoveryInitiatedDate = RecoveryInitiatedDate,
LastNotificationDate = LastNotificationDate,
CreationDate = CreationDate,
RevisionDate = RevisionDate,
};
}
}
}

View File

@ -3,53 +3,54 @@ using Bit.Core.Enums;
using Bit.Core.Models.Data;
using Bit.Core.Utilities;
namespace Bit.Core.Entities;
public class Event : ITableObject<Guid>, IEvent
namespace Bit.Core.Entities
{
public Event() { }
public Event(IEvent e)
public class Event : ITableObject<Guid>, IEvent
{
Date = e.Date;
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;
InstallationId = e.InstallationId;
ProviderUserId = e.ProviderUserId;
ProviderOrganizationId = e.ProviderOrganizationId;
DeviceType = e.DeviceType;
IpAddress = e.IpAddress;
ActingUserId = e.ActingUserId;
}
public Event() { }
public Guid Id { get; set; }
public DateTime Date { get; set; }
public EventType Type { get; set; }
public Guid? UserId { get; set; }
public Guid? OrganizationId { get; set; }
public Guid? InstallationId { 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 Guid? ProviderOrganizationId { get; set; }
public DeviceType? DeviceType { get; set; }
[MaxLength(50)]
public string IpAddress { get; set; }
public Guid? ActingUserId { get; set; }
public Event(IEvent e)
{
Date = e.Date;
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;
InstallationId = e.InstallationId;
ProviderUserId = e.ProviderUserId;
ProviderOrganizationId = e.ProviderOrganizationId;
DeviceType = e.DeviceType;
IpAddress = e.IpAddress;
ActingUserId = e.ActingUserId;
}
public void SetNewId()
{
Id = CoreHelpers.GenerateComb();
public Guid Id { get; set; }
public DateTime Date { get; set; }
public EventType Type { get; set; }
public Guid? UserId { get; set; }
public Guid? OrganizationId { get; set; }
public Guid? InstallationId { 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 Guid? ProviderOrganizationId { get; set; }
public DeviceType? DeviceType { get; set; }
[MaxLength(50)]
public string IpAddress { get; set; }
public Guid? ActingUserId { get; set; }
public void SetNewId()
{
Id = CoreHelpers.GenerateComb();
}
}
}

View File

@ -1,17 +1,18 @@
using Bit.Core.Utilities;
namespace Bit.Core.Entities;
public class Folder : ITableObject<Guid>
namespace Bit.Core.Entities
{
public Guid Id { get; set; }
public Guid UserId { get; set; }
public string Name { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
public void SetNewId()
public class Folder : ITableObject<Guid>
{
Id = CoreHelpers.GenerateComb();
public Guid Id { get; set; }
public Guid UserId { get; set; }
public string Name { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
public void SetNewId()
{
Id = CoreHelpers.GenerateComb();
}
}
}

View File

@ -1,23 +1,24 @@
using System.ComponentModel.DataAnnotations;
namespace Bit.Core.Entities;
public class Grant
namespace Bit.Core.Entities
{
[MaxLength(200)]
public string Key { get; set; }
[MaxLength(50)]
public string Type { get; set; }
[MaxLength(200)]
public string SubjectId { get; set; }
[MaxLength(100)]
public string SessionId { get; set; }
[MaxLength(200)]
public string ClientId { get; set; }
[MaxLength(200)]
public string Description { get; set; }
public DateTime CreationDate { get; set; }
public DateTime? ExpirationDate { get; set; }
public DateTime? ConsumedDate { get; set; }
public string Data { get; set; }
public class Grant
{
[MaxLength(200)]
public string Key { get; set; }
[MaxLength(50)]
public string Type { get; set; }
[MaxLength(200)]
public string SubjectId { get; set; }
[MaxLength(100)]
public string SessionId { get; set; }
[MaxLength(200)]
public string ClientId { get; set; }
[MaxLength(200)]
public string Description { get; set; }
public DateTime CreationDate { get; set; }
public DateTime? ExpirationDate { get; set; }
public DateTime? ConsumedDate { get; set; }
public string Data { get; set; }
}
}

View File

@ -2,22 +2,23 @@
using Bit.Core.Models;
using Bit.Core.Utilities;
namespace Bit.Core.Entities;
public class Group : ITableObject<Guid>, IExternal
namespace Bit.Core.Entities
{
public Guid Id { get; set; }
public Guid OrganizationId { get; set; }
[MaxLength(100)]
public string Name { get; set; }
public bool AccessAll { get; set; }
[MaxLength(300)]
public string ExternalId { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
public void SetNewId()
public class Group : ITableObject<Guid>, IExternal
{
Id = CoreHelpers.GenerateComb();
public Guid Id { get; set; }
public Guid OrganizationId { get; set; }
[MaxLength(100)]
public string Name { get; set; }
public bool AccessAll { get; set; }
[MaxLength(300)]
public string ExternalId { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
public void SetNewId()
{
Id = CoreHelpers.GenerateComb();
}
}
}

View File

@ -1,7 +1,8 @@
namespace Bit.Core.Entities;
public class GroupUser
namespace Bit.Core.Entities
{
public Guid GroupId { get; set; }
public Guid OrganizationUserId { get; set; }
public class GroupUser
{
public Guid GroupId { get; set; }
public Guid OrganizationUserId { get; set; }
}
}

View File

@ -1,8 +1,9 @@
namespace Bit.Core.Entities;
public interface IReferenceable
namespace Bit.Core.Entities
{
Guid Id { get; set; }
string ReferenceData { get; set; }
bool IsUser();
public interface IReferenceable
{
Guid Id { get; set; }
string ReferenceData { get; set; }
bool IsUser();
}
}

View File

@ -1,7 +1,8 @@
namespace Bit.Core.Entities;
public interface IRevisable
namespace Bit.Core.Entities
{
DateTime CreationDate { get; }
DateTime RevisionDate { get; }
public interface IRevisable
{
DateTime CreationDate { get; }
DateTime RevisionDate { get; }
}
}

View File

@ -1,9 +1,10 @@
namespace Bit.Core.Entities;
public interface IStorable
namespace Bit.Core.Entities
{
long? Storage { get; set; }
short? MaxStorageGb { get; set; }
long StorageBytesRemaining();
long StorageBytesRemaining(short maxStorageGb);
public interface IStorable
{
long? Storage { get; set; }
short? MaxStorageGb { get; set; }
long StorageBytesRemaining();
long StorageBytesRemaining(short maxStorageGb);
}
}

View File

@ -1,4 +1,5 @@
namespace Bit.Core.Entities;
public interface IStorableSubscriber : IStorable, ISubscriber
{ }
namespace Bit.Core.Entities
{
public interface IStorableSubscriber : IStorable, ISubscriber
{ }
}

View File

@ -1,17 +1,18 @@
using Bit.Core.Enums;
namespace Bit.Core.Entities;
public interface ISubscriber
namespace Bit.Core.Entities
{
Guid Id { get; }
GatewayType? Gateway { get; set; }
string GatewayCustomerId { get; set; }
string GatewaySubscriptionId { get; set; }
string BillingEmailAddress();
string BillingName();
string BraintreeCustomerIdPrefix();
string BraintreeIdField();
string GatewayIdField();
bool IsUser();
public interface ISubscriber
{
Guid Id { get; }
GatewayType? Gateway { get; set; }
string GatewayCustomerId { get; set; }
string GatewaySubscriptionId { get; set; }
string BillingEmailAddress();
string BillingName();
string BraintreeCustomerIdPrefix();
string BraintreeIdField();
string GatewayIdField();
bool IsUser();
}
}

View File

@ -1,7 +1,8 @@
namespace Bit.Core.Entities;
public interface ITableObject<T> where T : IEquatable<T>
namespace Bit.Core.Entities
{
T Id { get; set; }
void SetNewId();
public interface ITableObject<T> where T : IEquatable<T>
{
T Id { get; set; }
void SetNewId();
}
}

View File

@ -1,20 +1,21 @@
using System.ComponentModel.DataAnnotations;
using Bit.Core.Utilities;
namespace Bit.Core.Entities;
public class Installation : ITableObject<Guid>
namespace Bit.Core.Entities
{
public Guid Id { get; set; }
[MaxLength(256)]
public string Email { get; set; }
[MaxLength(150)]
public string Key { get; set; }
public bool Enabled { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public void SetNewId()
public class Installation : ITableObject<Guid>
{
Id = CoreHelpers.GenerateComb();
public Guid Id { get; set; }
[MaxLength(256)]
public string Email { get; set; }
[MaxLength(150)]
public string Key { get; set; }
public bool Enabled { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public void SetNewId()
{
Id = CoreHelpers.GenerateComb();
}
}
}

View File

@ -4,195 +4,196 @@ using Bit.Core.Enums;
using Bit.Core.Models;
using Bit.Core.Utilities;
namespace Bit.Core.Entities;
public class Organization : ITableObject<Guid>, ISubscriber, IStorable, IStorableSubscriber, IRevisable, IReferenceable
namespace Bit.Core.Entities
{
private Dictionary<TwoFactorProviderType, TwoFactorProvider> _twoFactorProviders;
public Guid Id { get; set; }
[MaxLength(50)]
public string Identifier { get; set; }
[MaxLength(50)]
public string Name { get; set; }
[MaxLength(50)]
public string BusinessName { get; set; }
[MaxLength(50)]
public string BusinessAddress1 { get; set; }
[MaxLength(50)]
public string BusinessAddress2 { get; set; }
[MaxLength(50)]
public string BusinessAddress3 { get; set; }
[MaxLength(2)]
public string BusinessCountry { get; set; }
[MaxLength(30)]
public string BusinessTaxNumber { get; set; }
[MaxLength(256)]
public string BillingEmail { get; set; }
[MaxLength(50)]
public string Plan { get; set; }
public PlanType PlanType { get; set; }
public int? Seats { get; set; }
public short? MaxCollections { get; set; }
public bool UsePolicies { get; set; }
public bool UseSso { get; set; }
public bool UseKeyConnector { get; set; }
public bool UseScim { 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 SelfHost { get; set; }
public bool UsersGetPremium { get; set; }
public long? Storage { get; set; }
public short? MaxStorageGb { get; set; }
public GatewayType? Gateway { get; set; }
[MaxLength(50)]
public string GatewayCustomerId { get; set; }
[MaxLength(50)]
public string GatewaySubscriptionId { get; set; }
public string ReferenceData { get; set; }
public bool Enabled { get; set; } = true;
[MaxLength(100)]
public string LicenseKey { get; set; }
public string PublicKey { get; set; }
public string PrivateKey { get; set; }
public string TwoFactorProviders { get; set; }
public DateTime? ExpirationDate { get; set; }
public DateTime CreationDate { get; set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; set; } = DateTime.UtcNow;
public int? MaxAutoscaleSeats { get; set; } = null;
public DateTime? OwnersNotifiedOfAutoscaling { get; set; } = null;
public void SetNewId()
public class Organization : ITableObject<Guid>, ISubscriber, IStorable, IStorableSubscriber, IRevisable, IReferenceable
{
if (Id == default(Guid))
private Dictionary<TwoFactorProviderType, TwoFactorProvider> _twoFactorProviders;
public Guid Id { get; set; }
[MaxLength(50)]
public string Identifier { get; set; }
[MaxLength(50)]
public string Name { get; set; }
[MaxLength(50)]
public string BusinessName { get; set; }
[MaxLength(50)]
public string BusinessAddress1 { get; set; }
[MaxLength(50)]
public string BusinessAddress2 { get; set; }
[MaxLength(50)]
public string BusinessAddress3 { get; set; }
[MaxLength(2)]
public string BusinessCountry { get; set; }
[MaxLength(30)]
public string BusinessTaxNumber { get; set; }
[MaxLength(256)]
public string BillingEmail { get; set; }
[MaxLength(50)]
public string Plan { get; set; }
public PlanType PlanType { get; set; }
public int? Seats { get; set; }
public short? MaxCollections { get; set; }
public bool UsePolicies { get; set; }
public bool UseSso { get; set; }
public bool UseKeyConnector { get; set; }
public bool UseScim { 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 SelfHost { get; set; }
public bool UsersGetPremium { get; set; }
public long? Storage { get; set; }
public short? MaxStorageGb { get; set; }
public GatewayType? Gateway { get; set; }
[MaxLength(50)]
public string GatewayCustomerId { get; set; }
[MaxLength(50)]
public string GatewaySubscriptionId { get; set; }
public string ReferenceData { get; set; }
public bool Enabled { get; set; } = true;
[MaxLength(100)]
public string LicenseKey { get; set; }
public string PublicKey { get; set; }
public string PrivateKey { get; set; }
public string TwoFactorProviders { get; set; }
public DateTime? ExpirationDate { get; set; }
public DateTime CreationDate { get; set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; set; } = DateTime.UtcNow;
public int? MaxAutoscaleSeats { get; set; } = null;
public DateTime? OwnersNotifiedOfAutoscaling { get; set; } = null;
public void SetNewId()
{
Id = CoreHelpers.GenerateComb();
}
}
public string BillingEmailAddress()
{
return BillingEmail?.ToLowerInvariant()?.Trim();
}
public string BillingName()
{
return BusinessName;
}
public string BraintreeCustomerIdPrefix()
{
return "o";
}
public string BraintreeIdField()
{
return "organization_id";
}
public string GatewayIdField()
{
return "organizationId";
}
public bool IsUser()
{
return false;
}
public long StorageBytesRemaining()
{
if (!MaxStorageGb.HasValue)
{
return 0;
}
return StorageBytesRemaining(MaxStorageGb.Value);
}
public long StorageBytesRemaining(short maxStorageGb)
{
var maxStorageBytes = maxStorageGb * 1073741824L;
if (!Storage.HasValue)
{
return maxStorageBytes;
}
return maxStorageBytes - Storage.Value;
}
public Dictionary<TwoFactorProviderType, TwoFactorProvider> GetTwoFactorProviders()
{
if (string.IsNullOrWhiteSpace(TwoFactorProviders))
{
return null;
}
try
{
if (_twoFactorProviders == null)
if (Id == default(Guid))
{
_twoFactorProviders =
JsonHelpers.LegacyDeserialize<Dictionary<TwoFactorProviderType, TwoFactorProvider>>(
TwoFactorProviders);
Id = CoreHelpers.GenerateComb();
}
}
public string BillingEmailAddress()
{
return BillingEmail?.ToLowerInvariant()?.Trim();
}
public string BillingName()
{
return BusinessName;
}
public string BraintreeCustomerIdPrefix()
{
return "o";
}
public string BraintreeIdField()
{
return "organization_id";
}
public string GatewayIdField()
{
return "organizationId";
}
public bool IsUser()
{
return false;
}
public long StorageBytesRemaining()
{
if (!MaxStorageGb.HasValue)
{
return 0;
}
return _twoFactorProviders;
return StorageBytesRemaining(MaxStorageGb.Value);
}
catch (JsonException)
public long StorageBytesRemaining(short maxStorageGb)
{
return null;
}
}
var maxStorageBytes = maxStorageGb * 1073741824L;
if (!Storage.HasValue)
{
return maxStorageBytes;
}
public void SetTwoFactorProviders(Dictionary<TwoFactorProviderType, TwoFactorProvider> providers)
{
if (!providers.Any())
return maxStorageBytes - Storage.Value;
}
public Dictionary<TwoFactorProviderType, TwoFactorProvider> GetTwoFactorProviders()
{
TwoFactorProviders = null;
_twoFactorProviders = null;
return;
if (string.IsNullOrWhiteSpace(TwoFactorProviders))
{
return null;
}
try
{
if (_twoFactorProviders == null)
{
_twoFactorProviders =
JsonHelpers.LegacyDeserialize<Dictionary<TwoFactorProviderType, TwoFactorProvider>>(
TwoFactorProviders);
}
return _twoFactorProviders;
}
catch (JsonException)
{
return null;
}
}
TwoFactorProviders = JsonHelpers.LegacySerialize(providers, JsonHelpers.LegacyEnumKeyResolver);
_twoFactorProviders = providers;
}
public bool TwoFactorProviderIsEnabled(TwoFactorProviderType provider)
{
var providers = GetTwoFactorProviders();
if (providers == null || !providers.ContainsKey(provider))
public void SetTwoFactorProviders(Dictionary<TwoFactorProviderType, TwoFactorProvider> providers)
{
return false;
if (!providers.Any())
{
TwoFactorProviders = null;
_twoFactorProviders = null;
return;
}
TwoFactorProviders = JsonHelpers.LegacySerialize(providers, JsonHelpers.LegacyEnumKeyResolver);
_twoFactorProviders = providers;
}
return providers[provider].Enabled && Use2fa;
}
public bool TwoFactorIsEnabled()
{
var providers = GetTwoFactorProviders();
if (providers == null)
public bool TwoFactorProviderIsEnabled(TwoFactorProviderType provider)
{
return false;
var providers = GetTwoFactorProviders();
if (providers == null || !providers.ContainsKey(provider))
{
return false;
}
return providers[provider].Enabled && Use2fa;
}
return providers.Any(p => (p.Value?.Enabled ?? false) && Use2fa);
}
public TwoFactorProvider GetTwoFactorProvider(TwoFactorProviderType provider)
{
var providers = GetTwoFactorProviders();
if (providers == null || !providers.ContainsKey(provider))
public bool TwoFactorIsEnabled()
{
return null;
var providers = GetTwoFactorProviders();
if (providers == null)
{
return false;
}
return providers.Any(p => (p.Value?.Enabled ?? false) && Use2fa);
}
return providers[provider];
public TwoFactorProvider GetTwoFactorProvider(TwoFactorProviderType provider)
{
var providers = GetTwoFactorProviders();
if (providers == null || !providers.ContainsKey(provider))
{
return null;
}
return providers[provider];
}
}
}

View File

@ -2,19 +2,20 @@
using Bit.Core.Enums;
using Bit.Core.Utilities;
namespace Bit.Core.Entities;
public class OrganizationApiKey : ITableObject<Guid>
namespace Bit.Core.Entities
{
public Guid Id { get; set; }
public Guid OrganizationId { get; set; }
public OrganizationApiKeyType Type { get; set; }
[MaxLength(30)]
public string ApiKey { get; set; }
public DateTime RevisionDate { get; set; }
public void SetNewId()
public class OrganizationApiKey : ITableObject<Guid>
{
Id = CoreHelpers.GenerateComb();
public Guid Id { get; set; }
public Guid OrganizationId { get; set; }
public OrganizationApiKeyType Type { get; set; }
[MaxLength(30)]
public string ApiKey { get; set; }
public DateTime RevisionDate { get; set; }
public void SetNewId()
{
Id = CoreHelpers.GenerateComb();
}
}
}

View File

@ -2,44 +2,45 @@
using Bit.Core.Enums;
using Bit.Core.Utilities;
namespace Bit.Core.Entities;
public class OrganizationConnection<T> : OrganizationConnection where T : new()
namespace Bit.Core.Entities
{
public new T Config
public class OrganizationConnection<T> : OrganizationConnection where T : new()
{
get => base.GetConfig<T>();
set => base.SetConfig<T>(value);
}
}
public class OrganizationConnection : ITableObject<Guid>
{
public Guid Id { get; set; }
public OrganizationConnectionType Type { get; set; }
public Guid OrganizationId { get; set; }
public bool Enabled { get; set; }
public string Config { get; set; }
public void SetNewId()
{
Id = CoreHelpers.GenerateComb();
}
public T GetConfig<T>() where T : new()
{
try
public new T Config
{
return JsonSerializer.Deserialize<T>(Config);
}
catch (JsonException)
{
return default;
get => base.GetConfig<T>();
set => base.SetConfig<T>(value);
}
}
public void SetConfig<T>(T config) where T : new()
public class OrganizationConnection : ITableObject<Guid>
{
Config = JsonSerializer.Serialize(config);
public Guid Id { get; set; }
public OrganizationConnectionType Type { get; set; }
public Guid OrganizationId { get; set; }
public bool Enabled { get; set; }
public string Config { get; set; }
public void SetNewId()
{
Id = CoreHelpers.GenerateComb();
}
public T GetConfig<T>() where T : new()
{
try
{
return JsonSerializer.Deserialize<T>(Config);
}
catch (JsonException)
{
return default;
}
}
public void SetConfig<T>(T config) where T : new()
{
Config = JsonSerializer.Serialize(config);
}
}
}

View File

@ -2,25 +2,26 @@
using Bit.Core.Enums;
using Bit.Core.Utilities;
namespace Bit.Core.Entities;
public class OrganizationSponsorship : ITableObject<Guid>
namespace Bit.Core.Entities
{
public Guid Id { get; set; }
public Guid? SponsoringOrganizationId { get; set; }
public Guid SponsoringOrganizationUserId { get; set; }
public Guid? SponsoredOrganizationId { get; set; }
[MaxLength(256)]
public string FriendlyName { get; set; }
[MaxLength(256)]
public string OfferedToEmail { get; set; }
public PlanSponsorshipType? PlanSponsorshipType { get; set; }
public DateTime? LastSyncDate { get; set; }
public DateTime? ValidUntil { get; set; }
public bool ToDelete { get; set; }
public void SetNewId()
public class OrganizationSponsorship : ITableObject<Guid>
{
Id = CoreHelpers.GenerateComb();
public Guid Id { get; set; }
public Guid? SponsoringOrganizationId { get; set; }
public Guid SponsoringOrganizationUserId { get; set; }
public Guid? SponsoredOrganizationId { get; set; }
[MaxLength(256)]
public string FriendlyName { get; set; }
[MaxLength(256)]
public string OfferedToEmail { get; set; }
public PlanSponsorshipType? PlanSponsorshipType { get; set; }
public DateTime? LastSyncDate { get; set; }
public DateTime? ValidUntil { get; set; }
public bool ToDelete { get; set; }
public void SetNewId()
{
Id = CoreHelpers.GenerateComb();
}
}
}

View File

@ -3,28 +3,29 @@ using Bit.Core.Enums;
using Bit.Core.Models;
using Bit.Core.Utilities;
namespace Bit.Core.Entities;
public class OrganizationUser : ITableObject<Guid>, IExternal
namespace Bit.Core.Entities
{
public Guid Id { get; set; }
public Guid OrganizationId { get; set; }
public Guid? UserId { get; set; }
[MaxLength(256)]
public string Email { get; set; }
public string Key { get; set; }
public string ResetPasswordKey { get; set; }
public OrganizationUserStatusType Status { get; set; }
public OrganizationUserType Type { get; set; }
public bool AccessAll { get; set; }
[MaxLength(300)]
public string ExternalId { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
public string Permissions { get; set; }
public void SetNewId()
public class OrganizationUser : ITableObject<Guid>, IExternal
{
Id = CoreHelpers.GenerateComb();
public Guid Id { get; set; }
public Guid OrganizationId { get; set; }
public Guid? UserId { get; set; }
[MaxLength(256)]
public string Email { get; set; }
public string Key { get; set; }
public string ResetPasswordKey { get; set; }
public OrganizationUserStatusType Status { get; set; }
public OrganizationUserType Type { get; set; }
public bool AccessAll { get; set; }
[MaxLength(300)]
public string ExternalId { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
public string Permissions { get; set; }
public void SetNewId()
{
Id = CoreHelpers.GenerateComb();
}
}
}

View File

@ -2,30 +2,31 @@
using Bit.Core.Models.Data.Organizations.Policies;
using Bit.Core.Utilities;
namespace Bit.Core.Entities;
public class Policy : ITableObject<Guid>
namespace Bit.Core.Entities
{
public Guid Id { get; set; }
public Guid OrganizationId { get; set; }
public PolicyType Type { get; set; }
public string Data { get; set; }
public bool Enabled { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
public void SetNewId()
public class Policy : ITableObject<Guid>
{
Id = CoreHelpers.GenerateComb();
}
public Guid Id { get; set; }
public Guid OrganizationId { get; set; }
public PolicyType Type { get; set; }
public string Data { get; set; }
public bool Enabled { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
public T GetDataModel<T>() where T : IPolicyDataModel, new()
{
return CoreHelpers.LoadClassFromJsonData<T>(Data);
}
public void SetNewId()
{
Id = CoreHelpers.GenerateComb();
}
public void SetDataModel<T>(T dataModel) where T : IPolicyDataModel, new()
{
Data = CoreHelpers.ClassToJsonData(dataModel);
public T GetDataModel<T>() where T : IPolicyDataModel, new()
{
return CoreHelpers.LoadClassFromJsonData<T>(Data);
}
public void SetDataModel<T>(T dataModel) where T : IPolicyDataModel, new()
{
Data = CoreHelpers.ClassToJsonData(dataModel);
}
}
}

View File

@ -1,30 +1,31 @@
using Bit.Core.Enums.Provider;
using Bit.Core.Utilities;
namespace Bit.Core.Entities.Provider;
public class Provider : ITableObject<Guid>
namespace Bit.Core.Entities.Provider
{
public Guid Id { get; set; }
public string Name { get; set; }
public string BusinessName { get; set; }
public string BusinessAddress1 { get; set; }
public string BusinessAddress2 { get; set; }
public string BusinessAddress3 { get; set; }
public string BusinessCountry { get; set; }
public string BusinessTaxNumber { get; set; }
public string BillingEmail { get; set; }
public ProviderStatusType Status { get; set; }
public bool UseEvents { get; set; }
public bool Enabled { get; set; } = true;
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
public void SetNewId()
public class Provider : ITableObject<Guid>
{
if (Id == default)
public Guid Id { get; set; }
public string Name { get; set; }
public string BusinessName { get; set; }
public string BusinessAddress1 { get; set; }
public string BusinessAddress2 { get; set; }
public string BusinessAddress3 { get; set; }
public string BusinessCountry { get; set; }
public string BusinessTaxNumber { get; set; }
public string BillingEmail { get; set; }
public ProviderStatusType Status { get; set; }
public bool UseEvents { get; set; }
public bool Enabled { get; set; } = true;
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
public void SetNewId()
{
Id = CoreHelpers.GenerateComb();
if (Id == default)
{
Id = CoreHelpers.GenerateComb();
}
}
}
}

View File

@ -1,22 +1,23 @@
using Bit.Core.Utilities;
namespace Bit.Core.Entities.Provider;
public class ProviderOrganization : ITableObject<Guid>
namespace Bit.Core.Entities.Provider
{
public Guid Id { get; set; }
public Guid ProviderId { get; set; }
public Guid OrganizationId { get; set; }
public string Key { get; set; }
public string Settings { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
public void SetNewId()
public class ProviderOrganization : ITableObject<Guid>
{
if (Id == default)
public Guid Id { get; set; }
public Guid ProviderId { get; set; }
public Guid OrganizationId { get; set; }
public string Key { get; set; }
public string Settings { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
public void SetNewId()
{
Id = CoreHelpers.GenerateComb();
if (Id == default)
{
Id = CoreHelpers.GenerateComb();
}
}
}
}

View File

@ -1,26 +1,27 @@
using Bit.Core.Enums.Provider;
using Bit.Core.Utilities;
namespace Bit.Core.Entities.Provider;
public class ProviderUser : ITableObject<Guid>
namespace Bit.Core.Entities.Provider
{
public Guid Id { get; set; }
public Guid ProviderId { get; set; }
public Guid? UserId { get; set; }
public string Email { get; set; }
public string Key { get; set; }
public ProviderUserStatusType Status { get; set; }
public ProviderUserType Type { get; set; }
public string Permissions { get; set; }
public DateTime CreationDate { get; set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; set; } = DateTime.UtcNow;
public void SetNewId()
public class ProviderUser : ITableObject<Guid>
{
if (Id == default)
public Guid Id { get; set; }
public Guid ProviderId { get; set; }
public Guid? UserId { get; set; }
public string Email { get; set; }
public string Key { get; set; }
public ProviderUserStatusType Status { get; set; }
public ProviderUserType Type { get; set; }
public string Permissions { get; set; }
public DateTime CreationDate { get; set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; set; } = DateTime.UtcNow;
public void SetNewId()
{
Id = CoreHelpers.GenerateComb();
if (Id == default)
{
Id = CoreHelpers.GenerateComb();
}
}
}
}

View File

@ -1,9 +1,10 @@
namespace Bit.Core.Entities;
/// <summary>
/// This class is not used. It is implemented to make the Identity provider happy.
/// </summary>
public class Role
namespace Bit.Core.Entities
{
public string Name { get; set; }
/// <summary>
/// This class is not used. It is implemented to make the Identity provider happy.
/// </summary>
public class Role
{
public string Name { get; set; }
}
}

View File

@ -2,29 +2,30 @@
using Bit.Core.Enums;
using Bit.Core.Utilities;
namespace Bit.Core.Entities;
public class Send : ITableObject<Guid>
namespace Bit.Core.Entities
{
public Guid Id { get; set; }
public Guid? UserId { get; set; }
public Guid? OrganizationId { get; set; }
public SendType Type { get; set; }
public string Data { get; set; }
public string Key { get; set; }
[MaxLength(300)]
public string Password { get; set; }
public int? MaxAccessCount { get; set; }
public int AccessCount { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
public DateTime? ExpirationDate { get; set; }
public DateTime DeletionDate { get; set; }
public bool Disabled { get; set; }
public bool? HideEmail { get; set; }
public void SetNewId()
public class Send : ITableObject<Guid>
{
Id = CoreHelpers.GenerateComb();
public Guid Id { get; set; }
public Guid? UserId { get; set; }
public Guid? OrganizationId { get; set; }
public SendType Type { get; set; }
public string Data { get; set; }
public string Key { get; set; }
[MaxLength(300)]
public string Password { get; set; }
public int? MaxAccessCount { get; set; }
public int AccessCount { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
public DateTime? ExpirationDate { get; set; }
public DateTime DeletionDate { get; set; }
public bool Disabled { get; set; }
public bool? HideEmail { get; set; }
public void SetNewId()
{
Id = CoreHelpers.GenerateComb();
}
}
}

View File

@ -1,29 +1,30 @@
using Bit.Core.Models.Data;
namespace Bit.Core.Entities;
public class SsoConfig : ITableObject<long>
namespace Bit.Core.Entities
{
public long Id { get; set; }
public bool Enabled { get; set; } = true;
public Guid OrganizationId { get; set; }
public string Data { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
public void SetNewId()
public class SsoConfig : ITableObject<long>
{
// int will be auto-populated
Id = 0;
}
public long Id { get; set; }
public bool Enabled { get; set; } = true;
public Guid OrganizationId { get; set; }
public string Data { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
public SsoConfigurationData GetData()
{
return SsoConfigurationData.Deserialize(Data);
}
public void SetNewId()
{
// int will be auto-populated
Id = 0;
}
public void SetData(SsoConfigurationData data)
{
Data = data.Serialize();
public SsoConfigurationData GetData()
{
return SsoConfigurationData.Deserialize(Data);
}
public void SetData(SsoConfigurationData data)
{
Data = data.Serialize();
}
}
}

View File

@ -1,19 +1,20 @@
using System.ComponentModel.DataAnnotations;
namespace Bit.Core.Entities;
public class SsoUser : ITableObject<long>
namespace Bit.Core.Entities
{
public long Id { get; set; }
public Guid UserId { get; set; }
public Guid? OrganizationId { get; set; }
[MaxLength(50)]
public string ExternalId { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public void SetNewId()
public class SsoUser : ITableObject<long>
{
// int will be auto-populated
Id = 0;
public long Id { get; set; }
public Guid UserId { get; set; }
public Guid? OrganizationId { get; set; }
[MaxLength(50)]
public string ExternalId { get; set; }
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
public void SetNewId()
{
// int will be auto-populated
Id = 0;
}
}
}

View File

@ -1,23 +1,24 @@
using System.ComponentModel.DataAnnotations;
namespace Bit.Core.Entities;
public class TaxRate : ITableObject<string>
namespace Bit.Core.Entities
{
[MaxLength(40)]
public string Id { get; set; }
[MaxLength(50)]
public string Country { get; set; }
[MaxLength(2)]
public string State { get; set; }
[MaxLength(10)]
public string PostalCode { get; set; }
public decimal Rate { get; set; }
public bool Active { get; set; }
public void SetNewId()
public class TaxRate : ITableObject<string>
{
// Id is created by Stripe, should exist before this gets called
return;
[MaxLength(40)]
public string Id { get; set; }
[MaxLength(50)]
public string Country { get; set; }
[MaxLength(2)]
public string State { get; set; }
[MaxLength(10)]
public string PostalCode { get; set; }
public decimal Rate { get; set; }
public bool Active { get; set; }
public void SetNewId()
{
// Id is created by Stripe, should exist before this gets called
return;
}
}
}

View File

@ -2,27 +2,28 @@
using Bit.Core.Enums;
using Bit.Core.Utilities;
namespace Bit.Core.Entities;
public class Transaction : ITableObject<Guid>
namespace Bit.Core.Entities
{
public Guid Id { get; set; }
public Guid? UserId { get; set; }
public Guid? OrganizationId { get; set; }
public TransactionType Type { get; set; }
public decimal Amount { get; set; }
public bool? Refunded { get; set; }
public decimal? RefundedAmount { get; set; }
[MaxLength(100)]
public string Details { get; set; }
public PaymentMethodType? PaymentMethodType { get; set; }
public GatewayType? Gateway { get; set; }
[MaxLength(50)]
public string GatewayId { get; set; }
public DateTime CreationDate { get; set; } = DateTime.UtcNow;
public void SetNewId()
public class Transaction : ITableObject<Guid>
{
Id = CoreHelpers.GenerateComb();
public Guid Id { get; set; }
public Guid? UserId { get; set; }
public Guid? OrganizationId { get; set; }
public TransactionType Type { get; set; }
public decimal Amount { get; set; }
public bool? Refunded { get; set; }
public decimal? RefundedAmount { get; set; }
[MaxLength(100)]
public string Details { get; set; }
public PaymentMethodType? PaymentMethodType { get; set; }
public GatewayType? Gateway { get; set; }
[MaxLength(50)]
public string GatewayId { get; set; }
public DateTime CreationDate { get; set; } = DateTime.UtcNow;
public void SetNewId()
{
Id = CoreHelpers.GenerateComb();
}
}
}

View File

@ -5,188 +5,189 @@ using Bit.Core.Models;
using Bit.Core.Utilities;
using Microsoft.AspNetCore.Identity;
namespace Bit.Core.Entities;
public class User : ITableObject<Guid>, ISubscriber, IStorable, IStorableSubscriber, IRevisable, ITwoFactorProvidersUser, IReferenceable
namespace Bit.Core.Entities
{
private Dictionary<TwoFactorProviderType, TwoFactorProvider> _twoFactorProviders;
public Guid Id { get; set; }
[MaxLength(50)]
public string Name { get; set; }
[Required]
[MaxLength(256)]
public string Email { get; set; }
public bool EmailVerified { get; set; }
[MaxLength(300)]
public string MasterPassword { get; set; }
[MaxLength(50)]
public string MasterPasswordHint { get; set; }
[MaxLength(10)]
public string Culture { get; set; } = "en-US";
[Required]
[MaxLength(50)]
public string SecurityStamp { get; set; }
public string TwoFactorProviders { get; set; }
[MaxLength(32)]
public string TwoFactorRecoveryCode { get; set; }
public string EquivalentDomains { get; set; }
public string ExcludedGlobalEquivalentDomains { get; set; }
public DateTime AccountRevisionDate { get; set; } = DateTime.UtcNow;
public string Key { get; set; }
public string PublicKey { get; set; }
public string PrivateKey { get; set; }
public bool Premium { get; set; }
public DateTime? PremiumExpirationDate { get; set; }
public DateTime? RenewalReminderDate { get; set; }
public long? Storage { get; set; }
public short? MaxStorageGb { get; set; }
public GatewayType? Gateway { get; set; }
[MaxLength(50)]
public string GatewayCustomerId { get; set; }
[MaxLength(50)]
public string GatewaySubscriptionId { get; set; }
public string ReferenceData { get; set; }
[MaxLength(100)]
public string LicenseKey { get; set; }
[Required]
[MaxLength(30)]
public string ApiKey { get; set; }
public KdfType Kdf { get; set; } = KdfType.PBKDF2_SHA256;
public int KdfIterations { get; set; } = 5000;
public DateTime CreationDate { get; set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; set; } = DateTime.UtcNow;
public bool ForcePasswordReset { get; set; }
public bool UsesKeyConnector { get; set; }
public int FailedLoginCount { get; set; }
public DateTime? LastFailedLoginDate { get; set; }
public bool UnknownDeviceVerificationEnabled { get; set; }
public void SetNewId()
public class User : ITableObject<Guid>, ISubscriber, IStorable, IStorableSubscriber, IRevisable, ITwoFactorProvidersUser, IReferenceable
{
Id = CoreHelpers.GenerateComb();
}
private Dictionary<TwoFactorProviderType, TwoFactorProvider> _twoFactorProviders;
public string BillingEmailAddress()
{
return Email?.ToLowerInvariant()?.Trim();
}
public Guid Id { get; set; }
[MaxLength(50)]
public string Name { get; set; }
[Required]
[MaxLength(256)]
public string Email { get; set; }
public bool EmailVerified { get; set; }
[MaxLength(300)]
public string MasterPassword { get; set; }
[MaxLength(50)]
public string MasterPasswordHint { get; set; }
[MaxLength(10)]
public string Culture { get; set; } = "en-US";
[Required]
[MaxLength(50)]
public string SecurityStamp { get; set; }
public string TwoFactorProviders { get; set; }
[MaxLength(32)]
public string TwoFactorRecoveryCode { get; set; }
public string EquivalentDomains { get; set; }
public string ExcludedGlobalEquivalentDomains { get; set; }
public DateTime AccountRevisionDate { get; set; } = DateTime.UtcNow;
public string Key { get; set; }
public string PublicKey { get; set; }
public string PrivateKey { get; set; }
public bool Premium { get; set; }
public DateTime? PremiumExpirationDate { get; set; }
public DateTime? RenewalReminderDate { get; set; }
public long? Storage { get; set; }
public short? MaxStorageGb { get; set; }
public GatewayType? Gateway { get; set; }
[MaxLength(50)]
public string GatewayCustomerId { get; set; }
[MaxLength(50)]
public string GatewaySubscriptionId { get; set; }
public string ReferenceData { get; set; }
[MaxLength(100)]
public string LicenseKey { get; set; }
[Required]
[MaxLength(30)]
public string ApiKey { get; set; }
public KdfType Kdf { get; set; } = KdfType.PBKDF2_SHA256;
public int KdfIterations { get; set; } = 5000;
public DateTime CreationDate { get; set; } = DateTime.UtcNow;
public DateTime RevisionDate { get; set; } = DateTime.UtcNow;
public bool ForcePasswordReset { get; set; }
public bool UsesKeyConnector { get; set; }
public int FailedLoginCount { get; set; }
public DateTime? LastFailedLoginDate { get; set; }
public bool UnknownDeviceVerificationEnabled { get; set; }
public string BillingName()
{
return Name;
}
public string BraintreeCustomerIdPrefix()
{
return "u";
}
public string BraintreeIdField()
{
return "user_id";
}
public string GatewayIdField()
{
return "userId";
}
public bool IsUser()
{
return true;
}
public Dictionary<TwoFactorProviderType, TwoFactorProvider> GetTwoFactorProviders()
{
if (string.IsNullOrWhiteSpace(TwoFactorProviders))
public void SetNewId()
{
return null;
Id = CoreHelpers.GenerateComb();
}
try
public string BillingEmailAddress()
{
if (_twoFactorProviders == null)
return Email?.ToLowerInvariant()?.Trim();
}
public string BillingName()
{
return Name;
}
public string BraintreeCustomerIdPrefix()
{
return "u";
}
public string BraintreeIdField()
{
return "user_id";
}
public string GatewayIdField()
{
return "userId";
}
public bool IsUser()
{
return true;
}
public Dictionary<TwoFactorProviderType, TwoFactorProvider> GetTwoFactorProviders()
{
if (string.IsNullOrWhiteSpace(TwoFactorProviders))
{
_twoFactorProviders =
JsonHelpers.LegacyDeserialize<Dictionary<TwoFactorProviderType, TwoFactorProvider>>(
TwoFactorProviders);
return null;
}
return _twoFactorProviders;
}
catch (JsonException)
{
return null;
}
}
try
{
if (_twoFactorProviders == null)
{
_twoFactorProviders =
JsonHelpers.LegacyDeserialize<Dictionary<TwoFactorProviderType, TwoFactorProvider>>(
TwoFactorProviders);
}
public Guid? GetUserId()
{
return Id;
}
public bool GetPremium()
{
return Premium;
}
public void SetTwoFactorProviders(Dictionary<TwoFactorProviderType, TwoFactorProvider> providers)
{
// When replacing with system.text remember to remove the extra serialization in WebAuthnTokenProvider.
TwoFactorProviders = JsonHelpers.LegacySerialize(providers, JsonHelpers.LegacyEnumKeyResolver);
_twoFactorProviders = providers;
}
public void ClearTwoFactorProviders()
{
SetTwoFactorProviders(new Dictionary<TwoFactorProviderType, TwoFactorProvider>());
}
public TwoFactorProvider GetTwoFactorProvider(TwoFactorProviderType provider)
{
var providers = GetTwoFactorProviders();
if (providers == null || !providers.ContainsKey(provider))
{
return null;
return _twoFactorProviders;
}
catch (JsonException)
{
return null;
}
}
return providers[provider];
}
public long StorageBytesRemaining()
{
if (!MaxStorageGb.HasValue)
public Guid? GetUserId()
{
return 0;
return Id;
}
return StorageBytesRemaining(MaxStorageGb.Value);
}
public long StorageBytesRemaining(short maxStorageGb)
{
var maxStorageBytes = maxStorageGb * 1073741824L;
if (!Storage.HasValue)
public bool GetPremium()
{
return maxStorageBytes;
return Premium;
}
return maxStorageBytes - Storage.Value;
}
public IdentityUser ToIdentityUser(bool twoFactorEnabled)
{
return new IdentityUser
public void SetTwoFactorProviders(Dictionary<TwoFactorProviderType, TwoFactorProvider> providers)
{
Id = Id.ToString(),
Email = Email,
NormalizedEmail = Email,
EmailConfirmed = EmailVerified,
UserName = Email,
NormalizedUserName = Email,
TwoFactorEnabled = twoFactorEnabled,
SecurityStamp = SecurityStamp
};
// When replacing with system.text remember to remove the extra serialization in WebAuthnTokenProvider.
TwoFactorProviders = JsonHelpers.LegacySerialize(providers, JsonHelpers.LegacyEnumKeyResolver);
_twoFactorProviders = providers;
}
public void ClearTwoFactorProviders()
{
SetTwoFactorProviders(new Dictionary<TwoFactorProviderType, TwoFactorProvider>());
}
public TwoFactorProvider GetTwoFactorProvider(TwoFactorProviderType provider)
{
var providers = GetTwoFactorProviders();
if (providers == null || !providers.ContainsKey(provider))
{
return null;
}
return providers[provider];
}
public long StorageBytesRemaining()
{
if (!MaxStorageGb.HasValue)
{
return 0;
}
return StorageBytesRemaining(MaxStorageGb.Value);
}
public long StorageBytesRemaining(short maxStorageGb)
{
var maxStorageBytes = maxStorageGb * 1073741824L;
if (!Storage.HasValue)
{
return maxStorageBytes;
}
return maxStorageBytes - Storage.Value;
}
public IdentityUser ToIdentityUser(bool twoFactorEnabled)
{
return new IdentityUser
{
Id = Id.ToString(),
Email = Email,
NormalizedEmail = Email,
EmailConfirmed = EmailVerified,
UserName = Email,
NormalizedUserName = Email,
TwoFactorEnabled = twoFactorEnabled,
SecurityStamp = SecurityStamp
};
}
}
}

View File

@ -1,7 +1,8 @@
namespace Bit.Core.Enums;
public enum ApplicationCacheMessageType : byte
namespace Bit.Core.Enums
{
UpsertOrganizationAbility = 0,
DeleteOrganizationAbility = 1
public enum ApplicationCacheMessageType : byte
{
UpsertOrganizationAbility = 0,
DeleteOrganizationAbility = 1
}
}

View File

@ -1,12 +1,13 @@
namespace Bit.Core.Enums;
public static class BitwardenClient
namespace Bit.Core.Enums
{
public const string
Web = "web",
Browser = "browser",
Desktop = "desktop",
Mobile = "mobile",
Cli = "cli",
DirectoryConnector = "connector";
public static class BitwardenClient
{
public const string
Web = "web",
Browser = "browser",
Desktop = "desktop",
Mobile = "mobile",
Cli = "cli",
DirectoryConnector = "connector";
}
}

View File

@ -1,7 +1,8 @@
namespace Bit.Core.Enums;
public enum CipherRepromptType : byte
namespace Bit.Core.Enums
{
None = 0,
Password = 1,
public enum CipherRepromptType : byte
{
None = 0,
Password = 1,
}
}

View File

@ -1,8 +1,9 @@
namespace Bit.Core.Enums;
public enum CipherStateAction
namespace Bit.Core.Enums
{
Restore,
SoftDelete,
HardDelete,
public enum CipherStateAction
{
Restore,
SoftDelete,
HardDelete,
}
}

View File

@ -1,11 +1,12 @@
namespace Bit.Core.Enums;
public enum CipherType : byte
namespace Bit.Core.Enums
{
// Folder is deprecated
//Folder = 0,
Login = 1,
SecureNote = 2,
Card = 3,
Identity = 4
public enum CipherType : byte
{
// Folder is deprecated
//Folder = 0,
Login = 1,
SecureNote = 2,
Card = 3,
Identity = 4
}
}

View File

@ -1,49 +1,50 @@
using System.ComponentModel.DataAnnotations;
namespace Bit.Core.Enums;
public enum DeviceType : byte
namespace Bit.Core.Enums
{
[Display(Name = "Android")]
Android = 0,
[Display(Name = "iOS")]
iOS = 1,
[Display(Name = "Chrome Extension")]
ChromeExtension = 2,
[Display(Name = "Firefox Extension")]
FirefoxExtension = 3,
[Display(Name = "Opera Extension")]
OperaExtension = 4,
[Display(Name = "Edge Extension")]
EdgeExtension = 5,
[Display(Name = "Windows")]
WindowsDesktop = 6,
[Display(Name = "macOS")]
MacOsDesktop = 7,
[Display(Name = "Linux")]
LinuxDesktop = 8,
[Display(Name = "Chrome")]
ChromeBrowser = 9,
[Display(Name = "Firefox")]
FirefoxBrowser = 10,
[Display(Name = "Opera")]
OperaBrowser = 11,
[Display(Name = "Edge")]
EdgeBrowser = 12,
[Display(Name = "Internet Explorer")]
IEBrowser = 13,
[Display(Name = "Unknown Browser")]
UnknownBrowser = 14,
[Display(Name = "Android")]
AndroidAmazon = 15,
[Display(Name = "UWP")]
UWP = 16,
[Display(Name = "Safari")]
SafariBrowser = 17,
[Display(Name = "Vivaldi")]
VivaldiBrowser = 18,
[Display(Name = "Vivaldi Extension")]
VivaldiExtension = 19,
[Display(Name = "Safari Extension")]
SafariExtension = 20
public enum DeviceType : byte
{
[Display(Name = "Android")]
Android = 0,
[Display(Name = "iOS")]
iOS = 1,
[Display(Name = "Chrome Extension")]
ChromeExtension = 2,
[Display(Name = "Firefox Extension")]
FirefoxExtension = 3,
[Display(Name = "Opera Extension")]
OperaExtension = 4,
[Display(Name = "Edge Extension")]
EdgeExtension = 5,
[Display(Name = "Windows")]
WindowsDesktop = 6,
[Display(Name = "macOS")]
MacOsDesktop = 7,
[Display(Name = "Linux")]
LinuxDesktop = 8,
[Display(Name = "Chrome")]
ChromeBrowser = 9,
[Display(Name = "Firefox")]
FirefoxBrowser = 10,
[Display(Name = "Opera")]
OperaBrowser = 11,
[Display(Name = "Edge")]
EdgeBrowser = 12,
[Display(Name = "Internet Explorer")]
IEBrowser = 13,
[Display(Name = "Unknown Browser")]
UnknownBrowser = 14,
[Display(Name = "Android")]
AndroidAmazon = 15,
[Display(Name = "UWP")]
UWP = 16,
[Display(Name = "Safari")]
SafariBrowser = 17,
[Display(Name = "Vivaldi")]
VivaldiBrowser = 18,
[Display(Name = "Vivaldi Extension")]
VivaldiExtension = 19,
[Display(Name = "Safari Extension")]
SafariExtension = 20
}
}

View File

@ -1,10 +1,11 @@
namespace Bit.Core.Enums;
public enum EmergencyAccessStatusType : byte
namespace Bit.Core.Enums
{
Invited = 0,
Accepted = 1,
Confirmed = 2,
RecoveryInitiated = 3,
RecoveryApproved = 4,
public enum EmergencyAccessStatusType : byte
{
Invited = 0,
Accepted = 1,
Confirmed = 2,
RecoveryInitiated = 3,
RecoveryApproved = 4,
}
}

View File

@ -1,7 +1,8 @@
namespace Bit.Core.Enums;
public enum EmergencyAccessType : byte
namespace Bit.Core.Enums
{
View = 0,
Takeover = 1,
public enum EmergencyAccessType : byte
{
View = 0,
Takeover = 1,
}
}

View File

@ -1,12 +1,13 @@
namespace Bit.Core.Enums;
public enum EncryptionType : byte
namespace Bit.Core.Enums
{
AesCbc256_B64 = 0,
AesCbc128_HmacSha256_B64 = 1,
AesCbc256_HmacSha256_B64 = 2,
Rsa2048_OaepSha256_B64 = 3,
Rsa2048_OaepSha1_B64 = 4,
Rsa2048_OaepSha256_HmacSha256_B64 = 5,
Rsa2048_OaepSha1_HmacSha256_B64 = 6
public enum EncryptionType : byte
{
AesCbc256_B64 = 0,
AesCbc128_HmacSha256_B64 = 1,
AesCbc256_HmacSha256_B64 = 2,
Rsa2048_OaepSha256_B64 = 3,
Rsa2048_OaepSha1_B64 = 4,
Rsa2048_OaepSha256_HmacSha256_B64 = 5,
Rsa2048_OaepSha1_HmacSha256_B64 = 6
}
}

View File

@ -1,78 +1,79 @@
namespace Bit.Core.Enums;
public enum EventType : int
namespace Bit.Core.Enums
{
User_LoggedIn = 1000,
User_ChangedPassword = 1001,
User_Updated2fa = 1002,
User_Disabled2fa = 1003,
User_Recovered2fa = 1004,
User_FailedLogIn = 1005,
User_FailedLogIn2fa = 1006,
User_ClientExportedVault = 1007,
User_UpdatedTempPassword = 1008,
User_MigratedKeyToKeyConnector = 1009,
public enum EventType : int
{
User_LoggedIn = 1000,
User_ChangedPassword = 1001,
User_Updated2fa = 1002,
User_Disabled2fa = 1003,
User_Recovered2fa = 1004,
User_FailedLogIn = 1005,
User_FailedLogIn2fa = 1006,
User_ClientExportedVault = 1007,
User_UpdatedTempPassword = 1008,
User_MigratedKeyToKeyConnector = 1009,
Cipher_Created = 1100,
Cipher_Updated = 1101,
Cipher_Deleted = 1102,
Cipher_AttachmentCreated = 1103,
Cipher_AttachmentDeleted = 1104,
Cipher_Shared = 1105,
Cipher_UpdatedCollections = 1106,
Cipher_ClientViewed = 1107,
Cipher_ClientToggledPasswordVisible = 1108,
Cipher_ClientToggledHiddenFieldVisible = 1109,
Cipher_ClientToggledCardCodeVisible = 1110,
Cipher_ClientCopiedPassword = 1111,
Cipher_ClientCopiedHiddenField = 1112,
Cipher_ClientCopiedCardCode = 1113,
Cipher_ClientAutofilled = 1114,
Cipher_SoftDeleted = 1115,
Cipher_Restored = 1116,
Cipher_ClientToggledCardNumberVisible = 1117,
Cipher_Created = 1100,
Cipher_Updated = 1101,
Cipher_Deleted = 1102,
Cipher_AttachmentCreated = 1103,
Cipher_AttachmentDeleted = 1104,
Cipher_Shared = 1105,
Cipher_UpdatedCollections = 1106,
Cipher_ClientViewed = 1107,
Cipher_ClientToggledPasswordVisible = 1108,
Cipher_ClientToggledHiddenFieldVisible = 1109,
Cipher_ClientToggledCardCodeVisible = 1110,
Cipher_ClientCopiedPassword = 1111,
Cipher_ClientCopiedHiddenField = 1112,
Cipher_ClientCopiedCardCode = 1113,
Cipher_ClientAutofilled = 1114,
Cipher_SoftDeleted = 1115,
Cipher_Restored = 1116,
Cipher_ClientToggledCardNumberVisible = 1117,
Collection_Created = 1300,
Collection_Updated = 1301,
Collection_Deleted = 1302,
Collection_Created = 1300,
Collection_Updated = 1301,
Collection_Deleted = 1302,
Group_Created = 1400,
Group_Updated = 1401,
Group_Deleted = 1402,
Group_Created = 1400,
Group_Updated = 1401,
Group_Deleted = 1402,
OrganizationUser_Invited = 1500,
OrganizationUser_Confirmed = 1501,
OrganizationUser_Updated = 1502,
OrganizationUser_Removed = 1503,
OrganizationUser_UpdatedGroups = 1504,
OrganizationUser_UnlinkedSso = 1505,
OrganizationUser_ResetPassword_Enroll = 1506,
OrganizationUser_ResetPassword_Withdraw = 1507,
OrganizationUser_AdminResetPassword = 1508,
OrganizationUser_ResetSsoLink = 1509,
OrganizationUser_FirstSsoLogin = 1510,
OrganizationUser_Revoked = 1511,
OrganizationUser_Restored = 1512,
OrganizationUser_Invited = 1500,
OrganizationUser_Confirmed = 1501,
OrganizationUser_Updated = 1502,
OrganizationUser_Removed = 1503,
OrganizationUser_UpdatedGroups = 1504,
OrganizationUser_UnlinkedSso = 1505,
OrganizationUser_ResetPassword_Enroll = 1506,
OrganizationUser_ResetPassword_Withdraw = 1507,
OrganizationUser_AdminResetPassword = 1508,
OrganizationUser_ResetSsoLink = 1509,
OrganizationUser_FirstSsoLogin = 1510,
OrganizationUser_Revoked = 1511,
OrganizationUser_Restored = 1512,
Organization_Updated = 1600,
Organization_PurgedVault = 1601,
Organization_ClientExportedVault = 1602,
Organization_VaultAccessed = 1603,
Organization_EnabledSso = 1604,
Organization_DisabledSso = 1605,
Organization_EnabledKeyConnector = 1606,
Organization_DisabledKeyConnector = 1607,
Organization_SponsorshipsSynced = 1608,
Organization_Updated = 1600,
Organization_PurgedVault = 1601,
Organization_ClientExportedVault = 1602,
Organization_VaultAccessed = 1603,
Organization_EnabledSso = 1604,
Organization_DisabledSso = 1605,
Organization_EnabledKeyConnector = 1606,
Organization_DisabledKeyConnector = 1607,
Organization_SponsorshipsSynced = 1608,
Policy_Updated = 1700,
Policy_Updated = 1700,
ProviderUser_Invited = 1800,
ProviderUser_Confirmed = 1801,
ProviderUser_Updated = 1802,
ProviderUser_Removed = 1803,
ProviderUser_Invited = 1800,
ProviderUser_Confirmed = 1801,
ProviderUser_Updated = 1802,
ProviderUser_Removed = 1803,
ProviderOrganization_Created = 1900,
ProviderOrganization_Added = 1901,
ProviderOrganization_Removed = 1902,
ProviderOrganization_VaultAccessed = 1903,
ProviderOrganization_Created = 1900,
ProviderOrganization_Added = 1901,
ProviderOrganization_Removed = 1902,
ProviderOrganization_VaultAccessed = 1903,
}
}

View File

@ -1,9 +1,10 @@
namespace Bit.Core.Enums;
public enum FieldType : byte
namespace Bit.Core.Enums
{
Text = 0,
Hidden = 1,
Boolean = 2,
Linked = 3,
public enum FieldType : byte
{
Text = 0,
Hidden = 1,
Boolean = 2,
Linked = 3,
}
}

View File

@ -1,7 +1,8 @@
namespace Bit.Core.Enums;
public enum FileUploadType
namespace Bit.Core.Enums
{
Direct = 0,
Azure = 1,
public enum FileUploadType
{
Direct = 0,
Azure = 1,
}
}

View File

@ -1,21 +1,22 @@
using System.ComponentModel.DataAnnotations;
namespace Bit.Core.Enums;
public enum GatewayType : byte
namespace Bit.Core.Enums
{
[Display(Name = "Stripe")]
Stripe = 0,
[Display(Name = "Braintree")]
Braintree = 1,
[Display(Name = "Apple App Store")]
AppStore = 2,
[Display(Name = "Google Play Store")]
PlayStore = 3,
[Display(Name = "BitPay")]
BitPay = 4,
[Display(Name = "PayPal")]
PayPal = 5,
[Display(Name = "Bank")]
Bank = 6,
public enum GatewayType : byte
{
[Display(Name = "Stripe")]
Stripe = 0,
[Display(Name = "Braintree")]
Braintree = 1,
[Display(Name = "Apple App Store")]
AppStore = 2,
[Display(Name = "Google Play Store")]
PlayStore = 3,
[Display(Name = "BitPay")]
BitPay = 4,
[Display(Name = "PayPal")]
PayPal = 5,
[Display(Name = "Bank")]
Bank = 6,
}
}

View File

@ -1,94 +1,95 @@
namespace Bit.Core.Enums;
public enum GlobalEquivalentDomainsType : byte
namespace Bit.Core.Enums
{
Google = 0,
Apple = 1,
Ameritrade = 2,
BoA = 3,
Sprint = 4,
WellsFargo = 5,
Merrill = 6,
Citi = 7,
Cnet = 8,
Gap = 9,
Microsoft = 10,
United = 11,
Yahoo = 12,
Zonelabs = 13,
PayPal = 14,
Avon = 15,
Diapers = 16,
Contacts = 17,
Amazon = 18,
Cox = 19,
Norton = 20,
Verizon = 21,
Buy = 22,
Sirius = 23,
Ea = 24,
Basecamp = 25,
Steam = 26,
Chart = 27,
Gotomeeting = 28,
Gogo = 29,
Oracle = 30,
Discover = 31,
Dcu = 32,
Healthcare = 33,
Pepco = 34,
Century21 = 35,
Comcast = 36,
Cricket = 37,
Mtb = 38,
Dropbox = 39,
Snapfish = 40,
Alibaba = 41,
Playstation = 42,
Mercado = 43,
Zendesk = 44,
Autodesk = 45,
RailNation = 46,
Wpcu = 47,
Mathletics = 48,
Discountbank = 49,
Mi = 50,
Facebook = 51,
Postepay = 52,
Skysports = 53,
Disney = 54,
Pokemon = 55,
Uv = 56,
Yahavo = 57,
Mdsol = 58,
Sears = 59,
Xiami = 60,
Belkin = 61,
Turbotax = 62,
Shopify = 63,
Ebay = 64,
Techdata = 65,
Schwab = 66,
Mozilla = 67, // deprecated
Tesla = 68,
MorganStanley = 69,
TaxAct = 70,
Wikimedia = 71,
Airbnb = 72,
Eventbrite = 73,
StackExchange = 74,
Docusign = 75,
Envato = 76,
X10Hosting = 77,
Cisco = 78,
CedarFair = 79,
Ubiquiti = 80,
Discord = 81,
Netcup = 82,
Yandex = 83,
Sony = 84,
Proton = 85,
Ubisoft = 86,
TransferWise = 87,
TakeawayEU = 88,
public enum GlobalEquivalentDomainsType : byte
{
Google = 0,
Apple = 1,
Ameritrade = 2,
BoA = 3,
Sprint = 4,
WellsFargo = 5,
Merrill = 6,
Citi = 7,
Cnet = 8,
Gap = 9,
Microsoft = 10,
United = 11,
Yahoo = 12,
Zonelabs = 13,
PayPal = 14,
Avon = 15,
Diapers = 16,
Contacts = 17,
Amazon = 18,
Cox = 19,
Norton = 20,
Verizon = 21,
Buy = 22,
Sirius = 23,
Ea = 24,
Basecamp = 25,
Steam = 26,
Chart = 27,
Gotomeeting = 28,
Gogo = 29,
Oracle = 30,
Discover = 31,
Dcu = 32,
Healthcare = 33,
Pepco = 34,
Century21 = 35,
Comcast = 36,
Cricket = 37,
Mtb = 38,
Dropbox = 39,
Snapfish = 40,
Alibaba = 41,
Playstation = 42,
Mercado = 43,
Zendesk = 44,
Autodesk = 45,
RailNation = 46,
Wpcu = 47,
Mathletics = 48,
Discountbank = 49,
Mi = 50,
Facebook = 51,
Postepay = 52,
Skysports = 53,
Disney = 54,
Pokemon = 55,
Uv = 56,
Yahavo = 57,
Mdsol = 58,
Sears = 59,
Xiami = 60,
Belkin = 61,
Turbotax = 62,
Shopify = 63,
Ebay = 64,
Techdata = 65,
Schwab = 66,
Mozilla = 67, // deprecated
Tesla = 68,
MorganStanley = 69,
TaxAct = 70,
Wikimedia = 71,
Airbnb = 72,
Eventbrite = 73,
StackExchange = 74,
Docusign = 75,
Envato = 76,
X10Hosting = 77,
Cisco = 78,
CedarFair = 79,
Ubiquiti = 80,
Discord = 81,
Netcup = 82,
Yandex = 83,
Sony = 84,
Proton = 85,
Ubisoft = 86,
TransferWise = 87,
TakeawayEU = 88,
}
}

View File

@ -1,6 +1,7 @@
namespace Bit.Core.Enums;
public enum KdfType : byte
namespace Bit.Core.Enums
{
PBKDF2_SHA256 = 0
public enum KdfType : byte
{
PBKDF2_SHA256 = 0
}
}

View File

@ -1,7 +1,8 @@
namespace Bit.Core.Enums;
public enum LicenseType : byte
namespace Bit.Core.Enums
{
User = 0,
Organization = 1,
public enum LicenseType : byte
{
User = 0,
Organization = 1,
}
}

View File

@ -1,8 +1,9 @@
namespace Bit.Core.Enums;
public enum OrganizationApiKeyType : byte
namespace Bit.Core.Enums
{
Default = 0,
BillingSync = 1,
Scim = 2,
public enum OrganizationApiKeyType : byte
{
Default = 0,
BillingSync = 1,
Scim = 2,
}
}

View File

@ -1,7 +1,8 @@
namespace Bit.Core.Enums;
public enum OrganizationConnectionType : byte
namespace Bit.Core.Enums
{
CloudBillingSync = 1,
Scim = 2,
public enum OrganizationConnectionType : byte
{
CloudBillingSync = 1,
Scim = 2,
}
}

View File

@ -1,9 +1,10 @@
namespace Bit.Core.Enums;
public enum OrganizationUserStatusType : short
namespace Bit.Core.Enums
{
Invited = 0,
Accepted = 1,
Confirmed = 2,
Revoked = -1,
public enum OrganizationUserStatusType : short
{
Invited = 0,
Accepted = 1,
Confirmed = 2,
Revoked = -1,
}
}

View File

@ -1,10 +1,11 @@
namespace Bit.Core.Enums;
public enum OrganizationUserType : byte
namespace Bit.Core.Enums
{
Owner = 0,
Admin = 1,
User = 2,
Manager = 3,
Custom = 4,
public enum OrganizationUserType : byte
{
Owner = 0,
Admin = 1,
User = 2,
Manager = 3,
Custom = 4,
}
}

View File

@ -1,27 +1,28 @@
using System.ComponentModel.DataAnnotations;
namespace Bit.Core.Enums;
public enum PaymentMethodType : byte
namespace Bit.Core.Enums
{
[Display(Name = "Card")]
Card = 0,
[Display(Name = "Bank Account")]
BankAccount = 1,
[Display(Name = "PayPal")]
PayPal = 2,
[Display(Name = "BitPay")]
BitPay = 3,
[Display(Name = "Credit")]
Credit = 4,
[Display(Name = "Wire Transfer")]
WireTransfer = 5,
[Display(Name = "Apple In-App Purchase")]
AppleInApp = 6,
[Display(Name = "Google In-App Purchase")]
GoogleInApp = 7,
[Display(Name = "Check")]
Check = 8,
[Display(Name = "None")]
None = 255,
public enum PaymentMethodType : byte
{
[Display(Name = "Card")]
Card = 0,
[Display(Name = "Bank Account")]
BankAccount = 1,
[Display(Name = "PayPal")]
PayPal = 2,
[Display(Name = "BitPay")]
BitPay = 3,
[Display(Name = "Credit")]
Credit = 4,
[Display(Name = "Wire Transfer")]
WireTransfer = 5,
[Display(Name = "Apple In-App Purchase")]
AppleInApp = 6,
[Display(Name = "Google In-App Purchase")]
GoogleInApp = 7,
[Display(Name = "Check")]
Check = 8,
[Display(Name = "None")]
None = 255,
}
}

View File

@ -1,9 +1,10 @@
using System.ComponentModel.DataAnnotations;
namespace Bit.Core.Enums;
public enum PlanSponsorshipType : byte
namespace Bit.Core.Enums
{
[Display(Name = "Families For Enterprise")]
FamiliesForEnterprise = 0,
public enum PlanSponsorshipType : byte
{
[Display(Name = "Families For Enterprise")]
FamiliesForEnterprise = 0,
}
}

View File

@ -1,31 +1,32 @@
using System.ComponentModel.DataAnnotations;
namespace Bit.Core.Enums;
public enum PlanType : byte
namespace Bit.Core.Enums
{
[Display(Name = "Free")]
Free = 0,
[Display(Name = "Families 2019")]
FamiliesAnnually2019 = 1,
[Display(Name = "Teams (Monthly) 2019")]
TeamsMonthly2019 = 2,
[Display(Name = "Teams (Annually) 2019")]
TeamsAnnually2019 = 3,
[Display(Name = "Enterprise (Monthly) 2019")]
EnterpriseMonthly2019 = 4,
[Display(Name = "Enterprise (Annually) 2019")]
EnterpriseAnnually2019 = 5,
[Display(Name = "Custom")]
Custom = 6,
[Display(Name = "Families")]
FamiliesAnnually = 7,
[Display(Name = "Teams (Monthly)")]
TeamsMonthly = 8,
[Display(Name = "Teams (Annually)")]
TeamsAnnually = 9,
[Display(Name = "Enterprise (Monthly)")]
EnterpriseMonthly = 10,
[Display(Name = "Enterprise (Annually)")]
EnterpriseAnnually = 11,
public enum PlanType : byte
{
[Display(Name = "Free")]
Free = 0,
[Display(Name = "Families 2019")]
FamiliesAnnually2019 = 1,
[Display(Name = "Teams (Monthly) 2019")]
TeamsMonthly2019 = 2,
[Display(Name = "Teams (Annually) 2019")]
TeamsAnnually2019 = 3,
[Display(Name = "Enterprise (Monthly) 2019")]
EnterpriseMonthly2019 = 4,
[Display(Name = "Enterprise (Annually) 2019")]
EnterpriseAnnually2019 = 5,
[Display(Name = "Custom")]
Custom = 6,
[Display(Name = "Families")]
FamiliesAnnually = 7,
[Display(Name = "Teams (Monthly)")]
TeamsMonthly = 8,
[Display(Name = "Teams (Annually)")]
TeamsAnnually = 9,
[Display(Name = "Enterprise (Monthly)")]
EnterpriseMonthly = 10,
[Display(Name = "Enterprise (Annually)")]
EnterpriseAnnually = 11,
}
}

View File

@ -1,16 +1,17 @@
namespace Bit.Core.Enums;
public enum PolicyType : byte
namespace Bit.Core.Enums
{
TwoFactorAuthentication = 0,
MasterPassword = 1,
PasswordGenerator = 2,
SingleOrg = 3,
RequireSso = 4,
PersonalOwnership = 5,
DisableSend = 6,
SendOptions = 7,
ResetPassword = 8,
MaximumVaultTimeout = 9,
DisablePersonalVaultExport = 10,
public enum PolicyType : byte
{
TwoFactorAuthentication = 0,
MasterPassword = 1,
PasswordGenerator = 2,
SingleOrg = 3,
RequireSso = 4,
PersonalOwnership = 5,
DisableSend = 6,
SendOptions = 7,
ResetPassword = 8,
MaximumVaultTimeout = 9,
DisablePersonalVaultExport = 10,
}
}

View File

@ -1,16 +1,17 @@
using System.ComponentModel.DataAnnotations;
namespace Bit.Core.Enums;
public enum ProductType : byte
namespace Bit.Core.Enums
{
[Display(Name = "Free")]
Free = 0,
[Display(Name = "Families")]
Families = 1,
[Display(Name = "Teams")]
Teams = 2,
[Display(Name = "Enterprise")]
Enterprise = 3,
public enum ProductType : byte
{
[Display(Name = "Free")]
Free = 0,
[Display(Name = "Families")]
Families = 1,
[Display(Name = "Teams")]
Teams = 2,
[Display(Name = "Enterprise")]
Enterprise = 3,
}
}

View File

@ -1,7 +1,8 @@
namespace Bit.Core.Enums.Provider;
public enum ProviderStatusType : byte
namespace Bit.Core.Enums.Provider
{
Pending = 0,
Created = 1,
public enum ProviderStatusType : byte
{
Pending = 0,
Created = 1,
}
}

View File

@ -1,8 +1,9 @@
namespace Bit.Core.Enums.Provider;
public enum ProviderUserStatusType : byte
namespace Bit.Core.Enums.Provider
{
Invited = 0,
Accepted = 1,
Confirmed = 2,
public enum ProviderUserStatusType : byte
{
Invited = 0,
Accepted = 1,
Confirmed = 2,
}
}

View File

@ -1,7 +1,8 @@
namespace Bit.Core.Enums.Provider;
public enum ProviderUserType : byte
namespace Bit.Core.Enums.Provider
{
ProviderAdmin = 0,
ServiceUser = 1,
public enum ProviderUserType : byte
{
ProviderAdmin = 0,
ServiceUser = 1,
}
}

View File

@ -1,23 +1,24 @@
namespace Bit.Core.Enums;
public enum PushType : byte
namespace Bit.Core.Enums
{
SyncCipherUpdate = 0,
SyncCipherCreate = 1,
SyncLoginDelete = 2,
SyncFolderDelete = 3,
SyncCiphers = 4,
public enum PushType : byte
{
SyncCipherUpdate = 0,
SyncCipherCreate = 1,
SyncLoginDelete = 2,
SyncFolderDelete = 3,
SyncCiphers = 4,
SyncVault = 5,
SyncOrgKeys = 6,
SyncFolderCreate = 7,
SyncFolderUpdate = 8,
SyncCipherDelete = 9,
SyncSettings = 10,
SyncVault = 5,
SyncOrgKeys = 6,
SyncFolderCreate = 7,
SyncFolderUpdate = 8,
SyncCipherDelete = 9,
SyncSettings = 10,
LogOut = 11,
LogOut = 11,
SyncSendCreate = 12,
SyncSendUpdate = 13,
SyncSendDelete = 14,
SyncSendCreate = 12,
SyncSendUpdate = 13,
SyncSendDelete = 14,
}
}

View File

@ -1,11 +1,12 @@
using System.Runtime.Serialization;
namespace Bit.Core.Enums;
public enum ReferenceEventSource
namespace Bit.Core.Enums
{
[EnumMember(Value = "organization")]
Organization,
[EnumMember(Value = "user")]
User,
public enum ReferenceEventSource
{
[EnumMember(Value = "organization")]
Organization,
[EnumMember(Value = "user")]
User,
}
}

View File

@ -1,43 +1,44 @@
using System.Runtime.Serialization;
namespace Bit.Core.Enums;
public enum ReferenceEventType
namespace Bit.Core.Enums
{
[EnumMember(Value = "signup")]
Signup,
[EnumMember(Value = "upgrade-plan")]
UpgradePlan,
[EnumMember(Value = "adjust-storage")]
AdjustStorage,
[EnumMember(Value = "adjust-seats")]
AdjustSeats,
[EnumMember(Value = "cancel-subscription")]
CancelSubscription,
[EnumMember(Value = "reinstate-subscription")]
ReinstateSubscription,
[EnumMember(Value = "delete-account")]
DeleteAccount,
[EnumMember(Value = "confirm-email")]
ConfirmEmailAddress,
[EnumMember(Value = "invited-users")]
InvitedUsers,
[EnumMember(Value = "rebilled")]
Rebilled,
[EnumMember(Value = "send-created")]
SendCreated,
[EnumMember(Value = "send-accessed")]
SendAccessed,
[EnumMember(Value = "directory-synced")]
DirectorySynced,
[EnumMember(Value = "vault-imported")]
VaultImported,
[EnumMember(Value = "cipher-created")]
CipherCreated,
[EnumMember(Value = "group-created")]
GroupCreated,
[EnumMember(Value = "collection-created")]
CollectionCreated,
[EnumMember(Value = "organization-edited-by-admin")]
OrganizationEditedByAdmin
public enum ReferenceEventType
{
[EnumMember(Value = "signup")]
Signup,
[EnumMember(Value = "upgrade-plan")]
UpgradePlan,
[EnumMember(Value = "adjust-storage")]
AdjustStorage,
[EnumMember(Value = "adjust-seats")]
AdjustSeats,
[EnumMember(Value = "cancel-subscription")]
CancelSubscription,
[EnumMember(Value = "reinstate-subscription")]
ReinstateSubscription,
[EnumMember(Value = "delete-account")]
DeleteAccount,
[EnumMember(Value = "confirm-email")]
ConfirmEmailAddress,
[EnumMember(Value = "invited-users")]
InvitedUsers,
[EnumMember(Value = "rebilled")]
Rebilled,
[EnumMember(Value = "send-created")]
SendCreated,
[EnumMember(Value = "send-accessed")]
SendAccessed,
[EnumMember(Value = "directory-synced")]
DirectorySynced,
[EnumMember(Value = "vault-imported")]
VaultImported,
[EnumMember(Value = "cipher-created")]
CipherCreated,
[EnumMember(Value = "group-created")]
GroupCreated,
[EnumMember(Value = "collection-created")]
CollectionCreated,
[EnumMember(Value = "organization-edited-by-admin")]
OrganizationEditedByAdmin
}
}

View File

@ -1,7 +1,8 @@
namespace Bit.Core.Enums;
public enum Saml2BindingType : byte
namespace Bit.Core.Enums
{
HttpRedirect = 1,
HttpPost = 2,
public enum Saml2BindingType : byte
{
HttpRedirect = 1,
HttpPost = 2,
}
}

View File

@ -1,14 +1,15 @@
namespace Bit.Core.Enums;
public enum Saml2NameIdFormat : byte
namespace Bit.Core.Enums
{
NotConfigured = 0,
Unspecified = 1,
EmailAddress = 2,
X509SubjectName = 3,
WindowsDomainQualifiedName = 4,
KerberosPrincipalName = 5,
EntityIdentifier = 6,
Persistent = 7,
Transient = 8,
public enum Saml2NameIdFormat : byte
{
NotConfigured = 0,
Unspecified = 1,
EmailAddress = 2,
X509SubjectName = 3,
WindowsDomainQualifiedName = 4,
KerberosPrincipalName = 5,
EntityIdentifier = 6,
Persistent = 7,
Transient = 8,
}
}

View File

@ -1,8 +1,9 @@
namespace Bit.Core.Enums;
public enum Saml2SigningBehavior : byte
namespace Bit.Core.Enums
{
IfIdpWantAuthnRequestsSigned = 0,
Always = 1,
Never = 3
public enum Saml2SigningBehavior : byte
{
IfIdpWantAuthnRequestsSigned = 0,
Always = 1,
Never = 3
}
}

View File

@ -1,12 +1,13 @@
namespace Bit.Core.Enums;
public enum ScimProviderType : byte
namespace Bit.Core.Enums
{
Default = 0,
AzureAd = 1,
Okta = 2,
OneLogin = 3,
JumpCloud = 4,
GoogleWorkspace = 5,
Rippling = 6,
public enum ScimProviderType : byte
{
Default = 0,
AzureAd = 1,
Okta = 2,
OneLogin = 3,
JumpCloud = 4,
GoogleWorkspace = 5,
Rippling = 6,
}
}

View File

@ -1,6 +1,7 @@
namespace Bit.Core.Enums;
public enum SecureNoteType : byte
namespace Bit.Core.Enums
{
Generic = 0
public enum SecureNoteType : byte
{
Generic = 0
}
}

View File

@ -1,7 +1,8 @@
namespace Bit.Core.Enums;
public enum SendType : byte
namespace Bit.Core.Enums
{
Text = 0,
File = 1
public enum SendType : byte
{
Text = 0,
File = 1
}
}

View File

@ -1,7 +1,8 @@
namespace Bit.Core.Enums;
public enum SsoType : byte
namespace Bit.Core.Enums
{
OpenIdConnect = 1,
Saml2 = 2,
public enum SsoType : byte
{
OpenIdConnect = 1,
Saml2 = 2,
}
}

View File

@ -1,9 +1,10 @@
namespace Bit.Core.Enums;
public enum SupportedDatabaseProviders
namespace Bit.Core.Enums
{
SqlServer,
MySql,
Postgres,
public enum SupportedDatabaseProviders
{
SqlServer,
MySql,
Postgres,
}
}

View File

@ -1,17 +1,18 @@
using System.ComponentModel.DataAnnotations;
namespace Bit.Core.Enums;
public enum TransactionType : byte
namespace Bit.Core.Enums
{
[Display(Name = "Charge")]
Charge = 0,
[Display(Name = "Credit")]
Credit = 1,
[Display(Name = "Promotional Credit")]
PromotionalCredit = 2,
[Display(Name = "Referral Credit")]
ReferralCredit = 3,
[Display(Name = "Refund")]
Refund = 4,
public enum TransactionType : byte
{
[Display(Name = "Charge")]
Charge = 0,
[Display(Name = "Credit")]
Credit = 1,
[Display(Name = "Promotional Credit")]
PromotionalCredit = 2,
[Display(Name = "Referral Credit")]
ReferralCredit = 3,
[Display(Name = "Refund")]
Refund = 4,
}
}

View File

@ -1,13 +1,14 @@
namespace Bit.Core.Enums;
public enum TwoFactorProviderType : byte
namespace Bit.Core.Enums
{
Authenticator = 0,
Email = 1,
Duo = 2,
YubiKey = 3,
U2f = 4, // Deprecated
Remember = 5,
OrganizationDuo = 6,
WebAuthn = 7,
public enum TwoFactorProviderType : byte
{
Authenticator = 0,
Email = 1,
Duo = 2,
YubiKey = 3,
U2f = 4, // Deprecated
Remember = 5,
OrganizationDuo = 6,
WebAuthn = 7,
}
}

View File

@ -1,11 +1,12 @@
namespace Bit.Core.Enums;
public enum UriMatchType : byte
namespace Bit.Core.Enums
{
Domain = 0,
Host = 1,
StartsWith = 2,
Exact = 3,
RegularExpression = 4,
Never = 5
public enum UriMatchType : byte
{
Domain = 0,
Host = 1,
StartsWith = 2,
Exact = 3,
RegularExpression = 4,
Never = 5
}
}

View File

@ -1,30 +1,31 @@
using Microsoft.AspNetCore.Mvc.ModelBinding;
namespace Bit.Core.Exceptions;
public class BadRequestException : Exception
namespace Bit.Core.Exceptions
{
public BadRequestException(string message)
: base(message)
{ }
public BadRequestException(string key, string errorMessage)
: base("The model state is invalid.")
public class BadRequestException : Exception
{
ModelState = new ModelStateDictionary();
ModelState.AddModelError(key, errorMessage);
}
public BadRequestException(string message)
: base(message)
{ }
public BadRequestException(ModelStateDictionary modelState)
: base("The model state is invalid.")
{
if (modelState.IsValid || modelState.ErrorCount == 0)
public BadRequestException(string key, string errorMessage)
: base("The model state is invalid.")
{
return;
ModelState = new ModelStateDictionary();
ModelState.AddModelError(key, errorMessage);
}
ModelState = modelState;
}
public BadRequestException(ModelStateDictionary modelState)
: base("The model state is invalid.")
{
if (modelState.IsValid || modelState.ErrorCount == 0)
{
return;
}
public ModelStateDictionary ModelState { get; set; }
ModelState = modelState;
}
public ModelStateDictionary ModelState { get; set; }
}
}

View File

@ -1,8 +1,9 @@
namespace Bit.Core.Exceptions;
public class GatewayException : Exception
namespace Bit.Core.Exceptions
{
public GatewayException(string message, Exception innerException = null)
: base(message, innerException)
{ }
public class GatewayException : Exception
{
public GatewayException(string message, Exception innerException = null)
: base(message, innerException)
{ }
}
}

View File

@ -1,10 +1,11 @@
namespace Bit.Core.Exceptions;
public class InvalidEmailException : Exception
namespace Bit.Core.Exceptions
{
public InvalidEmailException()
: base("Invalid email.")
public class InvalidEmailException : Exception
{
public InvalidEmailException()
: base("Invalid email.")
{
}
}
}

View File

@ -1,10 +1,11 @@
namespace Bit.Core.Exceptions;
public class InvalidGatewayCustomerIdException : Exception
namespace Bit.Core.Exceptions
{
public InvalidGatewayCustomerIdException()
: base("Invalid gateway customerId.")
public class InvalidGatewayCustomerIdException : Exception
{
public InvalidGatewayCustomerIdException()
: base("Invalid gateway customerId.")
{
}
}
}

View File

@ -1,3 +1,4 @@
namespace Bit.Core.Exceptions;
public class NotFoundException : Exception { }
namespace Bit.Core.Exceptions
{
public class NotFoundException : Exception { }
}

View File

@ -8,99 +8,100 @@ using Microsoft.Azure.ServiceBus.Management;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace Bit.Core.HostedServices;
public class ApplicationCacheHostedService : IHostedService, IDisposable
namespace Bit.Core.HostedServices
{
private readonly InMemoryServiceBusApplicationCacheService _applicationCacheService;
private readonly IOrganizationRepository _organizationRepository;
protected readonly ILogger<ApplicationCacheHostedService> _logger;
private readonly SubscriptionClient _subscriptionClient;
private readonly ManagementClient _managementClient;
private readonly string _subName;
private readonly string _topicName;
public ApplicationCacheHostedService(
IApplicationCacheService applicationCacheService,
IOrganizationRepository organizationRepository,
ILogger<ApplicationCacheHostedService> logger,
GlobalSettings globalSettings)
public class ApplicationCacheHostedService : IHostedService, IDisposable
{
_topicName = globalSettings.ServiceBus.ApplicationCacheTopicName;
_subName = CoreHelpers.GetApplicationCacheServiceBusSubcriptionName(globalSettings);
_applicationCacheService = applicationCacheService as InMemoryServiceBusApplicationCacheService;
_organizationRepository = organizationRepository;
_logger = logger;
_managementClient = new ManagementClient(globalSettings.ServiceBus.ConnectionString);
_subscriptionClient = new SubscriptionClient(globalSettings.ServiceBus.ConnectionString,
_topicName, _subName);
}
private readonly InMemoryServiceBusApplicationCacheService _applicationCacheService;
private readonly IOrganizationRepository _organizationRepository;
protected readonly ILogger<ApplicationCacheHostedService> _logger;
private readonly SubscriptionClient _subscriptionClient;
private readonly ManagementClient _managementClient;
private readonly string _subName;
private readonly string _topicName;
public virtual async Task StartAsync(CancellationToken cancellationToken)
{
try
public ApplicationCacheHostedService(
IApplicationCacheService applicationCacheService,
IOrganizationRepository organizationRepository,
ILogger<ApplicationCacheHostedService> logger,
GlobalSettings globalSettings)
{
await _managementClient.CreateSubscriptionAsync(new SubscriptionDescription(_topicName, _subName)
{
DefaultMessageTimeToLive = TimeSpan.FromDays(14),
LockDuration = TimeSpan.FromSeconds(30),
EnableDeadLetteringOnFilterEvaluationExceptions = true,
EnableDeadLetteringOnMessageExpiration = true,
}, new RuleDescription("default", new SqlFilter($"sys.Label != '{_subName}'")));
_topicName = globalSettings.ServiceBus.ApplicationCacheTopicName;
_subName = CoreHelpers.GetApplicationCacheServiceBusSubcriptionName(globalSettings);
_applicationCacheService = applicationCacheService as InMemoryServiceBusApplicationCacheService;
_organizationRepository = organizationRepository;
_logger = logger;
_managementClient = new ManagementClient(globalSettings.ServiceBus.ConnectionString);
_subscriptionClient = new SubscriptionClient(globalSettings.ServiceBus.ConnectionString,
_topicName, _subName);
}
catch (MessagingEntityAlreadyExistsException) { }
_subscriptionClient.RegisterMessageHandler(ProcessMessageAsync,
new MessageHandlerOptions(ExceptionReceivedHandlerAsync)
{
MaxConcurrentCalls = 2,
AutoComplete = false,
});
}
public virtual async Task StopAsync(CancellationToken cancellationToken)
{
await _subscriptionClient.CloseAsync();
try
public virtual async Task StartAsync(CancellationToken cancellationToken)
{
await _managementClient.DeleteSubscriptionAsync(_topicName, _subName, cancellationToken);
try
{
await _managementClient.CreateSubscriptionAsync(new SubscriptionDescription(_topicName, _subName)
{
DefaultMessageTimeToLive = TimeSpan.FromDays(14),
LockDuration = TimeSpan.FromSeconds(30),
EnableDeadLetteringOnFilterEvaluationExceptions = true,
EnableDeadLetteringOnMessageExpiration = true,
}, new RuleDescription("default", new SqlFilter($"sys.Label != '{_subName}'")));
}
catch (MessagingEntityAlreadyExistsException) { }
_subscriptionClient.RegisterMessageHandler(ProcessMessageAsync,
new MessageHandlerOptions(ExceptionReceivedHandlerAsync)
{
MaxConcurrentCalls = 2,
AutoComplete = false,
});
}
catch { }
}
public virtual void Dispose()
{ }
private async Task ProcessMessageAsync(Message message, CancellationToken cancellationToken)
{
if (message.Label != _subName && _applicationCacheService != null)
public virtual async Task StopAsync(CancellationToken cancellationToken)
{
switch ((ApplicationCacheMessageType)message.UserProperties["type"])
await _subscriptionClient.CloseAsync();
try
{
case ApplicationCacheMessageType.UpsertOrganizationAbility:
var upsertedOrgId = (Guid)message.UserProperties["id"];
var upsertedOrg = await _organizationRepository.GetByIdAsync(upsertedOrgId);
if (upsertedOrg != null)
{
await _applicationCacheService.BaseUpsertOrganizationAbilityAsync(upsertedOrg);
}
break;
case ApplicationCacheMessageType.DeleteOrganizationAbility:
await _applicationCacheService.BaseDeleteOrganizationAbilityAsync(
(Guid)message.UserProperties["id"]);
break;
default:
break;
await _managementClient.DeleteSubscriptionAsync(_topicName, _subName, cancellationToken);
}
catch { }
}
public virtual void Dispose()
{ }
private async Task ProcessMessageAsync(Message message, CancellationToken cancellationToken)
{
if (message.Label != _subName && _applicationCacheService != null)
{
switch ((ApplicationCacheMessageType)message.UserProperties["type"])
{
case ApplicationCacheMessageType.UpsertOrganizationAbility:
var upsertedOrgId = (Guid)message.UserProperties["id"];
var upsertedOrg = await _organizationRepository.GetByIdAsync(upsertedOrgId);
if (upsertedOrg != null)
{
await _applicationCacheService.BaseUpsertOrganizationAbilityAsync(upsertedOrg);
}
break;
case ApplicationCacheMessageType.DeleteOrganizationAbility:
await _applicationCacheService.BaseDeleteOrganizationAbilityAsync(
(Guid)message.UserProperties["id"]);
break;
default:
break;
}
}
if (!cancellationToken.IsCancellationRequested)
{
await _subscriptionClient.CompleteAsync(message.SystemProperties.LockToken);
}
}
if (!cancellationToken.IsCancellationRequested)
private Task ExceptionReceivedHandlerAsync(ExceptionReceivedEventArgs args)
{
await _subscriptionClient.CompleteAsync(message.SystemProperties.LockToken);
_logger.LogError(args.Exception, "Message handler encountered an exception.");
return Task.FromResult(0);
}
}
private Task ExceptionReceivedHandlerAsync(ExceptionReceivedEventArgs args)
{
_logger.LogError(args.Exception, "Message handler encountered an exception.");
return Task.FromResult(0);
}
}

View File

@ -1,40 +1,41 @@
using AspNetCoreRateLimit;
using Microsoft.Extensions.Hosting;
namespace Bit.Core.HostedServices;
/// <summary>
/// A startup service that will seed the IP rate limiting stores with any values in the
/// GlobalSettings configuration.
/// </summary>
/// <remarks>
/// <para>Using an <see cref="IHostedService"/> here because it runs before the request processing pipeline
/// is configured, so that any rate limiting configuration is seeded/applied before any requests come in.
/// </para>
/// <para>
/// This is a cleaner alternative to modifying Program.cs in every project that requires rate limiting as
/// described/suggested here:
/// https://github.com/stefanprodan/AspNetCoreRateLimit/wiki/Version-3.0.0-Breaking-Changes
/// </para>
/// </remarks>
public class IpRateLimitSeedStartupService : IHostedService
namespace Bit.Core.HostedServices
{
private readonly IIpPolicyStore _ipPolicyStore;
private readonly IClientPolicyStore _clientPolicyStore;
public IpRateLimitSeedStartupService(IIpPolicyStore ipPolicyStore, IClientPolicyStore clientPolicyStore)
/// <summary>
/// A startup service that will seed the IP rate limiting stores with any values in the
/// GlobalSettings configuration.
/// </summary>
/// <remarks>
/// <para>Using an <see cref="IHostedService"/> here because it runs before the request processing pipeline
/// is configured, so that any rate limiting configuration is seeded/applied before any requests come in.
/// </para>
/// <para>
/// This is a cleaner alternative to modifying Program.cs in every project that requires rate limiting as
/// described/suggested here:
/// https://github.com/stefanprodan/AspNetCoreRateLimit/wiki/Version-3.0.0-Breaking-Changes
/// </para>
/// </remarks>
public class IpRateLimitSeedStartupService : IHostedService
{
_ipPolicyStore = ipPolicyStore;
_clientPolicyStore = clientPolicyStore;
}
private readonly IIpPolicyStore _ipPolicyStore;
private readonly IClientPolicyStore _clientPolicyStore;
public async Task StartAsync(CancellationToken cancellationToken)
{
// Seed the policies from GlobalSettings
await _ipPolicyStore.SeedAsync();
await _clientPolicyStore.SeedAsync();
}
public IpRateLimitSeedStartupService(IIpPolicyStore ipPolicyStore, IClientPolicyStore clientPolicyStore)
{
_ipPolicyStore = ipPolicyStore;
_clientPolicyStore = clientPolicyStore;
}
// noop
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
public async Task StartAsync(CancellationToken cancellationToken)
{
// Seed the policies from GlobalSettings
await _ipPolicyStore.SeedAsync();
await _clientPolicyStore.SeedAsync();
}
// noop
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}
}

View File

@ -5,41 +5,42 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection;
using OtpNet;
namespace Bit.Core.Identity;
public class AuthenticatorTokenProvider : IUserTwoFactorTokenProvider<User>
namespace Bit.Core.Identity
{
private readonly IServiceProvider _serviceProvider;
public AuthenticatorTokenProvider(IServiceProvider serviceProvider)
public class AuthenticatorTokenProvider : IUserTwoFactorTokenProvider<User>
{
_serviceProvider = serviceProvider;
}
private readonly IServiceProvider _serviceProvider;
public async Task<bool> CanGenerateTwoFactorTokenAsync(UserManager<User> manager, User user)
{
var provider = user.GetTwoFactorProvider(TwoFactorProviderType.Authenticator);
if (string.IsNullOrWhiteSpace((string)provider?.MetaData["Key"]))
public AuthenticatorTokenProvider(IServiceProvider serviceProvider)
{
return false;
_serviceProvider = serviceProvider;
}
return await _serviceProvider.GetRequiredService<IUserService>()
.TwoFactorProviderIsEnabledAsync(TwoFactorProviderType.Authenticator, user);
}
public Task<string> GenerateAsync(string purpose, UserManager<User> manager, User user)
{
return Task.FromResult<string>(null);
}
public async Task<bool> CanGenerateTwoFactorTokenAsync(UserManager<User> manager, User user)
{
var provider = user.GetTwoFactorProvider(TwoFactorProviderType.Authenticator);
if (string.IsNullOrWhiteSpace((string)provider?.MetaData["Key"]))
{
return false;
}
return await _serviceProvider.GetRequiredService<IUserService>()
.TwoFactorProviderIsEnabledAsync(TwoFactorProviderType.Authenticator, user);
}
public Task<bool> ValidateAsync(string purpose, string token, UserManager<User> manager, User user)
{
var provider = user.GetTwoFactorProvider(TwoFactorProviderType.Authenticator);
var otp = new Totp(Base32Encoding.ToBytes((string)provider.MetaData["Key"]));
public Task<string> GenerateAsync(string purpose, UserManager<User> manager, User user)
{
return Task.FromResult<string>(null);
}
long timeStepMatched;
var valid = otp.VerifyTotp(token, out timeStepMatched, new VerificationWindow(1, 1));
public Task<bool> ValidateAsync(string purpose, string token, UserManager<User> manager, User user)
{
var provider = user.GetTwoFactorProvider(TwoFactorProviderType.Authenticator);
var otp = new Totp(Base32Encoding.ToBytes((string)provider.MetaData["Key"]));
return Task.FromResult(valid);
long timeStepMatched;
var valid = otp.VerifyTotp(token, out timeStepMatched, new VerificationWindow(1, 1));
return Task.FromResult(valid);
}
}
}

View File

@ -2,48 +2,49 @@
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection.Extensions;
namespace Microsoft.Extensions.DependencyInjection;
// ref: https://github.com/aspnet/Identity/blob/dev/src/Microsoft.AspNetCore.Identity/IdentityServiceCollectionExtensions.cs
public static class CustomIdentityServiceCollectionExtensions
namespace Microsoft.Extensions.DependencyInjection
{
public static IdentityBuilder AddIdentityWithoutCookieAuth<TUser, TRole>(
this IServiceCollection services)
where TUser : class
where TRole : class
// ref: https://github.com/aspnet/Identity/blob/dev/src/Microsoft.AspNetCore.Identity/IdentityServiceCollectionExtensions.cs
public static class CustomIdentityServiceCollectionExtensions
{
return services.AddIdentityWithoutCookieAuth<TUser, TRole>(setupAction: null);
}
public static IdentityBuilder AddIdentityWithoutCookieAuth<TUser, TRole>(
this IServiceCollection services,
Action<IdentityOptions> setupAction)
where TUser : class
where TRole : class
{
// Hosting doesn't add IHttpContextAccessor by default
services.AddHttpContextAccessor();
// Identity services
services.TryAddScoped<IUserValidator<TUser>, UserValidator<TUser>>();
services.TryAddScoped<IPasswordValidator<TUser>, PasswordValidator<TUser>>();
services.TryAddScoped<IPasswordHasher<TUser>, PasswordHasher<TUser>>();
services.TryAddScoped<ILookupNormalizer, LowerInvariantLookupNormalizer>();
services.TryAddScoped<IRoleValidator<TRole>, RoleValidator<TRole>>();
// No interface for the error describer so we can add errors without rev'ing the interface
services.TryAddScoped<IdentityErrorDescriber>();
services.TryAddScoped<ISecurityStampValidator, SecurityStampValidator<TUser>>();
services.TryAddScoped<ITwoFactorSecurityStampValidator, TwoFactorSecurityStampValidator<TUser>>();
services.TryAddScoped<IUserClaimsPrincipalFactory<TUser>, UserClaimsPrincipalFactory<TUser, TRole>>();
services.TryAddScoped<IUserConfirmation<TUser>, DefaultUserConfirmation<TUser>>();
services.TryAddScoped<UserManager<TUser>>();
services.TryAddScoped<SignInManager<TUser>>();
services.TryAddScoped<RoleManager<TRole>>();
if (setupAction != null)
public static IdentityBuilder AddIdentityWithoutCookieAuth<TUser, TRole>(
this IServiceCollection services)
where TUser : class
where TRole : class
{
services.Configure(setupAction);
return services.AddIdentityWithoutCookieAuth<TUser, TRole>(setupAction: null);
}
return new IdentityBuilder(typeof(TUser), typeof(TRole), services);
public static IdentityBuilder AddIdentityWithoutCookieAuth<TUser, TRole>(
this IServiceCollection services,
Action<IdentityOptions> setupAction)
where TUser : class
where TRole : class
{
// Hosting doesn't add IHttpContextAccessor by default
services.AddHttpContextAccessor();
// Identity services
services.TryAddScoped<IUserValidator<TUser>, UserValidator<TUser>>();
services.TryAddScoped<IPasswordValidator<TUser>, PasswordValidator<TUser>>();
services.TryAddScoped<IPasswordHasher<TUser>, PasswordHasher<TUser>>();
services.TryAddScoped<ILookupNormalizer, LowerInvariantLookupNormalizer>();
services.TryAddScoped<IRoleValidator<TRole>, RoleValidator<TRole>>();
// No interface for the error describer so we can add errors without rev'ing the interface
services.TryAddScoped<IdentityErrorDescriber>();
services.TryAddScoped<ISecurityStampValidator, SecurityStampValidator<TUser>>();
services.TryAddScoped<ITwoFactorSecurityStampValidator, TwoFactorSecurityStampValidator<TUser>>();
services.TryAddScoped<IUserClaimsPrincipalFactory<TUser>, UserClaimsPrincipalFactory<TUser, TRole>>();
services.TryAddScoped<IUserConfirmation<TUser>, DefaultUserConfirmation<TUser>>();
services.TryAddScoped<UserManager<TUser>>();
services.TryAddScoped<SignInManager<TUser>>();
services.TryAddScoped<RoleManager<TRole>>();
if (setupAction != null)
{
services.Configure(setupAction);
}
return new IdentityBuilder(typeof(TUser), typeof(TRole), services);
}
}
}

View File

@ -7,80 +7,81 @@ using Bit.Core.Utilities.Duo;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection;
namespace Bit.Core.Identity;
public class DuoWebTokenProvider : IUserTwoFactorTokenProvider<User>
namespace Bit.Core.Identity
{
private readonly IServiceProvider _serviceProvider;
private readonly GlobalSettings _globalSettings;
public DuoWebTokenProvider(
IServiceProvider serviceProvider,
GlobalSettings globalSettings)
public class DuoWebTokenProvider : IUserTwoFactorTokenProvider<User>
{
_serviceProvider = serviceProvider;
_globalSettings = globalSettings;
}
private readonly IServiceProvider _serviceProvider;
private readonly GlobalSettings _globalSettings;
public async Task<bool> CanGenerateTwoFactorTokenAsync(UserManager<User> manager, User user)
{
var userService = _serviceProvider.GetRequiredService<IUserService>();
if (!(await userService.CanAccessPremium(user)))
public DuoWebTokenProvider(
IServiceProvider serviceProvider,
GlobalSettings globalSettings)
{
return false;
_serviceProvider = serviceProvider;
_globalSettings = globalSettings;
}
var provider = user.GetTwoFactorProvider(TwoFactorProviderType.Duo);
if (!HasProperMetaData(provider))
public async Task<bool> CanGenerateTwoFactorTokenAsync(UserManager<User> manager, User user)
{
return false;
var userService = _serviceProvider.GetRequiredService<IUserService>();
if (!(await userService.CanAccessPremium(user)))
{
return false;
}
var provider = user.GetTwoFactorProvider(TwoFactorProviderType.Duo);
if (!HasProperMetaData(provider))
{
return false;
}
return await userService.TwoFactorProviderIsEnabledAsync(TwoFactorProviderType.Duo, user);
}
return await userService.TwoFactorProviderIsEnabledAsync(TwoFactorProviderType.Duo, user);
}
public async Task<string> GenerateAsync(string purpose, UserManager<User> manager, User user)
{
var userService = _serviceProvider.GetRequiredService<IUserService>();
if (!(await userService.CanAccessPremium(user)))
public async Task<string> GenerateAsync(string purpose, UserManager<User> manager, User user)
{
return null;
var userService = _serviceProvider.GetRequiredService<IUserService>();
if (!(await userService.CanAccessPremium(user)))
{
return null;
}
var provider = user.GetTwoFactorProvider(TwoFactorProviderType.Duo);
if (!HasProperMetaData(provider))
{
return null;
}
var signatureRequest = DuoWeb.SignRequest((string)provider.MetaData["IKey"],
(string)provider.MetaData["SKey"], _globalSettings.Duo.AKey, user.Email);
return signatureRequest;
}
var provider = user.GetTwoFactorProvider(TwoFactorProviderType.Duo);
if (!HasProperMetaData(provider))
public async Task<bool> ValidateAsync(string purpose, string token, UserManager<User> manager, User user)
{
return null;
var userService = _serviceProvider.GetRequiredService<IUserService>();
if (!(await userService.CanAccessPremium(user)))
{
return false;
}
var provider = user.GetTwoFactorProvider(TwoFactorProviderType.Duo);
if (!HasProperMetaData(provider))
{
return false;
}
var response = DuoWeb.VerifyResponse((string)provider.MetaData["IKey"], (string)provider.MetaData["SKey"],
_globalSettings.Duo.AKey, token);
return response == user.Email;
}
var signatureRequest = DuoWeb.SignRequest((string)provider.MetaData["IKey"],
(string)provider.MetaData["SKey"], _globalSettings.Duo.AKey, user.Email);
return signatureRequest;
}
public async Task<bool> ValidateAsync(string purpose, string token, UserManager<User> manager, User user)
{
var userService = _serviceProvider.GetRequiredService<IUserService>();
if (!(await userService.CanAccessPremium(user)))
private bool HasProperMetaData(TwoFactorProvider provider)
{
return false;
return provider?.MetaData != null && provider.MetaData.ContainsKey("IKey") &&
provider.MetaData.ContainsKey("SKey") && provider.MetaData.ContainsKey("Host");
}
var provider = user.GetTwoFactorProvider(TwoFactorProviderType.Duo);
if (!HasProperMetaData(provider))
{
return false;
}
var response = DuoWeb.VerifyResponse((string)provider.MetaData["IKey"], (string)provider.MetaData["SKey"],
_globalSettings.Duo.AKey, token);
return response == user.Email;
}
private bool HasProperMetaData(TwoFactorProvider provider)
{
return provider?.MetaData != null && provider.MetaData.ContainsKey("IKey") &&
provider.MetaData.ContainsKey("SKey") && provider.MetaData.ContainsKey("Host");
}
}

View File

@ -5,79 +5,80 @@ using Bit.Core.Services;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection;
namespace Bit.Core.Identity;
public class EmailTokenProvider : IUserTwoFactorTokenProvider<User>
namespace Bit.Core.Identity
{
private readonly IServiceProvider _serviceProvider;
public EmailTokenProvider(IServiceProvider serviceProvider)
public class EmailTokenProvider : IUserTwoFactorTokenProvider<User>
{
_serviceProvider = serviceProvider;
}
private readonly IServiceProvider _serviceProvider;
public async Task<bool> CanGenerateTwoFactorTokenAsync(UserManager<User> manager, User user)
{
var provider = user.GetTwoFactorProvider(TwoFactorProviderType.Email);
if (!HasProperMetaData(provider))
public EmailTokenProvider(IServiceProvider serviceProvider)
{
return false;
_serviceProvider = serviceProvider;
}
return await _serviceProvider.GetRequiredService<IUserService>().
TwoFactorProviderIsEnabledAsync(TwoFactorProviderType.Email, user);
}
public Task<string> GenerateAsync(string purpose, UserManager<User> manager, User user)
{
var provider = user.GetTwoFactorProvider(TwoFactorProviderType.Email);
if (!HasProperMetaData(provider))
public async Task<bool> CanGenerateTwoFactorTokenAsync(UserManager<User> manager, User user)
{
return null;
var provider = user.GetTwoFactorProvider(TwoFactorProviderType.Email);
if (!HasProperMetaData(provider))
{
return false;
}
return await _serviceProvider.GetRequiredService<IUserService>().
TwoFactorProviderIsEnabledAsync(TwoFactorProviderType.Email, user);
}
return Task.FromResult(RedactEmail((string)provider.MetaData["Email"]));
}
public Task<bool> ValidateAsync(string purpose, string token, UserManager<User> manager, User user)
{
return _serviceProvider.GetRequiredService<IUserService>().VerifyTwoFactorEmailAsync(user, token);
}
private bool HasProperMetaData(TwoFactorProvider provider)
{
return provider?.MetaData != null && provider.MetaData.ContainsKey("Email") &&
!string.IsNullOrWhiteSpace((string)provider.MetaData["Email"]);
}
private static string RedactEmail(string email)
{
var emailParts = email.Split('@');
string shownPart = null;
if (emailParts[0].Length > 2 && emailParts[0].Length <= 4)
public Task<string> GenerateAsync(string purpose, UserManager<User> manager, User user)
{
shownPart = emailParts[0].Substring(0, 1);
}
else if (emailParts[0].Length > 4)
{
shownPart = emailParts[0].Substring(0, 2);
}
else
{
shownPart = string.Empty;
var provider = user.GetTwoFactorProvider(TwoFactorProviderType.Email);
if (!HasProperMetaData(provider))
{
return null;
}
return Task.FromResult(RedactEmail((string)provider.MetaData["Email"]));
}
string redactedPart = null;
if (emailParts[0].Length > 4)
public Task<bool> ValidateAsync(string purpose, string token, UserManager<User> manager, User user)
{
redactedPart = new string('*', emailParts[0].Length - 2);
}
else
{
redactedPart = new string('*', emailParts[0].Length - shownPart.Length);
return _serviceProvider.GetRequiredService<IUserService>().VerifyTwoFactorEmailAsync(user, token);
}
return $"{shownPart}{redactedPart}@{emailParts[1]}";
private bool HasProperMetaData(TwoFactorProvider provider)
{
return provider?.MetaData != null && provider.MetaData.ContainsKey("Email") &&
!string.IsNullOrWhiteSpace((string)provider.MetaData["Email"]);
}
private static string RedactEmail(string email)
{
var emailParts = email.Split('@');
string shownPart = null;
if (emailParts[0].Length > 2 && emailParts[0].Length <= 4)
{
shownPart = emailParts[0].Substring(0, 1);
}
else if (emailParts[0].Length > 4)
{
shownPart = emailParts[0].Substring(0, 2);
}
else
{
shownPart = string.Empty;
}
string redactedPart = null;
if (emailParts[0].Length > 4)
{
redactedPart = new string('*', emailParts[0].Length - 2);
}
else
{
redactedPart = new string('*', emailParts[0].Length - shownPart.Length);
}
return $"{shownPart}{redactedPart}@{emailParts[1]}";
}
}
}

View File

@ -1,10 +1,11 @@
using Bit.Core.Entities;
namespace Bit.Core.Identity;
public interface IOrganizationTwoFactorTokenProvider
namespace Bit.Core.Identity
{
Task<bool> CanGenerateTwoFactorTokenAsync(Organization organization);
Task<string> GenerateAsync(Organization organization, User user);
Task<bool> ValidateAsync(string token, Organization organization, User user);
public interface IOrganizationTwoFactorTokenProvider
{
Task<bool> CanGenerateTwoFactorTokenAsync(Organization organization);
Task<string> GenerateAsync(Organization organization, User user);
Task<bool> ValidateAsync(string token, Organization organization, User user);
}
}

View File

@ -1,21 +1,22 @@
using Microsoft.AspNetCore.Identity;
namespace Bit.Core.Identity;
public class LowerInvariantLookupNormalizer : ILookupNormalizer
namespace Bit.Core.Identity
{
public string NormalizeEmail(string email)
public class LowerInvariantLookupNormalizer : ILookupNormalizer
{
return Normalize(email);
}
public string NormalizeEmail(string email)
{
return Normalize(email);
}
public string NormalizeName(string name)
{
return Normalize(name);
}
public string NormalizeName(string name)
{
return Normalize(name);
}
private string Normalize(string key)
{
return key?.Normalize().ToLowerInvariant();
private string Normalize(string key)
{
return key?.Normalize().ToLowerInvariant();
}
}
}

View File

@ -4,72 +4,73 @@ using Bit.Core.Models;
using Bit.Core.Settings;
using Bit.Core.Utilities.Duo;
namespace Bit.Core.Identity;
public interface IOrganizationDuoWebTokenProvider : IOrganizationTwoFactorTokenProvider { }
public class OrganizationDuoWebTokenProvider : IOrganizationDuoWebTokenProvider
namespace Bit.Core.Identity
{
private readonly GlobalSettings _globalSettings;
public interface IOrganizationDuoWebTokenProvider : IOrganizationTwoFactorTokenProvider { }
public OrganizationDuoWebTokenProvider(GlobalSettings globalSettings)
public class OrganizationDuoWebTokenProvider : IOrganizationDuoWebTokenProvider
{
_globalSettings = globalSettings;
}
private readonly GlobalSettings _globalSettings;
public Task<bool> CanGenerateTwoFactorTokenAsync(Organization organization)
{
if (organization == null || !organization.Enabled || !organization.Use2fa)
public OrganizationDuoWebTokenProvider(GlobalSettings globalSettings)
{
return Task.FromResult(false);
_globalSettings = globalSettings;
}
var provider = organization.GetTwoFactorProvider(TwoFactorProviderType.OrganizationDuo);
var canGenerate = organization.TwoFactorProviderIsEnabled(TwoFactorProviderType.OrganizationDuo)
&& HasProperMetaData(provider);
return Task.FromResult(canGenerate);
}
public Task<string> GenerateAsync(Organization organization, User user)
{
if (organization == null || !organization.Enabled || !organization.Use2fa)
public Task<bool> CanGenerateTwoFactorTokenAsync(Organization organization)
{
return Task.FromResult<string>(null);
if (organization == null || !organization.Enabled || !organization.Use2fa)
{
return Task.FromResult(false);
}
var provider = organization.GetTwoFactorProvider(TwoFactorProviderType.OrganizationDuo);
var canGenerate = organization.TwoFactorProviderIsEnabled(TwoFactorProviderType.OrganizationDuo)
&& HasProperMetaData(provider);
return Task.FromResult(canGenerate);
}
var provider = organization.GetTwoFactorProvider(TwoFactorProviderType.OrganizationDuo);
if (!HasProperMetaData(provider))
public Task<string> GenerateAsync(Organization organization, User user)
{
return Task.FromResult<string>(null);
if (organization == null || !organization.Enabled || !organization.Use2fa)
{
return Task.FromResult<string>(null);
}
var provider = organization.GetTwoFactorProvider(TwoFactorProviderType.OrganizationDuo);
if (!HasProperMetaData(provider))
{
return Task.FromResult<string>(null);
}
var signatureRequest = DuoWeb.SignRequest(provider.MetaData["IKey"].ToString(),
provider.MetaData["SKey"].ToString(), _globalSettings.Duo.AKey, user.Email);
return Task.FromResult(signatureRequest);
}
var signatureRequest = DuoWeb.SignRequest(provider.MetaData["IKey"].ToString(),
provider.MetaData["SKey"].ToString(), _globalSettings.Duo.AKey, user.Email);
return Task.FromResult(signatureRequest);
}
public Task<bool> ValidateAsync(string token, Organization organization, User user)
{
if (organization == null || !organization.Enabled || !organization.Use2fa)
public Task<bool> ValidateAsync(string token, Organization organization, User user)
{
return Task.FromResult(false);
if (organization == null || !organization.Enabled || !organization.Use2fa)
{
return Task.FromResult(false);
}
var provider = organization.GetTwoFactorProvider(TwoFactorProviderType.OrganizationDuo);
if (!HasProperMetaData(provider))
{
return Task.FromResult(false);
}
var response = DuoWeb.VerifyResponse(provider.MetaData["IKey"].ToString(),
provider.MetaData["SKey"].ToString(), _globalSettings.Duo.AKey, token);
return Task.FromResult(response == user.Email);
}
var provider = organization.GetTwoFactorProvider(TwoFactorProviderType.OrganizationDuo);
if (!HasProperMetaData(provider))
private bool HasProperMetaData(TwoFactorProvider provider)
{
return Task.FromResult(false);
return provider?.MetaData != null && provider.MetaData.ContainsKey("IKey") &&
provider.MetaData.ContainsKey("SKey") && provider.MetaData.ContainsKey("Host");
}
var response = DuoWeb.VerifyResponse(provider.MetaData["IKey"].ToString(),
provider.MetaData["SKey"].ToString(), _globalSettings.Duo.AKey, token);
return Task.FromResult(response == user.Email);
}
private bool HasProperMetaData(TwoFactorProvider provider)
{
return provider?.MetaData != null && provider.MetaData.ContainsKey("IKey") &&
provider.MetaData.ContainsKey("SKey") && provider.MetaData.ContainsKey("Host");
}
}

View File

@ -5,85 +5,86 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Bit.Core.Identity;
public class PasswordlessSignInManager<TUser> : SignInManager<TUser> where TUser : class
namespace Bit.Core.Identity
{
public const string PasswordlessSignInPurpose = "PasswordlessSignIn";
private readonly IMailService _mailService;
public PasswordlessSignInManager(UserManager<TUser> userManager,
IHttpContextAccessor contextAccessor,
IUserClaimsPrincipalFactory<TUser> claimsFactory,
IOptions<IdentityOptions> optionsAccessor,
ILogger<SignInManager<TUser>> logger,
IAuthenticationSchemeProvider schemes,
IUserConfirmation<TUser> confirmation,
IMailService mailService)
: base(userManager, contextAccessor, claimsFactory, optionsAccessor, logger, schemes, confirmation)
public class PasswordlessSignInManager<TUser> : SignInManager<TUser> where TUser : class
{
_mailService = mailService;
}
public const string PasswordlessSignInPurpose = "PasswordlessSignIn";
public async Task<SignInResult> PasswordlessSignInAsync(string email, string returnUrl)
{
var user = await UserManager.FindByEmailAsync(email);
if (user == null)
private readonly IMailService _mailService;
public PasswordlessSignInManager(UserManager<TUser> userManager,
IHttpContextAccessor contextAccessor,
IUserClaimsPrincipalFactory<TUser> claimsFactory,
IOptions<IdentityOptions> optionsAccessor,
ILogger<SignInManager<TUser>> logger,
IAuthenticationSchemeProvider schemes,
IUserConfirmation<TUser> confirmation,
IMailService mailService)
: base(userManager, contextAccessor, claimsFactory, optionsAccessor, logger, schemes, confirmation)
{
return SignInResult.Failed;
_mailService = mailService;
}
var token = await UserManager.GenerateUserTokenAsync(user, Options.Tokens.PasswordResetTokenProvider,
PasswordlessSignInPurpose);
await _mailService.SendPasswordlessSignInAsync(returnUrl, token, email);
return SignInResult.Success;
}
public async Task<SignInResult> PasswordlessSignInAsync(TUser user, string token, bool isPersistent)
{
if (user == null)
public async Task<SignInResult> PasswordlessSignInAsync(string email, string returnUrl)
{
throw new ArgumentNullException(nameof(user));
}
var user = await UserManager.FindByEmailAsync(email);
if (user == null)
{
return SignInResult.Failed;
}
var attempt = await CheckPasswordlessSignInAsync(user, token);
return attempt.Succeeded ?
await SignInOrTwoFactorAsync(user, isPersistent, bypassTwoFactor: true) : attempt;
}
public async Task<SignInResult> PasswordlessSignInAsync(string email, string token, bool isPersistent)
{
var user = await UserManager.FindByEmailAsync(email);
if (user == null)
{
return SignInResult.Failed;
}
return await PasswordlessSignInAsync(user, token, isPersistent);
}
public virtual async Task<SignInResult> CheckPasswordlessSignInAsync(TUser user, string token)
{
if (user == null)
{
throw new ArgumentNullException(nameof(user));
}
var error = await PreSignInCheck(user);
if (error != null)
{
return error;
}
if (await UserManager.VerifyUserTokenAsync(user, Options.Tokens.PasswordResetTokenProvider,
PasswordlessSignInPurpose, token))
{
var token = await UserManager.GenerateUserTokenAsync(user, Options.Tokens.PasswordResetTokenProvider,
PasswordlessSignInPurpose);
await _mailService.SendPasswordlessSignInAsync(returnUrl, token, email);
return SignInResult.Success;
}
Logger.LogWarning(2, "User {userId} failed to provide the correct token.",
await UserManager.GetUserIdAsync(user));
return SignInResult.Failed;
public async Task<SignInResult> PasswordlessSignInAsync(TUser user, string token, bool isPersistent)
{
if (user == null)
{
throw new ArgumentNullException(nameof(user));
}
var attempt = await CheckPasswordlessSignInAsync(user, token);
return attempt.Succeeded ?
await SignInOrTwoFactorAsync(user, isPersistent, bypassTwoFactor: true) : attempt;
}
public async Task<SignInResult> PasswordlessSignInAsync(string email, string token, bool isPersistent)
{
var user = await UserManager.FindByEmailAsync(email);
if (user == null)
{
return SignInResult.Failed;
}
return await PasswordlessSignInAsync(user, token, isPersistent);
}
public virtual async Task<SignInResult> CheckPasswordlessSignInAsync(TUser user, string token)
{
if (user == null)
{
throw new ArgumentNullException(nameof(user));
}
var error = await PreSignInCheck(user);
if (error != null)
{
return error;
}
if (await UserManager.VerifyUserTokenAsync(user, Options.Tokens.PasswordResetTokenProvider,
PasswordlessSignInPurpose, token))
{
return SignInResult.Success;
}
Logger.LogWarning(2, "User {userId} failed to provide the correct token.",
await UserManager.GetUserIdAsync(user));
return SignInResult.Failed;
}
}
}

View File

@ -2,37 +2,38 @@
using Bit.Core.Services;
using Microsoft.AspNetCore.Identity;
namespace Bit.Core.Identity;
public class ReadOnlyDatabaseIdentityUserStore : ReadOnlyIdentityUserStore
namespace Bit.Core.Identity
{
private readonly IUserService _userService;
private readonly IUserRepository _userRepository;
public ReadOnlyDatabaseIdentityUserStore(
IUserService userService,
IUserRepository userRepository)
public class ReadOnlyDatabaseIdentityUserStore : ReadOnlyIdentityUserStore
{
_userService = userService;
_userRepository = userRepository;
}
private readonly IUserService _userService;
private readonly IUserRepository _userRepository;
public override async Task<IdentityUser> FindByEmailAsync(string normalizedEmail,
CancellationToken cancellationToken = default(CancellationToken))
{
var user = await _userRepository.GetByEmailAsync(normalizedEmail);
return user?.ToIdentityUser(await _userService.TwoFactorIsEnabledAsync(user));
}
public override async Task<IdentityUser> FindByIdAsync(string userId,
CancellationToken cancellationToken = default(CancellationToken))
{
if (!Guid.TryParse(userId, out var userIdGuid))
public ReadOnlyDatabaseIdentityUserStore(
IUserService userService,
IUserRepository userRepository)
{
return null;
_userService = userService;
_userRepository = userRepository;
}
var user = await _userRepository.GetByIdAsync(userIdGuid);
return user?.ToIdentityUser(await _userService.TwoFactorIsEnabledAsync(user));
public override async Task<IdentityUser> FindByEmailAsync(string normalizedEmail,
CancellationToken cancellationToken = default(CancellationToken))
{
var user = await _userRepository.GetByEmailAsync(normalizedEmail);
return user?.ToIdentityUser(await _userService.TwoFactorIsEnabledAsync(user));
}
public override async Task<IdentityUser> FindByIdAsync(string userId,
CancellationToken cancellationToken = default(CancellationToken))
{
if (!Guid.TryParse(userId, out var userIdGuid))
{
return null;
}
var user = await _userRepository.GetByIdAsync(userIdGuid);
return user?.ToIdentityUser(await _userService.TwoFactorIsEnabledAsync(user));
}
}
}

View File

@ -2,65 +2,66 @@
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Configuration;
namespace Bit.Core.Identity;
public class ReadOnlyEnvIdentityUserStore : ReadOnlyIdentityUserStore
namespace Bit.Core.Identity
{
private readonly IConfiguration _configuration;
public ReadOnlyEnvIdentityUserStore(IConfiguration configuration)
public class ReadOnlyEnvIdentityUserStore : ReadOnlyIdentityUserStore
{
_configuration = configuration;
}
private readonly IConfiguration _configuration;
public override Task<IdentityUser> FindByEmailAsync(string normalizedEmail,
CancellationToken cancellationToken = default(CancellationToken))
{
var usersCsv = _configuration["adminSettings:admins"];
if (!CoreHelpers.SettingHasValue(usersCsv))
public ReadOnlyEnvIdentityUserStore(IConfiguration configuration)
{
return Task.FromResult<IdentityUser>(null);
_configuration = configuration;
}
var users = usersCsv.ToLowerInvariant().Split(',');
var usersDict = new Dictionary<string, string>();
foreach (var u in users)
public override Task<IdentityUser> FindByEmailAsync(string normalizedEmail,
CancellationToken cancellationToken = default(CancellationToken))
{
var parts = u.Split(':');
if (parts.Length == 2)
var usersCsv = _configuration["adminSettings:admins"];
if (!CoreHelpers.SettingHasValue(usersCsv))
{
var email = parts[0].Trim();
var stamp = parts[1].Trim();
usersDict.Add(email, stamp);
return Task.FromResult<IdentityUser>(null);
}
else
var users = usersCsv.ToLowerInvariant().Split(',');
var usersDict = new Dictionary<string, string>();
foreach (var u in users)
{
var email = parts[0].Trim();
usersDict.Add(email, email);
var parts = u.Split(':');
if (parts.Length == 2)
{
var email = parts[0].Trim();
var stamp = parts[1].Trim();
usersDict.Add(email, stamp);
}
else
{
var email = parts[0].Trim();
usersDict.Add(email, email);
}
}
var userStamp = usersDict.ContainsKey(normalizedEmail) ? usersDict[normalizedEmail] : null;
if (userStamp == null)
{
return Task.FromResult<IdentityUser>(null);
}
return Task.FromResult(new IdentityUser
{
Id = normalizedEmail,
Email = normalizedEmail,
NormalizedEmail = normalizedEmail,
EmailConfirmed = true,
UserName = normalizedEmail,
NormalizedUserName = normalizedEmail,
SecurityStamp = userStamp
});
}
var userStamp = usersDict.ContainsKey(normalizedEmail) ? usersDict[normalizedEmail] : null;
if (userStamp == null)
public override Task<IdentityUser> FindByIdAsync(string userId,
CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult<IdentityUser>(null);
return FindByEmailAsync(userId, cancellationToken);
}
return Task.FromResult(new IdentityUser
{
Id = normalizedEmail,
Email = normalizedEmail,
NormalizedEmail = normalizedEmail,
EmailConfirmed = true,
UserName = normalizedEmail,
NormalizedUserName = normalizedEmail,
SecurityStamp = userStamp
});
}
public override Task<IdentityUser> FindByIdAsync(string userId,
CancellationToken cancellationToken = default(CancellationToken))
{
return FindByEmailAsync(userId, cancellationToken);
}
}

View File

@ -1,119 +1,120 @@
using Microsoft.AspNetCore.Identity;
namespace Bit.Core.Identity;
public abstract class ReadOnlyIdentityUserStore :
IUserStore<IdentityUser>,
IUserEmailStore<IdentityUser>,
IUserSecurityStampStore<IdentityUser>
namespace Bit.Core.Identity
{
public void Dispose() { }
public Task<IdentityResult> CreateAsync(IdentityUser user,
CancellationToken cancellationToken = default(CancellationToken))
public abstract class ReadOnlyIdentityUserStore :
IUserStore<IdentityUser>,
IUserEmailStore<IdentityUser>,
IUserSecurityStampStore<IdentityUser>
{
throw new NotImplementedException();
}
public void Dispose() { }
public Task<IdentityResult> DeleteAsync(IdentityUser user,
CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
}
public Task<IdentityResult> CreateAsync(IdentityUser user,
CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
}
public abstract Task<IdentityUser> FindByEmailAsync(string normalizedEmail,
CancellationToken cancellationToken = default(CancellationToken));
public Task<IdentityResult> DeleteAsync(IdentityUser user,
CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
}
public abstract Task<IdentityUser> FindByIdAsync(string userId,
CancellationToken cancellationToken = default(CancellationToken));
public abstract Task<IdentityUser> FindByEmailAsync(string normalizedEmail,
CancellationToken cancellationToken = default(CancellationToken));
public async Task<IdentityUser> FindByNameAsync(string normalizedUserName,
CancellationToken cancellationToken = default(CancellationToken))
{
return await FindByEmailAsync(normalizedUserName, cancellationToken);
}
public abstract Task<IdentityUser> FindByIdAsync(string userId,
CancellationToken cancellationToken = default(CancellationToken));
public Task<string> GetEmailAsync(IdentityUser user,
CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(user.Email);
}
public async Task<IdentityUser> FindByNameAsync(string normalizedUserName,
CancellationToken cancellationToken = default(CancellationToken))
{
return await FindByEmailAsync(normalizedUserName, cancellationToken);
}
public Task<bool> GetEmailConfirmedAsync(IdentityUser user,
CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(user.EmailConfirmed);
}
public Task<string> GetEmailAsync(IdentityUser user,
CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(user.Email);
}
public Task<string> GetNormalizedEmailAsync(IdentityUser user,
CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(user.Email);
}
public Task<bool> GetEmailConfirmedAsync(IdentityUser user,
CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(user.EmailConfirmed);
}
public Task<string> GetNormalizedUserNameAsync(IdentityUser user,
CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(user.Email);
}
public Task<string> GetNormalizedEmailAsync(IdentityUser user,
CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(user.Email);
}
public Task<string> GetUserIdAsync(IdentityUser user,
CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(user.Id);
}
public Task<string> GetNormalizedUserNameAsync(IdentityUser user,
CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(user.Email);
}
public Task<string> GetUserNameAsync(IdentityUser user,
CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(user.Email);
}
public Task<string> GetUserIdAsync(IdentityUser user,
CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(user.Id);
}
public Task SetEmailAsync(IdentityUser user, string email,
CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
}
public Task<string> GetUserNameAsync(IdentityUser user,
CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(user.Email);
}
public Task SetEmailConfirmedAsync(IdentityUser user, bool confirmed,
CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
}
public Task SetEmailAsync(IdentityUser user, string email,
CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
}
public Task SetNormalizedEmailAsync(IdentityUser user, string normalizedEmail,
CancellationToken cancellationToken = default(CancellationToken))
{
user.NormalizedEmail = normalizedEmail;
return Task.FromResult(0);
}
public Task SetEmailConfirmedAsync(IdentityUser user, bool confirmed,
CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
}
public Task SetNormalizedUserNameAsync(IdentityUser user, string normalizedName,
CancellationToken cancellationToken = default(CancellationToken))
{
user.NormalizedUserName = normalizedName;
return Task.FromResult(0);
}
public Task SetNormalizedEmailAsync(IdentityUser user, string normalizedEmail,
CancellationToken cancellationToken = default(CancellationToken))
{
user.NormalizedEmail = normalizedEmail;
return Task.FromResult(0);
}
public Task SetUserNameAsync(IdentityUser user, string userName,
CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
}
public Task SetNormalizedUserNameAsync(IdentityUser user, string normalizedName,
CancellationToken cancellationToken = default(CancellationToken))
{
user.NormalizedUserName = normalizedName;
return Task.FromResult(0);
}
public Task<IdentityResult> UpdateAsync(IdentityUser user,
CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(IdentityResult.Success);
}
public Task SetUserNameAsync(IdentityUser user, string userName,
CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
}
public Task SetSecurityStampAsync(IdentityUser user, string stamp, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<IdentityResult> UpdateAsync(IdentityUser user,
CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(IdentityResult.Success);
}
public Task<string> GetSecurityStampAsync(IdentityUser user, CancellationToken cancellationToken)
{
return Task.FromResult(user.SecurityStamp);
public Task SetSecurityStampAsync(IdentityUser user, string stamp, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<string> GetSecurityStampAsync(IdentityUser user, CancellationToken cancellationToken)
{
return Task.FromResult(user.SecurityStamp);
}
}
}

Some files were not shown because too many files have changed in this diff Show More