1
0
mirror of https://github.com/bitwarden/server.git synced 2025-04-08 14:38:15 -05:00

support for readonly sql db connection string

This commit is contained in:
Kyle Spearrin 2018-10-09 17:21:12 -04:00
parent aba009c221
commit cbab6eb9d7
17 changed files with 65 additions and 47 deletions

View File

@ -48,6 +48,7 @@ namespace Bit.Core
public class SqlServerSettings public class SqlServerSettings
{ {
private string _connectionString; private string _connectionString;
private string _readOnlyConnectionString;
public string ConnectionString public string ConnectionString
{ {
@ -57,6 +58,16 @@ namespace Bit.Core
_connectionString = value.Trim('"'); _connectionString = value.Trim('"');
} }
} }
public string ReadOnlyConnectionString
{
get => string.IsNullOrWhiteSpace(_readOnlyConnectionString) ?
_connectionString : _readOnlyConnectionString;
set
{
_readOnlyConnectionString = value.Trim('"');
}
}
} }
public class StorageSettings public class StorageSettings

View File

@ -10,16 +10,22 @@ namespace Bit.Core.Repositories.SqlServer
SqlMapper.AddTypeHandler(new DateTimeHandler()); SqlMapper.AddTypeHandler(new DateTimeHandler());
} }
public BaseRepository(string connectionString) public BaseRepository(string connectionString, string readOnlyConnectionString)
{ {
if(string.IsNullOrWhiteSpace(connectionString)) if(string.IsNullOrWhiteSpace(connectionString))
{ {
throw new ArgumentNullException(nameof(connectionString)); throw new ArgumentNullException(nameof(connectionString));
} }
if(string.IsNullOrWhiteSpace(readOnlyConnectionString))
{
throw new ArgumentNullException(nameof(readOnlyConnectionString));
}
ConnectionString = connectionString; ConnectionString = connectionString;
ReadOnlyConnectionString = readOnlyConnectionString;
} }
protected string ConnectionString { get; private set; } protected string ConnectionString { get; private set; }
protected string ReadOnlyConnectionString { get; private set; }
} }
} }

View File

