mirror of
https://github.com/bitwarden/server.git
synced 2024-11-21 12:05:42 +01:00
[PM-2943] Enable Nullable Repositories in Unowned Files (#4549)
* Enable Nullable In Unowned Repos * Update More Tests * Move to One If * Fix Collections * Format * Add Migrations * Move Pragma Annotation * Add Better Assert Message
This commit is contained in:
parent
b5f09c599b
commit
1e0182008b
@ -7,8 +7,8 @@ namespace Bit.Core.Models.Data;
|
||||
/// </summary>
|
||||
public class CollectionAdminDetails : CollectionDetails
|
||||
{
|
||||
public IEnumerable<CollectionAccessSelection>? Groups { get; set; } = new List<CollectionAccessSelection>();
|
||||
public IEnumerable<CollectionAccessSelection>? Users { get; set; } = new List<CollectionAccessSelection>();
|
||||
public IEnumerable<CollectionAccessSelection> Groups { get; set; } = [];
|
||||
public IEnumerable<CollectionAccessSelection> Users { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Flag for whether the user has been explicitly assigned to the collection either directly or through a group.
|
||||
|
@ -156,4 +156,3 @@ public static class OrganizationServiceCollectionExtensions
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
using Bit.Core.Entities;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Core.Repositories;
|
||||
|
||||
public interface ICollectionCipherRepository
|
||||
|
@ -1,6 +1,8 @@
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Models.Data;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Core.Repositories;
|
||||
|
||||
public interface ICollectionRepository : IRepository<Collection, Guid>
|
||||
@ -10,7 +12,7 @@ public interface ICollectionRepository : IRepository<Collection, Guid>
|
||||
/// <summary>
|
||||
/// Returns a collection and fetches group/user associations for the collection.
|
||||
/// </summary>
|
||||
Task<Tuple<Collection, CollectionAccessDetails>> GetByIdWithAccessAsync(Guid id);
|
||||
Task<Tuple<Collection?, CollectionAccessDetails>> GetByIdWithAccessAsync(Guid id);
|
||||
|
||||
/// <summary>
|
||||
/// Return all collections that belong to the organization. Does not include any permission details or group/user
|
||||
@ -43,7 +45,7 @@ public interface ICollectionRepository : IRepository<Collection, Guid>
|
||||
/// This does not perform any authorization checks internally!
|
||||
/// Optionally, you can include access relationships for other Groups/Users and the collection.
|
||||
/// </summary>
|
||||
Task<CollectionAdminDetails> GetByIdWithPermissionsAsync(Guid collectionId, Guid? userId, bool includeAccessRelationships);
|
||||
Task<CollectionAdminDetails?> GetByIdWithPermissionsAsync(Guid collectionId, Guid? userId, bool includeAccessRelationships);
|
||||
|
||||
Task CreateAsync(Collection obj, IEnumerable<CollectionAccessSelection> groups, IEnumerable<CollectionAccessSelection> users);
|
||||
Task ReplaceAsync(Collection obj, IEnumerable<CollectionAccessSelection> groups, IEnumerable<CollectionAccessSelection> users);
|
||||
|
@ -1,12 +1,14 @@
|
||||
using Bit.Core.Entities;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Core.Repositories;
|
||||
|
||||
public interface IDeviceRepository : IRepository<Device, Guid>
|
||||
{
|
||||
Task<Device> GetByIdAsync(Guid id, Guid userId);
|
||||
Task<Device> GetByIdentifierAsync(string identifier);
|
||||
Task<Device> GetByIdentifierAsync(string identifier, Guid userId);
|
||||
Task<Device?> GetByIdAsync(Guid id, Guid userId);
|
||||
Task<Device?> GetByIdentifierAsync(string identifier);
|
||||
Task<Device?> GetByIdentifierAsync(string identifier, Guid userId);
|
||||
Task<ICollection<Device>> GetManyByUserIdAsync(Guid userId);
|
||||
Task ClearPushTokenAsync(Guid id);
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Vault.Entities;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Core.Repositories;
|
||||
|
||||
public interface IEventRepository
|
||||
|
@ -1,5 +1,7 @@
|
||||
using Bit.Core.Models.Data;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Core.Repositories;
|
||||
|
||||
public interface IInstallationDeviceRepository
|
||||
|
@ -1,5 +1,7 @@
|
||||
using Bit.Core.Entities;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Core.Repositories;
|
||||
|
||||
public interface IInstallationRepository : IRepository<Installation, Guid>
|
||||
|
@ -1,5 +1,7 @@
|
||||
namespace Bit.Core.Repositories;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public interface IMaintenanceRepository
|
||||
{
|
||||
Task UpdateStatisticsAsync();
|
||||
|
@ -1,6 +1,8 @@
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Core.Repositories;
|
||||
|
||||
public interface IOrganizationApiKeyRepository : IRepository<OrganizationApiKey, Guid>
|
||||
|
@ -1,11 +1,13 @@
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Core.Repositories;
|
||||
|
||||
public interface IOrganizationConnectionRepository : IRepository<OrganizationConnection, Guid>
|
||||
{
|
||||
Task<OrganizationConnection> GetByIdOrganizationIdAsync(Guid id, Guid organizationId);
|
||||
Task<OrganizationConnection?> GetByIdOrganizationIdAsync(Guid id, Guid organizationId);
|
||||
Task<ICollection<OrganizationConnection>> GetByOrganizationIdTypeAsync(Guid organizationId, OrganizationConnectionType type);
|
||||
Task<ICollection<OrganizationConnection>> GetEnabledByOrganizationIdTypeAsync(Guid organizationId, OrganizationConnectionType type);
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Models.Data.Organizations;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Core.Repositories;
|
||||
|
||||
public interface IOrganizationDomainRepository : IRepository<OrganizationDomain, Guid>
|
||||
@ -8,9 +10,9 @@ public interface IOrganizationDomainRepository : IRepository<OrganizationDomain,
|
||||
Task<ICollection<OrganizationDomain>> GetClaimedDomainsByDomainNameAsync(string domainName);
|
||||
Task<ICollection<OrganizationDomain>> GetDomainsByOrganizationIdAsync(Guid orgId);
|
||||
Task<ICollection<OrganizationDomain>> GetManyByNextRunDateAsync(DateTime date);
|
||||
Task<OrganizationDomainSsoDetailsData> GetOrganizationDomainSsoDetailsAsync(string email);
|
||||
Task<OrganizationDomain> GetDomainByIdOrganizationIdAsync(Guid id, Guid organizationId);
|
||||
Task<OrganizationDomain> GetDomainByOrgIdAndDomainNameAsync(Guid orgId, string domainName);
|
||||
Task<OrganizationDomainSsoDetailsData?> GetOrganizationDomainSsoDetailsAsync(string email);
|
||||
Task<OrganizationDomain?> GetDomainByIdOrganizationIdAsync(Guid id, Guid organizationId);
|
||||
Task<OrganizationDomain?> GetDomainByOrgIdAndDomainNameAsync(Guid orgId, string domainName);
|
||||
Task<ICollection<OrganizationDomain>> GetExpiredOrganizationDomainsAsync();
|
||||
Task<bool> DeleteExpiredAsync(int expirationPeriod);
|
||||
}
|
||||
|
@ -1,15 +1,17 @@
|
||||
using Bit.Core.Entities;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Core.Repositories;
|
||||
|
||||
public interface IOrganizationSponsorshipRepository : IRepository<OrganizationSponsorship, Guid>
|
||||
{
|
||||
Task<ICollection<Guid>> CreateManyAsync(IEnumerable<OrganizationSponsorship> organizationSponsorships);
|
||||
Task<ICollection<Guid>?> CreateManyAsync(IEnumerable<OrganizationSponsorship> organizationSponsorships);
|
||||
Task ReplaceManyAsync(IEnumerable<OrganizationSponsorship> organizationSponsorships);
|
||||
Task UpsertManyAsync(IEnumerable<OrganizationSponsorship> organizationSponsorships);
|
||||
Task DeleteManyAsync(IEnumerable<Guid> organizationSponsorshipIds);
|
||||
Task<ICollection<OrganizationSponsorship>> GetManyBySponsoringOrganizationAsync(Guid sponsoringOrganizationId);
|
||||
Task<OrganizationSponsorship> GetBySponsoringOrganizationUserIdAsync(Guid sponsoringOrganizationUserId);
|
||||
Task<OrganizationSponsorship> GetBySponsoredOrganizationIdAsync(Guid sponsoredOrganizationId);
|
||||
Task<OrganizationSponsorship?> GetBySponsoringOrganizationUserIdAsync(Guid sponsoringOrganizationUserId);
|
||||
Task<OrganizationSponsorship?> GetBySponsoredOrganizationIdAsync(Guid sponsoredOrganizationId);
|
||||
Task<DateTime?> GetLatestSyncDateBySponsoringOrganizationIdAsync(Guid sponsoringOrganizationId);
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
using Bit.Core.Entities;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Core.Repositories;
|
||||
|
||||
public interface IRepository<T, TId> where TId : IEquatable<TId> where T : class, ITableObject<TId>
|
||||
{
|
||||
Task<T> GetByIdAsync(TId id);
|
||||
Task<T?> GetByIdAsync(TId id);
|
||||
Task<T> CreateAsync(T obj);
|
||||
Task ReplaceAsync(T obj);
|
||||
Task UpsertAsync(T obj);
|
||||
|
@ -1,5 +1,7 @@
|
||||
using Bit.Core.Entities;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Core.Repositories;
|
||||
|
||||
public interface ITaxRateRepository : IRepository<TaxRate, string>
|
||||
|
@ -1,6 +1,8 @@
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Core.Repositories;
|
||||
|
||||
public interface ITransactionRepository : IRepository<Transaction, Guid>
|
||||
@ -8,5 +10,5 @@ public interface ITransactionRepository : IRepository<Transaction, Guid>
|
||||
Task<ICollection<Transaction>> GetManyByUserIdAsync(Guid userId, int? limit = null);
|
||||
Task<ICollection<Transaction>> GetManyByOrganizationIdAsync(Guid organizationId, int? limit = null);
|
||||
Task<ICollection<Transaction>> GetManyByProviderIdAsync(Guid providerId, int? limit = null);
|
||||
Task<Transaction> GetByGatewayIdAsync(GatewayType gatewayType, string gatewayId);
|
||||
Task<Transaction?> GetByGatewayIdAsync(GatewayType gatewayType, string gatewayId);
|
||||
}
|
||||
|
@ -2,17 +2,19 @@
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Models.Data;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Core.Repositories;
|
||||
|
||||
public interface IUserRepository : IRepository<User, Guid>
|
||||
{
|
||||
Task<User> GetByEmailAsync(string email);
|
||||
Task<User?> GetByEmailAsync(string email);
|
||||
Task<IEnumerable<User>> GetManyByEmailsAsync(IEnumerable<string> emails);
|
||||
Task<User> GetBySsoUserAsync(string externalId, Guid? organizationId);
|
||||
Task<UserKdfInformation> GetKdfInformationByEmailAsync(string email);
|
||||
Task<User?> GetBySsoUserAsync(string externalId, Guid? organizationId);
|
||||
Task<UserKdfInformation?> GetKdfInformationByEmailAsync(string email);
|
||||
Task<ICollection<User>> SearchAsync(string email, int skip, int take);
|
||||
Task<ICollection<User>> GetManyByPremiumAsync(bool premium);
|
||||
Task<string> GetPublicKeyAsync(Guid id);
|
||||
Task<string?> GetPublicKeyAsync(Guid id);
|
||||
Task<DateTime> GetAccountRevisionDateAsync(Guid id);
|
||||
Task UpdateStorageAsync(Guid id);
|
||||
Task UpdateRenewalReminderDateAsync(Guid id, DateTime renewalReminderDate);
|
||||
|
@ -1,5 +1,7 @@
|
||||
using Bit.Core.Models.Data;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Core.Repositories.Noop;
|
||||
|
||||
public class InstallationDeviceRepository : IInstallationDeviceRepository
|
||||
|
@ -4,6 +4,8 @@ using Bit.Core.Settings;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Core.Vault.Entities;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Core.Repositories.TableStorage;
|
||||
|
||||
public class EventRepository : IEventRepository
|
||||
@ -78,9 +80,9 @@ public class EventRepository : IEventRepository
|
||||
await CreateEventAsync(entity);
|
||||
}
|
||||
|
||||
public async Task CreateManyAsync(IEnumerable<IEvent> e)
|
||||
public async Task CreateManyAsync(IEnumerable<IEvent>? e)
|
||||
{
|
||||
if (!e?.Any() ?? true)
|
||||
if (e is null || !e.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -91,7 +93,7 @@ public class EventRepository : IEventRepository
|
||||
return;
|
||||
}
|
||||
|
||||
var entities = e.Where(ev => ev is EventTableEntity).Select(ev => ev as EventTableEntity);
|
||||
var entities = e.OfType<EventTableEntity>();
|
||||
var entityGroups = entities.GroupBy(ent => ent.PartitionKey);
|
||||
foreach (var group in entityGroups)
|
||||
{
|
||||
@ -134,7 +136,7 @@ public class EventRepository : IEventRepository
|
||||
var result = new PagedResult<IEvent>();
|
||||
var query = _tableClient.QueryAsync<AzureEvent>(filter, pageOptions.PageSize);
|
||||
|
||||
await using (var enumerator = query.AsPages(pageOptions?.ContinuationToken,
|
||||
await using (var enumerator = query.AsPages(pageOptions.ContinuationToken,
|
||||
pageOptions.PageSize).GetAsyncEnumerator())
|
||||
{
|
||||
await enumerator.MoveNextAsync();
|
||||
|
@ -2,6 +2,8 @@
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Settings;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Core.Repositories.TableStorage;
|
||||
|
||||
public class InstallationDeviceRepository : IInstallationDeviceRepository
|
||||
@ -23,9 +25,9 @@ public class InstallationDeviceRepository : IInstallationDeviceRepository
|
||||
await _tableClient.UpsertEntityAsync(entity);
|
||||
}
|
||||
|
||||
public async Task UpsertManyAsync(IList<InstallationDeviceEntity> entities)
|
||||
public async Task UpsertManyAsync(IList<InstallationDeviceEntity>? entities)
|
||||
{
|
||||
if (!entities?.Any() ?? true)
|
||||
if (entities is null || !entities.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ using Bit.Core.Entities;
|
||||
using Bit.Core.Models.Data;
|
||||
using Dapper;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.Dapper;
|
||||
|
||||
public static class DapperHelpers
|
||||
@ -64,7 +66,7 @@ public static class DapperHelpers
|
||||
var table = new DataTable();
|
||||
table.SetTypeName("[dbo].[OrganizationSponsorshipType]");
|
||||
|
||||
var columnData = new List<(string name, Type type, Func<OrganizationSponsorship, object> getter)>
|
||||
var columnData = new List<(string name, Type type, Func<OrganizationSponsorship, object?> getter)>
|
||||
{
|
||||
(nameof(OrganizationSponsorship.Id), typeof(Guid), ou => ou.Id),
|
||||
(nameof(OrganizationSponsorship.SponsoringOrganizationId), typeof(Guid), ou => ou.SponsoringOrganizationId),
|
||||
@ -82,7 +84,7 @@ public static class DapperHelpers
|
||||
}
|
||||
|
||||
public static DataTable BuildTable<T>(this IEnumerable<T> entities, DataTable table,
|
||||
List<(string name, Type type, Func<T, object> getter)> columnData)
|
||||
List<(string name, Type type, Func<T, object?> getter)> columnData)
|
||||
{
|
||||
foreach (var (name, type, getter) in columnData)
|
||||
{
|
||||
|
@ -1,5 +1,7 @@
|
||||
using Dapper;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.Dapper.Repositories;
|
||||
|
||||
public abstract class BaseRepository
|
||||
|
@ -5,6 +5,8 @@ using Bit.Core.Settings;
|
||||
using Dapper;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.Dapper.Repositories;
|
||||
|
||||
public class CollectionCipherRepository : BaseRepository, ICollectionCipherRepository
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Data;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Models.Data;
|
||||
@ -7,6 +8,8 @@ using Bit.Core.Settings;
|
||||
using Dapper;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.Dapper.Repositories;
|
||||
|
||||
public class CollectionRepository : Repository<Collection, Guid>, ICollectionRepository
|
||||
@ -32,7 +35,7 @@ public class CollectionRepository : Repository<Collection, Guid>, ICollectionRep
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Tuple<Collection, CollectionAccessDetails>> GetByIdWithAccessAsync(Guid id)
|
||||
public async Task<Tuple<Collection?, CollectionAccessDetails>> GetByIdWithAccessAsync(Guid id)
|
||||
{
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
@ -46,7 +49,7 @@ public class CollectionRepository : Repository<Collection, Guid>, ICollectionRep
|
||||
var users = (await results.ReadAsync<CollectionAccessSelection>()).ToList();
|
||||
var access = new CollectionAccessDetails { Groups = groups, Users = users };
|
||||
|
||||
return new Tuple<Collection, CollectionAccessDetails>(collection, access);
|
||||
return new Tuple<Collection?, CollectionAccessDetails>(collection, access);
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,7 +185,7 @@ public class CollectionRepository : Repository<Collection, Guid>, ICollectionRep
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<CollectionAdminDetails> GetByIdWithPermissionsAsync(Guid collectionId, Guid? userId, bool includeAccessRelationships)
|
||||
public async Task<CollectionAdminDetails?> GetByIdWithPermissionsAsync(Guid collectionId, Guid? userId, bool includeAccessRelationships)
|
||||
{
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
@ -195,17 +198,18 @@ public class CollectionRepository : Repository<Collection, Guid>, ICollectionRep
|
||||
|
||||
if (!includeAccessRelationships || collectionDetails == null) return collectionDetails;
|
||||
|
||||
collectionDetails.Groups = (await results.ReadAsync<CollectionAccessSelection>()).ToList();
|
||||
// TODO-NRE: collectionDetails should be checked for null and probably return early
|
||||
collectionDetails!.Groups = (await results.ReadAsync<CollectionAccessSelection>()).ToList();
|
||||
collectionDetails.Users = (await results.ReadAsync<CollectionAccessSelection>()).ToList();
|
||||
|
||||
return collectionDetails;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task CreateAsync(Collection obj, IEnumerable<CollectionAccessSelection> groups, IEnumerable<CollectionAccessSelection> users)
|
||||
public async Task CreateAsync(Collection obj, IEnumerable<CollectionAccessSelection>? groups, IEnumerable<CollectionAccessSelection>? users)
|
||||
{
|
||||
obj.SetNewId();
|
||||
var objWithGroupsAndUsers = JsonSerializer.Deserialize<CollectionWithGroupsAndUsers>(JsonSerializer.Serialize(obj));
|
||||
var objWithGroupsAndUsers = JsonSerializer.Deserialize<CollectionWithGroupsAndUsers>(JsonSerializer.Serialize(obj))!;
|
||||
|
||||
objWithGroupsAndUsers.Groups = groups != null ? groups.ToArrayTVP() : Enumerable.Empty<CollectionAccessSelection>().ToArrayTVP();
|
||||
objWithGroupsAndUsers.Users = users != null ? users.ToArrayTVP() : Enumerable.Empty<CollectionAccessSelection>().ToArrayTVP();
|
||||
@ -219,9 +223,9 @@ public class CollectionRepository : Repository<Collection, Guid>, ICollectionRep
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ReplaceAsync(Collection obj, IEnumerable<CollectionAccessSelection> groups, IEnumerable<CollectionAccessSelection> users)
|
||||
public async Task ReplaceAsync(Collection obj, IEnumerable<CollectionAccessSelection>? groups, IEnumerable<CollectionAccessSelection>? users)
|
||||
{
|
||||
var objWithGroupsAndUsers = JsonSerializer.Deserialize<CollectionWithGroupsAndUsers>(JsonSerializer.Serialize(obj));
|
||||
var objWithGroupsAndUsers = JsonSerializer.Deserialize<CollectionWithGroupsAndUsers>(JsonSerializer.Serialize(obj))!;
|
||||
|
||||
objWithGroupsAndUsers.Groups = groups != null ? groups.ToArrayTVP() : Enumerable.Empty<CollectionAccessSelection>().ToArrayTVP();
|
||||
objWithGroupsAndUsers.Users = users != null ? users.ToArrayTVP() : Enumerable.Empty<CollectionAccessSelection>().ToArrayTVP();
|
||||
@ -307,7 +311,9 @@ public class CollectionRepository : Repository<Collection, Guid>, ICollectionRep
|
||||
|
||||
public class CollectionWithGroupsAndUsers : Collection
|
||||
{
|
||||
public DataTable Groups { get; set; }
|
||||
public DataTable Users { get; set; }
|
||||
[DisallowNull]
|
||||
public DataTable? Groups { get; set; }
|
||||
[DisallowNull]
|
||||
public DataTable? Users { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
using System.Data;
|
||||
using Dapper;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.Dapper.Repositories;
|
||||
|
||||
public class DateTimeHandler : SqlMapper.TypeHandler<DateTime>
|
||||
|
@ -5,6 +5,8 @@ using Bit.Core.Settings;
|
||||
using Dapper;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.Dapper.Repositories;
|
||||
|
||||
public class DeviceRepository : Repository<Device, Guid>, IDeviceRepository
|
||||
@ -17,7 +19,7 @@ public class DeviceRepository : Repository<Device, Guid>, IDeviceRepository
|
||||
: base(connectionString, readOnlyConnectionString)
|
||||
{ }
|
||||
|
||||
public async Task<Device> GetByIdAsync(Guid id, Guid userId)
|
||||
public async Task<Device?> GetByIdAsync(Guid id, Guid userId)
|
||||
{
|
||||
var device = await GetByIdAsync(id);
|
||||
if (device == null || device.UserId != userId)
|
||||
@ -28,7 +30,7 @@ public class DeviceRepository : Repository<Device, Guid>, IDeviceRepository
|
||||
return device;
|
||||
}
|
||||
|
||||
public async Task<Device> GetByIdentifierAsync(string identifier)
|
||||
public async Task<Device?> GetByIdentifierAsync(string identifier)
|
||||
{
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
@ -44,7 +46,7 @@ public class DeviceRepository : Repository<Device, Guid>, IDeviceRepository
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Device> GetByIdentifierAsync(string identifier, Guid userId)
|
||||
public async Task<Device?> GetByIdentifierAsync(string identifier, Guid userId)
|
||||
{
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
|
@ -7,6 +7,8 @@ using Bit.Core.Vault.Entities;
|
||||
using Dapper;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.Dapper.Repositories;
|
||||
|
||||
public class EventRepository : Repository<Event, Guid>, IEventRepository
|
||||
@ -23,7 +25,7 @@ public class EventRepository : Repository<Event, Guid>, IEventRepository
|
||||
PageOptions pageOptions)
|
||||
{
|
||||
return await GetManyAsync($"[{Schema}].[Event_ReadPageByUserId]",
|
||||
new Dictionary<string, object>
|
||||
new Dictionary<string, object?>
|
||||
{
|
||||
["@UserId"] = userId
|
||||
}, startDate, endDate, pageOptions);
|
||||
@ -33,7 +35,7 @@ public class EventRepository : Repository<Event, Guid>, IEventRepository
|
||||
DateTime startDate, DateTime endDate, PageOptions pageOptions)
|
||||
{
|
||||
return await GetManyAsync($"[{Schema}].[Event_ReadPageByOrganizationId]",
|
||||
new Dictionary<string, object>
|
||||
new Dictionary<string, object?>
|
||||
{
|
||||
["@OrganizationId"] = organizationId
|
||||
}, startDate, endDate, pageOptions);
|
||||
@ -43,7 +45,7 @@ public class EventRepository : Repository<Event, Guid>, IEventRepository
|
||||
DateTime startDate, DateTime endDate, PageOptions pageOptions)
|
||||
{
|
||||
return await GetManyAsync($"[{Schema}].[Event_ReadPageByOrganizationIdActingUserId]",
|
||||
new Dictionary<string, object>
|
||||
new Dictionary<string, object?>
|
||||
{
|
||||
["@OrganizationId"] = organizationId,
|
||||
["@ActingUserId"] = actingUserId
|
||||
@ -54,7 +56,7 @@ public class EventRepository : Repository<Event, Guid>, IEventRepository
|
||||
DateTime startDate, DateTime endDate, PageOptions pageOptions)
|
||||
{
|
||||
return await GetManyAsync($"[{Schema}].[Event_ReadPageByProviderId]",
|
||||
new Dictionary<string, object>
|
||||
new Dictionary<string, object?>
|
||||
{
|
||||
["@ProviderId"] = providerId
|
||||
}, startDate, endDate, pageOptions);
|
||||
@ -64,7 +66,7 @@ public class EventRepository : Repository<Event, Guid>, IEventRepository
|
||||
DateTime startDate, DateTime endDate, PageOptions pageOptions)
|
||||
{
|
||||
return await GetManyAsync($"[{Schema}].[Event_ReadPageByProviderIdActingUserId]",
|
||||
new Dictionary<string, object>
|
||||
new Dictionary<string, object?>
|
||||
{
|
||||
["@ProviderId"] = providerId,
|
||||
["@ActingUserId"] = actingUserId
|
||||
@ -75,7 +77,7 @@ public class EventRepository : Repository<Event, Guid>, IEventRepository
|
||||
PageOptions pageOptions)
|
||||
{
|
||||
return await GetManyAsync($"[{Schema}].[Event_ReadPageByCipherId]",
|
||||
new Dictionary<string, object>
|
||||
new Dictionary<string, object?>
|
||||
{
|
||||
["@OrganizationId"] = cipher.OrganizationId,
|
||||
["@UserId"] = cipher.UserId,
|
||||
@ -93,9 +95,9 @@ public class EventRepository : Repository<Event, Guid>, IEventRepository
|
||||
await base.CreateAsync(ev);
|
||||
}
|
||||
|
||||
public async Task CreateManyAsync(IEnumerable<IEvent> entities)
|
||||
public async Task CreateManyAsync(IEnumerable<IEvent>? entities)
|
||||
{
|
||||
if (!entities?.Any() ?? true)
|
||||
if (entities is null || !entities.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -112,7 +114,7 @@ public class EventRepository : Repository<Event, Guid>, IEventRepository
|
||||
using (var bulkCopy = new SqlBulkCopy(connection, SqlBulkCopyOptions.KeepIdentity, null))
|
||||
{
|
||||
bulkCopy.DestinationTableName = "[dbo].[Event]";
|
||||
var dataTable = BuildEventsTable(bulkCopy, entities.Select(e => e is Event ? e as Event : new Event(e)));
|
||||
var dataTable = BuildEventsTable(bulkCopy, entities.Select(e => e is Event @event ? @event : new Event(e)));
|
||||
await bulkCopy.WriteToServerAsync(dataTable);
|
||||
}
|
||||
}
|
||||
@ -123,7 +125,7 @@ public class EventRepository : Repository<Event, Guid>, IEventRepository
|
||||
PageOptions pageOptions)
|
||||
{
|
||||
return await GetManyAsync($"[{Schema}].[Event_ReadPageByOrganizationIdServiceAccountId]",
|
||||
new Dictionary<string, object>
|
||||
new Dictionary<string, object?>
|
||||
{
|
||||
["@OrganizationId"] = organizationId,
|
||||
["@ServiceAccountId"] = serviceAccountId
|
||||
@ -131,7 +133,7 @@ public class EventRepository : Repository<Event, Guid>, IEventRepository
|
||||
}
|
||||
|
||||
private async Task<PagedResult<IEvent>> GetManyAsync(string sprocName,
|
||||
IDictionary<string, object> sprocParams, DateTime startDate, DateTime endDate, PageOptions pageOptions)
|
||||
IDictionary<string, object?> sprocParams, DateTime startDate, DateTime endDate, PageOptions pageOptions)
|
||||
{
|
||||
DateTime? beforeDate = null;
|
||||
if (!string.IsNullOrWhiteSpace(pageOptions.ContinuationToken) &&
|
||||
|
@ -2,6 +2,8 @@
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Settings;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.Dapper.Repositories;
|
||||
|
||||
public class InstallationRepository : Repository<Installation, Guid>, IInstallationRepository
|
||||
|
@ -4,6 +4,8 @@ using Bit.Core.Settings;
|
||||
using Dapper;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.Dapper.Repositories;
|
||||
|
||||
public class MaintenanceRepository : BaseRepository, IMaintenanceRepository
|
||||
|
@ -6,6 +6,8 @@ using Bit.Core.Settings;
|
||||
using Dapper;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.Dapper.Repositories;
|
||||
|
||||
public class OrganizationApiKeyRepository : Repository<OrganizationApiKey, Guid>, IOrganizationApiKeyRepository
|
||||
|
@ -6,6 +6,8 @@ using Bit.Core.Settings;
|
||||
using Dapper;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.Dapper.Repositories;
|
||||
|
||||
public class OrganizationConnectionRepository : Repository<OrganizationConnection, Guid>, IOrganizationConnectionRepository
|
||||
@ -14,7 +16,7 @@ public class OrganizationConnectionRepository : Repository<OrganizationConnectio
|
||||
: base(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString)
|
||||
{ }
|
||||
|
||||
public async Task<OrganizationConnection> GetByIdOrganizationIdAsync(Guid id, Guid organizationId)
|
||||
public async Task<OrganizationConnection?> GetByIdOrganizationIdAsync(Guid id, Guid organizationId)
|
||||
{
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
|
@ -6,6 +6,8 @@ using Bit.Core.Settings;
|
||||
using Dapper;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.Dapper.Repositories;
|
||||
|
||||
public class OrganizationDomainRepository : Repository<OrganizationDomain, Guid>, IOrganizationDomainRepository
|
||||
@ -55,7 +57,7 @@ public class OrganizationDomainRepository : Repository<OrganizationDomain, Guid>
|
||||
return results.ToList();
|
||||
}
|
||||
|
||||
public async Task<OrganizationDomainSsoDetailsData> GetOrganizationDomainSsoDetailsAsync(string email)
|
||||
public async Task<OrganizationDomainSsoDetailsData?> GetOrganizationDomainSsoDetailsAsync(string email)
|
||||
{
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
@ -69,7 +71,7 @@ public class OrganizationDomainRepository : Repository<OrganizationDomain, Guid>
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<OrganizationDomain> GetDomainByIdOrganizationIdAsync(Guid id, Guid orgId)
|
||||
public async Task<OrganizationDomain?> GetDomainByIdOrganizationIdAsync(Guid id, Guid orgId)
|
||||
{
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
@ -83,7 +85,7 @@ public class OrganizationDomainRepository : Repository<OrganizationDomain, Guid>
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<OrganizationDomain> GetDomainByOrgIdAndDomainNameAsync(Guid orgId, string domainName)
|
||||
public async Task<OrganizationDomain?> GetDomainByOrgIdAndDomainNameAsync(Guid orgId, string domainName)
|
||||
{
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
|
@ -5,6 +5,8 @@ using Bit.Core.Settings;
|
||||
using Dapper;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.Dapper.Repositories;
|
||||
|
||||
public class OrganizationSponsorshipRepository : Repository<OrganizationSponsorship, Guid>, IOrganizationSponsorshipRepository
|
||||
@ -17,7 +19,7 @@ public class OrganizationSponsorshipRepository : Repository<OrganizationSponsors
|
||||
: base(connectionString, readOnlyConnectionString)
|
||||
{ }
|
||||
|
||||
public async Task<ICollection<Guid>> CreateManyAsync(IEnumerable<OrganizationSponsorship> organizationSponsorships)
|
||||
public async Task<ICollection<Guid>?> CreateManyAsync(IEnumerable<OrganizationSponsorship> organizationSponsorships)
|
||||
{
|
||||
if (!organizationSponsorships.Any())
|
||||
{
|
||||
@ -87,7 +89,7 @@ public class OrganizationSponsorshipRepository : Repository<OrganizationSponsors
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<OrganizationSponsorship> GetBySponsoringOrganizationUserIdAsync(Guid sponsoringOrganizationUserId)
|
||||
public async Task<OrganizationSponsorship?> GetBySponsoringOrganizationUserIdAsync(Guid sponsoringOrganizationUserId)
|
||||
{
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
@ -103,7 +105,7 @@ public class OrganizationSponsorshipRepository : Repository<OrganizationSponsors
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<OrganizationSponsorship> GetBySponsoredOrganizationIdAsync(Guid sponsoredOrganizationId)
|
||||
public async Task<OrganizationSponsorship?> GetBySponsoredOrganizationIdAsync(Guid sponsoredOrganizationId)
|
||||
{
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
|
@ -4,6 +4,8 @@ using Bit.Core.Repositories;
|
||||
using Dapper;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.Dapper.Repositories;
|
||||
|
||||
public abstract class Repository<T, TId> : BaseRepository, IRepository<T, TId>
|
||||
@ -11,7 +13,7 @@ public abstract class Repository<T, TId> : BaseRepository, IRepository<T, TId>
|
||||
where T : class, ITableObject<TId>
|
||||
{
|
||||
public Repository(string connectionString, string readOnlyConnectionString,
|
||||
string schema = null, string table = null)
|
||||
string? schema = null, string? table = null)
|
||||
: base(connectionString, readOnlyConnectionString)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(table))
|
||||
@ -28,7 +30,7 @@ public abstract class Repository<T, TId> : BaseRepository, IRepository<T, TId>
|
||||
protected string Schema { get; private set; } = "dbo";
|
||||
protected string Table { get; private set; } = typeof(T).Name;
|
||||
|
||||
public virtual async Task<T> GetByIdAsync(TId id)
|
||||
public virtual async Task<T?> GetByIdAsync(TId id)
|
||||
{
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
|
@ -5,6 +5,8 @@ using Bit.Core.Settings;
|
||||
using Dapper;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.Dapper.Repositories;
|
||||
|
||||
public class TaxRateRepository : Repository<TaxRate, string>, ITaxRateRepository
|
||||
|
@ -6,6 +6,8 @@ using Bit.Core.Settings;
|
||||
using Dapper;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.Dapper.Repositories;
|
||||
|
||||
public class TransactionRepository : Repository<Transaction, Guid>, ITransactionRepository
|
||||
@ -55,7 +57,7 @@ public class TransactionRepository : Repository<Transaction, Guid>, ITransaction
|
||||
return results.ToList();
|
||||
}
|
||||
|
||||
public async Task<Transaction> GetByGatewayIdAsync(GatewayType gatewayType, string gatewayId)
|
||||
public async Task<Transaction?> GetByGatewayIdAsync(GatewayType gatewayType, string gatewayId)
|
||||
{
|
||||
// maybe come back to this
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
|
@ -9,6 +9,8 @@ using Dapper;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.Dapper.Repositories;
|
||||
|
||||
public class UserRepository : Repository<User, Guid>, IUserRepository
|
||||
@ -18,23 +20,19 @@ public class UserRepository : Repository<User, Guid>, IUserRepository
|
||||
public UserRepository(
|
||||
GlobalSettings globalSettings,
|
||||
IDataProtectionProvider dataProtectionProvider)
|
||||
: this(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString)
|
||||
: base(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString)
|
||||
{
|
||||
_dataProtector = dataProtectionProvider.CreateProtector(Constants.DatabaseFieldProtectorPurpose);
|
||||
}
|
||||
|
||||
public UserRepository(string connectionString, string readOnlyConnectionString)
|
||||
: base(connectionString, readOnlyConnectionString)
|
||||
{ }
|
||||
|
||||
public override async Task<User> GetByIdAsync(Guid id)
|
||||
public override async Task<User?> GetByIdAsync(Guid id)
|
||||
{
|
||||
var user = await base.GetByIdAsync(id);
|
||||
UnprotectData(user);
|
||||
return user;
|
||||
}
|
||||
|
||||
public async Task<User> GetByEmailAsync(string email)
|
||||
public async Task<User?> GetByEmailAsync(string email)
|
||||
{
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
@ -69,7 +67,7 @@ public class UserRepository : Repository<User, Guid>, IUserRepository
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<User> GetBySsoUserAsync(string externalId, Guid? organizationId)
|
||||
public async Task<User?> GetBySsoUserAsync(string externalId, Guid? organizationId)
|
||||
{
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
@ -83,7 +81,7 @@ public class UserRepository : Repository<User, Guid>, IUserRepository
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<UserKdfInformation> GetKdfInformationByEmailAsync(string email)
|
||||
public async Task<UserKdfInformation?> GetKdfInformationByEmailAsync(string email)
|
||||
{
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
@ -125,7 +123,7 @@ public class UserRepository : Repository<User, Guid>, IUserRepository
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<string> GetPublicKeyAsync(Guid id)
|
||||
public async Task<string?> GetPublicKeyAsync(Guid id)
|
||||
{
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
@ -273,13 +271,13 @@ public class UserRepository : Repository<User, Guid>, IUserRepository
|
||||
if (!user.MasterPassword?.StartsWith(Constants.DatabaseFieldProtectedPrefix) ?? false)
|
||||
{
|
||||
user.MasterPassword = string.Concat(Constants.DatabaseFieldProtectedPrefix,
|
||||
_dataProtector.Protect(user.MasterPassword));
|
||||
_dataProtector.Protect(user.MasterPassword!));
|
||||
}
|
||||
|
||||
if (!user.Key?.StartsWith(Constants.DatabaseFieldProtectedPrefix) ?? false)
|
||||
{
|
||||
user.Key = string.Concat(Constants.DatabaseFieldProtectedPrefix,
|
||||
_dataProtector.Protect(user.Key));
|
||||
_dataProtector.Protect(user.Key!));
|
||||
}
|
||||
|
||||
// Save
|
||||
@ -290,7 +288,7 @@ public class UserRepository : Repository<User, Guid>, IUserRepository
|
||||
user.Key = originalKey;
|
||||
}
|
||||
|
||||
private void UnprotectData(User user)
|
||||
private void UnprotectData(User? user)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
|
@ -1,5 +1,7 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework;
|
||||
|
||||
public static class EfExtensions
|
||||
|
@ -4,13 +4,15 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Caching.Distributed;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework;
|
||||
|
||||
public class EntityFrameworkCache : IDistributedCache
|
||||
{
|
||||
#if DEBUG
|
||||
// Used for debugging in tests
|
||||
public Task scanTask;
|
||||
public Task? scanTask;
|
||||
#endif
|
||||
private static readonly TimeSpan _defaultSlidingExpiration = TimeSpan.FromMinutes(20);
|
||||
private static readonly TimeSpan _expiredItemsDeletionInterval = TimeSpan.FromMinutes(30);
|
||||
@ -22,14 +24,14 @@ public class EntityFrameworkCache : IDistributedCache
|
||||
|
||||
public EntityFrameworkCache(
|
||||
IServiceScopeFactory serviceScopeFactory,
|
||||
TimeProvider timeProvider = null)
|
||||
TimeProvider? timeProvider = null)
|
||||
{
|
||||
_deleteExpiredCachedItemsDelegate = DeleteExpiredCacheItems;
|
||||
_serviceScopeFactory = serviceScopeFactory;
|
||||
_timeProvider = timeProvider ?? TimeProvider.System;
|
||||
}
|
||||
|
||||
public byte[] Get(string key)
|
||||
public byte[]? Get(string key)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(key);
|
||||
|
||||
@ -53,7 +55,7 @@ public class EntityFrameworkCache : IDistributedCache
|
||||
return cache?.Value;
|
||||
}
|
||||
|
||||
public async Task<byte[]> GetAsync(string key, CancellationToken token = default)
|
||||
public async Task<byte[]?> GetAsync(string key, CancellationToken token = default)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(key);
|
||||
token.ThrowIfCancellationRequested();
|
||||
@ -181,7 +183,7 @@ public class EntityFrameworkCache : IDistributedCache
|
||||
ScanForExpiredItemsIfRequired();
|
||||
}
|
||||
|
||||
private Cache SetCache(Cache cache, string key, byte[] value, DistributedCacheEntryOptions options)
|
||||
private Cache SetCache(Cache? cache, string key, byte[] value, DistributedCacheEntryOptions options)
|
||||
{
|
||||
var utcNow = _timeProvider.GetUtcNow().DateTime;
|
||||
|
||||
|
@ -1,12 +1,14 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Models;
|
||||
|
||||
public class Cache
|
||||
{
|
||||
[StringLength(449)]
|
||||
public string Id { get; set; }
|
||||
public byte[] Value { get; set; }
|
||||
public required string Id { get; set; }
|
||||
public byte[] Value { get; set; } = null!;
|
||||
public DateTime ExpiresAtTime { get; set; }
|
||||
public long? SlidingExpirationInSeconds { get; set; }
|
||||
public DateTime? AbsoluteExpiration { get; set; }
|
||||
|
@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using User = Bit.Core.Entities.User;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Repositories;
|
||||
|
||||
public abstract class BaseEntityFrameworkRepository
|
||||
|
@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using CollectionCipher = Bit.Core.Entities.CollectionCipher;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Repositories;
|
||||
|
||||
public class CollectionCipherRepository : BaseEntityFrameworkRepository, ICollectionCipherRepository
|
||||
@ -21,7 +23,7 @@ public class CollectionCipherRepository : BaseEntityFrameworkRepository, ICollec
|
||||
var entity = Mapper.Map<Models.CollectionCipher>(obj);
|
||||
dbContext.Add(entity);
|
||||
await dbContext.SaveChangesAsync();
|
||||
var organizationId = (await dbContext.Ciphers.FirstOrDefaultAsync(c => c.Id.Equals(obj.CipherId))).OrganizationId;
|
||||
var organizationId = (await dbContext.Ciphers.FirstOrDefaultAsync(c => c.Id.Equals(obj.CipherId)))?.OrganizationId;
|
||||
if (organizationId.HasValue)
|
||||
{
|
||||
await dbContext.UserBumpAccountRevisionDateByCollectionIdAsync(obj.CollectionId, organizationId.Value);
|
||||
|
@ -6,6 +6,8 @@ using Bit.Infrastructure.EntityFramework.Repositories.Queries;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Repositories;
|
||||
|
||||
public class CollectionRepository : Repository<Core.Entities.Collection, Collection, Guid>, ICollectionRepository
|
||||
@ -110,7 +112,7 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Tuple<Core.Entities.Collection, CollectionAccessDetails>> GetByIdWithAccessAsync(Guid id)
|
||||
public async Task<Tuple<Core.Entities.Collection?, CollectionAccessDetails>> GetByIdWithAccessAsync(Guid id)
|
||||
{
|
||||
var collection = await base.GetByIdAsync(id);
|
||||
using (var scope = ServiceScopeFactory.CreateScope())
|
||||
@ -139,7 +141,7 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
|
||||
var users = await userQuery.ToArrayAsync();
|
||||
var access = new CollectionAccessDetails { Users = users, Groups = groups };
|
||||
|
||||
return new Tuple<Core.Entities.Collection, CollectionAccessDetails>(collection, access);
|
||||
return new Tuple<Core.Entities.Collection?, CollectionAccessDetails>(collection, access);
|
||||
}
|
||||
}
|
||||
|
||||
@ -392,7 +394,7 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<CollectionAdminDetails> GetByIdWithPermissionsAsync(Guid collectionId, Guid? userId,
|
||||
public async Task<CollectionAdminDetails?> GetByIdWithPermissionsAsync(Guid collectionId, Guid? userId,
|
||||
bool includeAccessRelationships)
|
||||
{
|
||||
using (var scope = ServiceScopeFactory.CreateScope())
|
||||
@ -400,7 +402,7 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
|
||||
var dbContext = GetDatabaseContext(scope);
|
||||
var query = CollectionAdminDetailsQuery.ByCollectionId(collectionId, userId).Run(dbContext);
|
||||
|
||||
CollectionAdminDetails collectionDetails;
|
||||
CollectionAdminDetails? collectionDetails;
|
||||
|
||||
// SQLite does not support the GROUP BY clause
|
||||
if (dbContext.Database.IsSqlite())
|
||||
@ -474,7 +476,8 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
|
||||
HidePasswords = cg.HidePasswords,
|
||||
Manage = cg.Manage
|
||||
};
|
||||
collectionDetails.Groups = await groupsQuery.ToListAsync();
|
||||
// TODO-NRE: Probably need to null check and return early
|
||||
collectionDetails!.Groups = await groupsQuery.ToListAsync();
|
||||
|
||||
var usersQuery = from cg in dbContext.CollectionUsers
|
||||
where cg.CollectionId.Equals(collectionId)
|
||||
|
@ -12,6 +12,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using DP = Microsoft.AspNetCore.DataProtection;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Repositories;
|
||||
|
||||
public class DatabaseContext : DbContext
|
||||
|
@ -1,9 +1,12 @@
|
||||
using Bit.Core.AdminConsole.Enums.Provider;
|
||||
using System.Diagnostics;
|
||||
using Bit.Core.AdminConsole.Enums.Provider;
|
||||
using Bit.Core.Auth.Enums;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Infrastructure.EntityFramework.Repositories.Queries;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Repositories;
|
||||
|
||||
public static class DatabaseContextExtensions
|
||||
@ -11,6 +14,7 @@ public static class DatabaseContextExtensions
|
||||
public static async Task UserBumpAccountRevisionDateAsync(this DatabaseContext context, Guid userId)
|
||||
{
|
||||
var user = await context.Users.FindAsync(userId);
|
||||
Debug.Assert(user is not null, "The user id is expected to be validated as a true-in database user before making this call.");
|
||||
user.AccountRevisionDate = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,8 @@ using Bit.Infrastructure.EntityFramework.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Repositories;
|
||||
|
||||
public class DeviceRepository : Repository<Core.Entities.Device, Device, Guid>, IDeviceRepository
|
||||
@ -24,7 +26,7 @@ public class DeviceRepository : Repository<Core.Entities.Device, Device, Guid>,
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Core.Entities.Device> GetByIdAsync(Guid id, Guid userId)
|
||||
public async Task<Core.Entities.Device?> GetByIdAsync(Guid id, Guid userId)
|
||||
{
|
||||
var device = await base.GetByIdAsync(id);
|
||||
if (device == null || device.UserId != userId)
|
||||
@ -35,7 +37,7 @@ public class DeviceRepository : Repository<Core.Entities.Device, Device, Guid>,
|
||||
return Mapper.Map<Core.Entities.Device>(device);
|
||||
}
|
||||
|
||||
public async Task<Core.Entities.Device> GetByIdentifierAsync(string identifier)
|
||||
public async Task<Core.Entities.Device?> GetByIdentifierAsync(string identifier)
|
||||
{
|
||||
using (var scope = ServiceScopeFactory.CreateScope())
|
||||
{
|
||||
@ -46,7 +48,7 @@ public class DeviceRepository : Repository<Core.Entities.Device, Device, Guid>,
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Core.Entities.Device> GetByIdentifierAsync(string identifier, Guid userId)
|
||||
public async Task<Core.Entities.Device?> GetByIdentifierAsync(string identifier, Guid userId)
|
||||
{
|
||||
using (var scope = ServiceScopeFactory.CreateScope())
|
||||
{
|
||||
|
@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Cipher = Bit.Core.Vault.Entities.Cipher;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Repositories;
|
||||
|
||||
public class EventRepository : Repository<Core.Entities.Event, Event, Guid>, IEventRepository
|
||||
@ -28,7 +30,7 @@ public class EventRepository : Repository<Core.Entities.Event, Event, Guid>, IEv
|
||||
|
||||
public async Task CreateManyAsync(IEnumerable<IEvent> entities)
|
||||
{
|
||||
if (!entities?.Any() ?? true)
|
||||
if (entities is null || !entities.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ using Bit.Core.Repositories;
|
||||
using Bit.Infrastructure.EntityFramework.Models;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Repositories;
|
||||
|
||||
public class InstallationRepository : Repository<Core.Entities.Installation, Installation, Guid>, IInstallationRepository
|
||||
|
@ -2,6 +2,8 @@
|
||||
using Bit.Core.Repositories;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Repositories;
|
||||
|
||||
public class MaintenanceRepository : BaseEntityFrameworkRepository, IMaintenanceRepository
|
||||
|
@ -5,6 +5,8 @@ using Bit.Core.Repositories;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Repositories;
|
||||
|
||||
public class OrganizationApiKeyRepository : Repository<OrganizationApiKey, Models.OrganizationApiKey, Guid>, IOrganizationApiKeyRepository
|
||||
|
@ -5,6 +5,8 @@ using Bit.Core.Repositories;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Repositories;
|
||||
|
||||
public class OrganizationConnectionRepository : Repository<OrganizationConnection, Models.OrganizationConnection, Guid>, IOrganizationConnectionRepository
|
||||
@ -15,7 +17,7 @@ public class OrganizationConnectionRepository : Repository<OrganizationConnectio
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<OrganizationConnection> GetByIdOrganizationIdAsync(Guid id, Guid organizationId)
|
||||
public async Task<OrganizationConnection?> GetByIdOrganizationIdAsync(Guid id, Guid organizationId)
|
||||
{
|
||||
using (var scope = ServiceScopeFactory.CreateScope())
|
||||
{
|
||||
|
@ -6,6 +6,8 @@ using Bit.Infrastructure.EntityFramework.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Repositories;
|
||||
|
||||
public class OrganizationDomainRepository : Repository<Core.Entities.OrganizationDomain, OrganizationDomain, Guid>, IOrganizationDomainRepository
|
||||
@ -67,7 +69,7 @@ public class OrganizationDomainRepository : Repository<Core.Entities.Organizatio
|
||||
return Mapper.Map<List<Core.Entities.OrganizationDomain>>(results);
|
||||
}
|
||||
|
||||
public async Task<OrganizationDomainSsoDetailsData> GetOrganizationDomainSsoDetailsAsync(string email)
|
||||
public async Task<OrganizationDomainSsoDetailsData?> GetOrganizationDomainSsoDetailsAsync(string email)
|
||||
{
|
||||
var domainName = new MailAddress(email).Host;
|
||||
|
||||
@ -93,7 +95,7 @@ public class OrganizationDomainRepository : Repository<Core.Entities.Organizatio
|
||||
return ssoDetails;
|
||||
}
|
||||
|
||||
public async Task<Core.Entities.OrganizationDomain> GetDomainByIdOrganizationIdAsync(Guid id, Guid orgId)
|
||||
public async Task<Core.Entities.OrganizationDomain?> GetDomainByIdOrganizationIdAsync(Guid id, Guid orgId)
|
||||
{
|
||||
using var scope = ServiceScopeFactory.CreateScope();
|
||||
var dbContext = GetDatabaseContext(scope);
|
||||
@ -105,7 +107,7 @@ public class OrganizationDomainRepository : Repository<Core.Entities.Organizatio
|
||||
return Mapper.Map<Core.Entities.OrganizationDomain>(domain);
|
||||
}
|
||||
|
||||
public async Task<Core.Entities.OrganizationDomain> GetDomainByOrgIdAndDomainNameAsync(Guid orgId, string domainName)
|
||||
public async Task<Core.Entities.OrganizationDomain?> GetDomainByOrgIdAndDomainNameAsync(Guid orgId, string domainName)
|
||||
{
|
||||
using var scope = ServiceScopeFactory.CreateScope();
|
||||
var dbContext = GetDatabaseContext(scope);
|
||||
|
@ -4,6 +4,8 @@ using Bit.Infrastructure.EntityFramework.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Repositories;
|
||||
|
||||
public class OrganizationSponsorshipRepository : Repository<Core.Entities.OrganizationSponsorship, OrganizationSponsorship, Guid>, IOrganizationSponsorshipRepository
|
||||
@ -12,10 +14,11 @@ public class OrganizationSponsorshipRepository : Repository<Core.Entities.Organi
|
||||
: base(serviceScopeFactory, mapper, (DatabaseContext context) => context.OrganizationSponsorships)
|
||||
{ }
|
||||
|
||||
public async Task<ICollection<Guid>> CreateManyAsync(IEnumerable<Core.Entities.OrganizationSponsorship> organizationSponsorships)
|
||||
public async Task<ICollection<Guid>?> CreateManyAsync(IEnumerable<Core.Entities.OrganizationSponsorship> organizationSponsorships)
|
||||
{
|
||||
if (!organizationSponsorships.Any())
|
||||
{
|
||||
// TODO: This differs from SQL server implementation, we should have both return empty collection
|
||||
return new List<Guid>();
|
||||
}
|
||||
|
||||
@ -79,7 +82,7 @@ public class OrganizationSponsorshipRepository : Repository<Core.Entities.Organi
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Core.Entities.OrganizationSponsorship> GetByOfferedToEmailAsync(string email)
|
||||
public async Task<Core.Entities.OrganizationSponsorship?> GetByOfferedToEmailAsync(string email)
|
||||
{
|
||||
using (var scope = ServiceScopeFactory.CreateScope())
|
||||
{
|
||||
@ -90,7 +93,7 @@ public class OrganizationSponsorshipRepository : Repository<Core.Entities.Organi
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Core.Entities.OrganizationSponsorship> GetBySponsoredOrganizationIdAsync(Guid sponsoredOrganizationId)
|
||||
public async Task<Core.Entities.OrganizationSponsorship?> GetBySponsoredOrganizationIdAsync(Guid sponsoredOrganizationId)
|
||||
{
|
||||
using (var scope = ServiceScopeFactory.CreateScope())
|
||||
{
|
||||
@ -101,7 +104,7 @@ public class OrganizationSponsorshipRepository : Repository<Core.Entities.Organi
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Core.Entities.OrganizationSponsorship> GetBySponsoringOrganizationUserIdAsync(Guid sponsoringOrganizationUserId)
|
||||
public async Task<Core.Entities.OrganizationSponsorship?> GetBySponsoringOrganizationUserIdAsync(Guid sponsoringOrganizationUserId)
|
||||
{
|
||||
using (var scope = ServiceScopeFactory.CreateScope())
|
||||
{
|
||||
|
@ -5,6 +5,8 @@ using Bit.Infrastructure.EntityFramework.Repositories.Queries;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Repositories;
|
||||
|
||||
public abstract class Repository<T, TEntity, TId> : BaseEntityFrameworkRepository, IRepository<T, TId>
|
||||
@ -20,7 +22,7 @@ public abstract class Repository<T, TEntity, TId> : BaseEntityFrameworkRepositor
|
||||
|
||||
protected Func<DatabaseContext, DbSet<TEntity>> GetDbSet { get; private set; }
|
||||
|
||||
public virtual async Task<T> GetByIdAsync(TId id)
|
||||
public virtual async Task<T?> GetByIdAsync(TId id)
|
||||
{
|
||||
using (var scope = ServiceScopeFactory.CreateScope())
|
||||
{
|
||||
|
@ -4,6 +4,8 @@ using Bit.Infrastructure.EntityFramework.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Repositories;
|
||||
|
||||
public class TaxRateRepository : Repository<Core.Entities.TaxRate, TaxRate, string>, ITaxRateRepository
|
||||
@ -17,9 +19,9 @@ public class TaxRateRepository : Repository<Core.Entities.TaxRate, TaxRate, stri
|
||||
using (var scope = ServiceScopeFactory.CreateScope())
|
||||
{
|
||||
var dbContext = GetDatabaseContext(scope);
|
||||
var entity = await dbContext.FindAsync<Core.Entities.TaxRate>(model);
|
||||
entity.Active = false;
|
||||
await dbContext.SaveChangesAsync();
|
||||
await dbContext.TaxRates
|
||||
.Where(tr => tr.Id == model.Id)
|
||||
.ExecuteUpdateAsync(property => property.SetProperty(tr => tr.Active, false));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,8 @@ using LinqToDB;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Repositories;
|
||||
|
||||
public class TransactionRepository : Repository<Core.Entities.Transaction, Transaction, Guid>, ITransactionRepository
|
||||
@ -14,7 +16,7 @@ public class TransactionRepository : Repository<Core.Entities.Transaction, Trans
|
||||
: base(serviceScopeFactory, mapper, (DatabaseContext context) => context.Transactions)
|
||||
{ }
|
||||
|
||||
public async Task<Core.Entities.Transaction> GetByGatewayIdAsync(GatewayType gatewayType, string gatewayId)
|
||||
public async Task<Core.Entities.Transaction?> GetByGatewayIdAsync(GatewayType gatewayType, string gatewayId)
|
||||
{
|
||||
using var scope = ServiceScopeFactory.CreateScope();
|
||||
var dbContext = GetDatabaseContext(scope);
|
||||
|
@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using DataModel = Bit.Core.Models.Data;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Repositories;
|
||||
|
||||
public class UserRepository : Repository<Core.Entities.User, User, Guid>, IUserRepository
|
||||
@ -14,7 +16,7 @@ public class UserRepository : Repository<Core.Entities.User, User, Guid>, IUserR
|
||||
: base(serviceScopeFactory, mapper, (DatabaseContext context) => context.Users)
|
||||
{ }
|
||||
|
||||
public async Task<Core.Entities.User> GetByEmailAsync(string email)
|
||||
public async Task<Core.Entities.User?> GetByEmailAsync(string email)
|
||||
{
|
||||
using (var scope = ServiceScopeFactory.CreateScope())
|
||||
{
|
||||
@ -36,7 +38,7 @@ public class UserRepository : Repository<Core.Entities.User, User, Guid>, IUserR
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<DataModel.UserKdfInformation> GetKdfInformationByEmailAsync(string email)
|
||||
public async Task<DataModel.UserKdfInformation?> GetKdfInformationByEmailAsync(string email)
|
||||
{
|
||||
using (var scope = ServiceScopeFactory.CreateScope())
|
||||
{
|
||||
@ -89,7 +91,7 @@ public class UserRepository : Repository<Core.Entities.User, User, Guid>, IUserR
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<string> GetPublicKeyAsync(Guid id)
|
||||
public async Task<string?> GetPublicKeyAsync(Guid id)
|
||||
{
|
||||
using (var scope = ServiceScopeFactory.CreateScope())
|
||||
{
|
||||
@ -130,7 +132,7 @@ public class UserRepository : Repository<Core.Entities.User, User, Guid>, IUserR
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Core.Entities.User> GetBySsoUserAsync(string externalId, Guid? organizationId)
|
||||
public async Task<Core.Entities.User?> GetBySsoUserAsync(string externalId, Guid? organizationId)
|
||||
{
|
||||
using (var scope = ServiceScopeFactory.CreateScope())
|
||||
{
|
||||
|
@ -199,6 +199,8 @@ public class IdentityServerSsoTests
|
||||
var userRepository = factory.Services.GetRequiredService<IUserRepository>();
|
||||
var user = await userRepository.GetByEmailAsync(TestEmail);
|
||||
|
||||
Assert.NotNull(user);
|
||||
|
||||
var deviceRepository = factory.Services.GetRequiredService<IDeviceRepository>();
|
||||
await deviceRepository.CreateAsync(new Device
|
||||
{
|
||||
@ -277,6 +279,7 @@ public class IdentityServerSsoTests
|
||||
var deviceIdentifier = $"test_id_{Guid.NewGuid()}";
|
||||
|
||||
var user = await factory.Services.GetRequiredService<IUserRepository>().GetByEmailAsync(TestEmail);
|
||||
Assert.NotNull(user);
|
||||
|
||||
const string expectedPrivateKey = "2.QmFzZTY0UGFydA==|QmFzZTY0UGFydA==|QmFzZTY0UGFydA==";
|
||||
const string expectedUserKey = "2.QmFzZTY0UGFydA==|QmFzZTY0UGFydA==|QmFzZTY0UGFydA==";
|
||||
@ -405,6 +408,7 @@ public class IdentityServerSsoTests
|
||||
}, challenge);
|
||||
|
||||
var user = await factory.Services.GetRequiredService<IUserRepository>().GetByEmailAsync(TestEmail);
|
||||
Assert.NotNull(user);
|
||||
var providerRepository = factory.Services.GetRequiredService<IProviderRepository>();
|
||||
var provider = await providerRepository.CreateAsync(new Provider
|
||||
{
|
||||
@ -551,7 +555,7 @@ public class IdentityServerSsoTests
|
||||
RequestedScopes = new[] { "api", "offline_access" },
|
||||
CodeChallenge = challenge.Sha256(),
|
||||
CodeChallengeMethod = "plain", //
|
||||
Subject = null, // Temporarily set it to null
|
||||
Subject = null!, // Temporarily set it to null
|
||||
};
|
||||
|
||||
factory.SubstituteService<IAuthorizationCodeStore>(service =>
|
||||
@ -569,6 +573,7 @@ public class IdentityServerSsoTests
|
||||
|
||||
var userRepository = factory.Services.GetRequiredService<IUserRepository>();
|
||||
var user = await userRepository.GetByEmailAsync(TestEmail);
|
||||
Assert.NotNull(user);
|
||||
|
||||
var organizationRepository = factory.Services.GetRequiredService<IOrganizationRepository>();
|
||||
var organization = await organizationRepository.CreateAsync(new Organization
|
||||
@ -621,7 +626,7 @@ public class IdentityServerSsoTests
|
||||
{
|
||||
var userRepository = factory.Services.GetRequiredService<IUserRepository>();
|
||||
var user = await userRepository.GetByEmailAsync(TestEmail);
|
||||
|
||||
Assert.NotNull(user);
|
||||
changeUser(user);
|
||||
|
||||
await userRepository.ReplaceAsync(user);
|
||||
|
2697
util/MySqlMigrations/Migrations/20240724001641_MakeBlobNonNull.Designer.cs
generated
Normal file
2697
util/MySqlMigrations/Migrations/20240724001641_MakeBlobNonNull.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,35 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Bit.MySqlMigrations.Migrations;
|
||||
|
||||
/// <inheritdoc />
|
||||
public partial class MakeBlobNonNull : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<byte[]>(
|
||||
name: "Value",
|
||||
table: "Cache",
|
||||
type: "longblob",
|
||||
nullable: false,
|
||||
defaultValue: new byte[0],
|
||||
oldClrType: typeof(byte[]),
|
||||
oldType: "longblob",
|
||||
oldNullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<byte[]>(
|
||||
name: "Value",
|
||||
table: "Cache",
|
||||
type: "longblob",
|
||||
nullable: true,
|
||||
oldClrType: typeof(byte[]),
|
||||
oldType: "longblob");
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ namespace Bit.MySqlMigrations.Migrations
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "8.0.6")
|
||||
.HasAnnotation("ProductVersion", "8.0.7")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||
|
||||
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
|
||||
@ -780,6 +780,7 @@ namespace Bit.MySqlMigrations.Migrations
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<byte[]>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("longblob");
|
||||
|
||||
b.HasKey("Id")
|
||||
@ -1622,7 +1623,7 @@ namespace Bit.MySqlMigrations.Migrations
|
||||
|
||||
b.ToTable("AccessPolicy", (string)null);
|
||||
|
||||
b.HasDiscriminator<string>("Discriminator").HasValue("AccessPolicy");
|
||||
b.HasDiscriminator().HasValue("AccessPolicy");
|
||||
|
||||
b.UseTphMappingStrategy();
|
||||
});
|
||||
|
2704
util/PostgresMigrations/Migrations/20240724001647_MakeBlobNonNull.Designer.cs
generated
Normal file
2704
util/PostgresMigrations/Migrations/20240724001647_MakeBlobNonNull.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,35 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Bit.PostgresMigrations.Migrations;
|
||||
|
||||
/// <inheritdoc />
|
||||
public partial class MakeBlobNonNull : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<byte[]>(
|
||||
name: "Value",
|
||||
table: "Cache",
|
||||
type: "bytea",
|
||||
nullable: false,
|
||||
defaultValue: new byte[0],
|
||||
oldClrType: typeof(byte[]),
|
||||
oldType: "bytea",
|
||||
oldNullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<byte[]>(
|
||||
name: "Value",
|
||||
table: "Cache",
|
||||
type: "bytea",
|
||||
nullable: true,
|
||||
oldClrType: typeof(byte[]),
|
||||
oldType: "bytea");
|
||||
}
|
||||
}
|
@ -18,7 +18,7 @@ namespace Bit.PostgresMigrations.Migrations
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("Npgsql:CollationDefinition:postgresIndetermanisticCollation", "en-u-ks-primary,en-u-ks-primary,icu,False")
|
||||
.HasAnnotation("ProductVersion", "8.0.6")
|
||||
.HasAnnotation("ProductVersion", "8.0.7")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
@ -785,6 +785,7 @@ namespace Bit.PostgresMigrations.Migrations
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<byte[]>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("bytea");
|
||||
|
||||
b.HasKey("Id")
|
||||
@ -1629,7 +1630,7 @@ namespace Bit.PostgresMigrations.Migrations
|
||||
|
||||
b.ToTable("AccessPolicy", (string)null);
|
||||
|
||||
b.HasDiscriminator<string>("Discriminator").HasValue("AccessPolicy");
|
||||
b.HasDiscriminator().HasValue("AccessPolicy");
|
||||
|
||||
b.UseTphMappingStrategy();
|
||||
});
|
||||
|
2686
util/SqliteMigrations/Migrations/20240724001634_MakeBlobNonNull.Designer.cs
generated
Normal file
2686
util/SqliteMigrations/Migrations/20240724001634_MakeBlobNonNull.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,35 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Bit.SqliteMigrations.Migrations;
|
||||
|
||||
/// <inheritdoc />
|
||||
public partial class MakeBlobNonNull : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<byte[]>(
|
||||
name: "Value",
|
||||
table: "Cache",
|
||||
type: "BLOB",
|
||||
nullable: false,
|
||||
defaultValue: new byte[0],
|
||||
oldClrType: typeof(byte[]),
|
||||
oldType: "BLOB",
|
||||
oldNullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<byte[]>(
|
||||
name: "Value",
|
||||
table: "Cache",
|
||||
type: "BLOB",
|
||||
nullable: true,
|
||||
oldClrType: typeof(byte[]),
|
||||
oldType: "BLOB");
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ namespace Bit.SqliteMigrations.Migrations
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.6");
|
||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.7");
|
||||
|
||||
modelBuilder.Entity("Bit.Infrastructure.EntityFramework.AdminConsole.Models.Organization", b =>
|
||||
{
|
||||
@ -769,6 +769,7 @@ namespace Bit.SqliteMigrations.Migrations
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<byte[]>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("BLOB");
|
||||
|
||||
b.HasKey("Id")
|
||||
@ -1611,7 +1612,7 @@ namespace Bit.SqliteMigrations.Migrations
|
||||
|
||||
b.ToTable("AccessPolicy", (string)null);
|
||||
|
||||
b.HasDiscriminator<string>("Discriminator").HasValue("AccessPolicy");
|
||||
b.HasDiscriminator().HasValue("AccessPolicy");
|
||||
|
||||
b.UseTphMappingStrategy();
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user