@ -16,11 +16,11 @@ namespace Bit.Core.Repositories.SqlServer
public class CipherRepository : Repository<Cipher, Guid>, ICipherRepository public class CipherRepository : Repository<Cipher, Guid>, ICipherRepository
{ {
public CipherRepository(GlobalSettings globalSettings) public CipherRepository(GlobalSettings globalSettings)
: this(globalSettings.SqlServer.ConnectionString) : this(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString)
{ } { }
public CipherRepository(string connectionString) public CipherRepository(string connectionString, string readOnlyConnectionString)
: base(connectionString) : base(connectionString, readOnlyConnectionString)
{ } { }
public async Task<CipherDetails> GetByIdAsync(Guid id, Guid userId) public async Task<CipherDetails> GetByIdAsync(Guid id, Guid userId)

View File

@ -13,11 +13,11 @@ namespace Bit.Core.Repositories.SqlServer
public class CollectionCipherRepository : BaseRepository, ICollectionCipherRepository public class CollectionCipherRepository : BaseRepository, ICollectionCipherRepository
{ {
public CollectionCipherRepository(GlobalSettings globalSettings) public CollectionCipherRepository(GlobalSettings globalSettings)
: this(globalSettings.SqlServer.ConnectionString) : this(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString)
{ } { }
public CollectionCipherRepository(string connectionString) public CollectionCipherRepository(string connectionString, string readOnlyConnectionString)
: base(connectionString) : base(connectionString, readOnlyConnectionString)
{ } { }
public async Task<ICollection<CollectionCipher>> GetManyByUserIdAsync(Guid userId) public async Task<ICollection<CollectionCipher>> GetManyByUserIdAsync(Guid userId)

View File

@ -15,11 +15,11 @@ namespace Bit.Core.Repositories.SqlServer
public class CollectionRepository : Repository<Collection, Guid>, ICollectionRepository public class CollectionRepository : Repository<Collection, Guid>, ICollectionRepository
{ {
public CollectionRepository(GlobalSettings globalSettings) public CollectionRepository(GlobalSettings globalSettings)
: this(globalSettings.SqlServer.ConnectionString) : this(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString)
{ } { }
public CollectionRepository(string connectionString) public CollectionRepository(string connectionString, string readOnlyConnectionString)
: base(connectionString) : base(connectionString, readOnlyConnectionString)
{ } { }
public async Task<int> GetCountByOrganizationIdAsync(Guid organizationId) public async Task<int> GetCountByOrganizationIdAsync(Guid organizationId)

View File

@ -12,11 +12,11 @@ namespace Bit.Core.Repositories.SqlServer
public class DeviceRepository : Repository<Device, Guid>, IDeviceRepository public class DeviceRepository : Repository<Device, Guid>, IDeviceRepository
{ {
public DeviceRepository(GlobalSettings globalSettings) public DeviceRepository(GlobalSettings globalSettings)
: this(globalSettings.SqlServer.ConnectionString) : this(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString)
{ } { }
public DeviceRepository(string connectionString) public DeviceRepository(string connectionString, string readOnlyConnectionString)
: base(connectionString) : base(connectionString, readOnlyConnectionString)
{ } { }
public async Task<Device> GetByIdAsync(Guid id, Guid userId) public async Task<Device> GetByIdAsync(Guid id, Guid userId)

View File

@ -13,11 +13,11 @@ namespace Bit.Core.Repositories.SqlServer
public class EventRepository : Repository<Event, Guid>, IEventRepository public class EventRepository : Repository<Event, Guid>, IEventRepository
{ {
public EventRepository(GlobalSettings globalSettings) public EventRepository(GlobalSettings globalSettings)
: this(globalSettings.SqlServer.ConnectionString) : this(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString)
{ } { }
public EventRepository(string connectionString) public EventRepository(string connectionString, string readOnlyConnectionString)
: base(connectionString) : base(connectionString, readOnlyConnectionString)
{ } { }
public async Task<PagedResult<IEvent>> GetManyByUserAsync(Guid userId, DateTime startDate, DateTime endDate, public async Task<PagedResult<IEvent>> GetManyByUserAsync(Guid userId, DateTime startDate, DateTime endDate,

View File

@ -12,11 +12,11 @@ namespace Bit.Core.Repositories.SqlServer
public class FolderRepository : Repository<Folder, Guid>, IFolderRepository public class FolderRepository : Repository<Folder, Guid>, IFolderRepository
{ {
public FolderRepository(GlobalSettings globalSettings) public FolderRepository(GlobalSettings globalSettings)
: this(globalSettings.SqlServer.ConnectionString) : this(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString)
{ } { }
public FolderRepository(string connectionString) public FolderRepository(string connectionString, string readOnlyConnectionString)
: base(connectionString) : base(connectionString, readOnlyConnectionString)
{ } { }
public async Task<Folder> GetByIdAsync(Guid id, Guid userId) public async Task<Folder> GetByIdAsync(Guid id, Guid userId)

View File

@ -12,11 +12,11 @@ namespace Bit.Core.Repositories.SqlServer
public class GrantRepository : BaseRepository, IGrantRepository public class GrantRepository : BaseRepository, IGrantRepository
{ {
public GrantRepository(GlobalSettings globalSettings) public GrantRepository(GlobalSettings globalSettings)
: this(globalSettings.SqlServer.ConnectionString) : this(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString)
{ } { }
public GrantRepository(string connectionString) public GrantRepository(string connectionString, string readOnlyConnectionString)
: base(connectionString) : base(connectionString, readOnlyConnectionString)
{ } { }
public async Task<Grant> GetByKeyAsync(string key) public async Task<Grant> GetByKeyAsync(string key)

View File

@ -15,11 +15,11 @@ namespace Bit.Core.Repositories.SqlServer
public class GroupRepository : Repository<Group, Guid>, IGroupRepository public class GroupRepository : Repository<Group, Guid>, IGroupRepository
{ {
public GroupRepository(GlobalSettings globalSettings) public GroupRepository(GlobalSettings globalSettings)
: this(globalSettings.SqlServer.ConnectionString) : this(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString)
{ } { }
public GroupRepository(string connectionString) public GroupRepository(string connectionString, string readOnlyConnectionString)
: base(connectionString) : base(connectionString, readOnlyConnectionString)
{ } { }
public async Task<Tuple<Group, ICollection<SelectionReadOnly>>> GetByIdWithCollectionsAsync(Guid id) public async Task<Tuple<Group, ICollection<SelectionReadOnly>>> GetByIdWithCollectionsAsync(Guid id)

View File

@ -6,11 +6,11 @@ namespace Bit.Core.Repositories.SqlServer
public class InstallationRepository : Repository<Installation, Guid>, IInstallationRepository public class InstallationRepository : Repository<Installation, Guid>, IInstallationRepository
{ {
public InstallationRepository(GlobalSettings globalSettings) public InstallationRepository(GlobalSettings globalSettings)
: this(globalSettings.SqlServer.ConnectionString) : this(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString)
{ } { }
public InstallationRepository(string connectionString) public InstallationRepository(string connectionString, string readOnlyConnectionString)
: base(connectionString) : base(connectionString, readOnlyConnectionString)
{ } { }
} }
} }

View File

@ -8,11 +8,11 @@ namespace Bit.Core.Repositories.SqlServer
public class MaintenanceRepository : BaseRepository, IMaintenanceRepository public class MaintenanceRepository : BaseRepository, IMaintenanceRepository
{ {
public MaintenanceRepository(GlobalSettings globalSettings) public MaintenanceRepository(GlobalSettings globalSettings)
: this(globalSettings.SqlServer.ConnectionString) : this(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString)
{ } { }
public MaintenanceRepository(string connectionString) public MaintenanceRepository(string connectionString, string readOnlyConnectionString)
: base(connectionString) : base(connectionString, readOnlyConnectionString)
{ } { }
public async Task UpdateStatisticsAsync() public async Task UpdateStatisticsAsync()

View File

@ -13,11 +13,11 @@ namespace Bit.Core.Repositories.SqlServer
public class OrganizationRepository : Repository<Organization, Guid>, IOrganizationRepository public class OrganizationRepository : Repository<Organization, Guid>, IOrganizationRepository
{ {
public OrganizationRepository(GlobalSettings globalSettings) public OrganizationRepository(GlobalSettings globalSettings)
: this(globalSettings.SqlServer.ConnectionString) : this(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString)
{ } { }
public OrganizationRepository(string connectionString) public OrganizationRepository(string connectionString, string readOnlyConnectionString)
: base(connectionString) : base(connectionString, readOnlyConnectionString)
{ } { }
public async Task<ICollection<Organization>> GetManyByEnabledAsync() public async Task<ICollection<Organization>> GetManyByEnabledAsync()
@ -48,7 +48,7 @@ namespace Bit.Core.Repositories.SqlServer
public async Task<ICollection<Organization>> SearchAsync(string name, string userEmail, bool? paid, public async Task<ICollection<Organization>> SearchAsync(string name, string userEmail, bool? paid,
int skip, int take) int skip, int take)
{ {
using(var connection = new SqlConnection(ConnectionString)) using(var connection = new SqlConnection(ReadOnlyConnectionString))
{ {
var results = await connection.QueryAsync<Organization>( var results = await connection.QueryAsync<Organization>(
"[dbo].[Organization_Search]", "[dbo].[Organization_Search]",

View File

@ -16,11 +16,11 @@ namespace Bit.Core.Repositories.SqlServer
public class OrganizationUserRepository : Repository<OrganizationUser, Guid>, IOrganizationUserRepository public class OrganizationUserRepository : Repository<OrganizationUser, Guid>, IOrganizationUserRepository
{ {
public OrganizationUserRepository(GlobalSettings globalSettings) public OrganizationUserRepository(GlobalSettings globalSettings)
: this(globalSettings.SqlServer.ConnectionString) : this(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString)
{ } { }
public OrganizationUserRepository(string connectionString) public OrganizationUserRepository(string connectionString, string readOnlyConnectionString)
: base(connectionString) : base(connectionString, readOnlyConnectionString)
{ } { }
public async Task<int> GetCountByOrganizationIdAsync(Guid organizationId) public async Task<int> GetCountByOrganizationIdAsync(Guid organizationId)

View File

@ -12,8 +12,9 @@ namespace Bit.Core.Repositories.SqlServer
where TId : IEquatable<TId> where TId : IEquatable<TId>
where T : class, ITableObject<TId> where T : class, ITableObject<TId>
{ {
public Repository(string connectionString, string schema = null, string table = null) public Repository(string connectionString, string readOnlyConnectionString,
: base(connectionString) string schema = null, string table = null)
: base(connectionString, readOnlyConnectionString)
{ {
if(!string.IsNullOrWhiteSpace(table)) if(!string.IsNullOrWhiteSpace(table))
{ {

View File

@ -12,11 +12,11 @@ namespace Bit.Core.Repositories.SqlServer
public class U2fRepository : Repository<U2f, int>, IU2fRepository public class U2fRepository : Repository<U2f, int>, IU2fRepository
{ {
public U2fRepository(GlobalSettings globalSettings) public U2fRepository(GlobalSettings globalSettings)
: this(globalSettings.SqlServer.ConnectionString) : this(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString)
{ } { }
public U2fRepository(string connectionString) public U2fRepository(string connectionString, string readOnlyConnectionString)
: base(connectionString) : base(connectionString, readOnlyConnectionString)
{ } { }
public async Task<ICollection<U2f>> GetManyByUserIdAsync(Guid userId) public async Task<ICollection<U2f>> GetManyByUserIdAsync(Guid userId)

View File

@ -13,11 +13,11 @@ namespace Bit.Core.Repositories.SqlServer
public class UserRepository : Repository<User, Guid>, IUserRepository public class UserRepository : Repository<User, Guid>, IUserRepository
{ {
public UserRepository(GlobalSettings globalSettings) public UserRepository(GlobalSettings globalSettings)
: this(globalSettings.SqlServer.ConnectionString) : this(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString)
{ } { }
public UserRepository(string connectionString) public UserRepository(string connectionString, string readOnlyConnectionString)
: base(connectionString) : base(connectionString, readOnlyConnectionString)
{ } { }
public override async Task<User> GetByIdAsync(Guid id) public override async Task<User> GetByIdAsync(Guid id)
@ -53,7 +53,7 @@ namespace Bit.Core.Repositories.SqlServer
public async Task<ICollection<User>> SearchAsync(string email, int skip, int take) public async Task<ICollection<User>> SearchAsync(string email, int skip, int take)
{ {
using(var connection = new SqlConnection(ConnectionString)) using(var connection = new SqlConnection(ReadOnlyConnectionString))
{ {
var results = await connection.QueryAsync<User>( var results = await connection.QueryAsync<User>(
$"[{Schema}].[{Table}_Search]", $"[{Schema}].[{Table}_Search]",