mirror of
https://github.com/bitwarden/server.git
synced 2024-11-28 13:15:12 +01:00
add api support for updating org identifier (#861)
* add api support for updating org identifier * add identifier to response as well * implement in EF repo
This commit is contained in:
parent
c8220fdfa6
commit
056b4b9bf4
@ -10,6 +10,8 @@ namespace Bit.Core.Models.Api
|
|||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
[StringLength(50)]
|
[StringLength(50)]
|
||||||
public string BusinessName { get; set; }
|
public string BusinessName { get; set; }
|
||||||
|
[StringLength(50)]
|
||||||
|
public string Identifier { get; set; }
|
||||||
[EmailAddress]
|
[EmailAddress]
|
||||||
[Required]
|
[Required]
|
||||||
[StringLength(50)]
|
[StringLength(50)]
|
||||||
@ -20,6 +22,7 @@ namespace Bit.Core.Models.Api
|
|||||||
existingOrganization.Name = Name;
|
existingOrganization.Name = Name;
|
||||||
existingOrganization.BusinessName = BusinessName;
|
existingOrganization.BusinessName = BusinessName;
|
||||||
existingOrganization.BillingEmail = BillingEmail?.ToLowerInvariant()?.Trim();
|
existingOrganization.BillingEmail = BillingEmail?.ToLowerInvariant()?.Trim();
|
||||||
|
existingOrganization.Identifier = Identifier;
|
||||||
return existingOrganization;
|
return existingOrganization;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ namespace Bit.Core.Models.Api
|
|||||||
}
|
}
|
||||||
|
|
||||||
Id = organization.Id.ToString();
|
Id = organization.Id.ToString();
|
||||||
|
Identifier = organization.Identifier;
|
||||||
Name = organization.Name;
|
Name = organization.Name;
|
||||||
BusinessName = organization.BusinessName;
|
BusinessName = organization.BusinessName;
|
||||||
BusinessAddress1 = organization.BusinessAddress1;
|
BusinessAddress1 = organization.BusinessAddress1;
|
||||||
@ -44,6 +45,7 @@ namespace Bit.Core.Models.Api
|
|||||||
}
|
}
|
||||||
|
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
|
public string Identifier { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string BusinessName { get; set; }
|
public string BusinessName { get; set; }
|
||||||
public string BusinessAddress1 { get; set; }
|
public string BusinessAddress1 { get; set; }
|
||||||
|
@ -8,6 +8,7 @@ using System.Collections.Generic;
|
|||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Bit.Core.Models.Table;
|
||||||
|
|
||||||
namespace Bit.Core.Repositories.EntityFramework
|
namespace Bit.Core.Repositories.EntityFramework
|
||||||
{
|
{
|
||||||
@ -17,6 +18,17 @@ namespace Bit.Core.Repositories.EntityFramework
|
|||||||
: base(serviceScopeFactory, mapper, (DatabaseContext context) => context.Organizations)
|
: base(serviceScopeFactory, mapper, (DatabaseContext context) => context.Organizations)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
public async Task<Organization> GetByIdentifierAsync(string identifier)
|
||||||
|
{
|
||||||
|
using (var scope = ServiceScopeFactory.CreateScope())
|
||||||
|
{
|
||||||
|
var dbContext = GetDatabaseContext(scope);
|
||||||
|
var organization = await GetDbSet(dbContext).Where(e => e.Identifier == identifier)
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
|
return organization;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<ICollection<TableModel.Organization>> GetManyByEnabledAsync()
|
public async Task<ICollection<TableModel.Organization>> GetManyByEnabledAsync()
|
||||||
{
|
{
|
||||||
using (var scope = ServiceScopeFactory.CreateScope())
|
using (var scope = ServiceScopeFactory.CreateScope())
|
||||||
|
@ -8,6 +8,7 @@ namespace Bit.Core.Repositories
|
|||||||
{
|
{
|
||||||
public interface IOrganizationRepository : IRepository<Organization, Guid>
|
public interface IOrganizationRepository : IRepository<Organization, Guid>
|
||||||
{
|
{
|
||||||
|
Task<Organization> GetByIdentifierAsync(string identifier);
|
||||||
Task<ICollection<Organization>> GetManyByEnabledAsync();
|
Task<ICollection<Organization>> GetManyByEnabledAsync();
|
||||||
Task<ICollection<Organization>> GetManyByUserIdAsync(Guid userId);
|
Task<ICollection<Organization>> GetManyByUserIdAsync(Guid userId);
|
||||||
Task<ICollection<Organization>> SearchAsync(string name, string userEmail, bool? paid, int skip, int take);
|
Task<ICollection<Organization>> SearchAsync(string name, string userEmail, bool? paid, int skip, int take);
|
||||||
|
@ -20,6 +20,18 @@ namespace Bit.Core.Repositories.SqlServer
|
|||||||
: base(connectionString, readOnlyConnectionString)
|
: base(connectionString, readOnlyConnectionString)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
public async Task<Organization> GetByIdentifierAsync(string identifier)
|
||||||
|
{
|
||||||
|
using (var connection = new SqlConnection(ConnectionString))
|
||||||
|
{
|
||||||
|
var results = await connection.QueryAsync<Organization>(
|
||||||
|
"[dbo].[Organization_ReadByIdentifier]",
|
||||||
|
commandType: CommandType.StoredProcedure);
|
||||||
|
|
||||||
|
return results.SingleOrDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<ICollection<Organization>> GetManyByEnabledAsync()
|
public async Task<ICollection<Organization>> GetManyByEnabledAsync()
|
||||||
{
|
{
|
||||||
using (var connection = new SqlConnection(ConnectionString))
|
using (var connection = new SqlConnection(ConnectionString))
|
||||||
|
@ -885,6 +885,15 @@ namespace Bit.Core.Services
|
|||||||
throw new ApplicationException("Cannot create org this way. Call SignUpAsync.");
|
throw new ApplicationException("Cannot create org this way. Call SignUpAsync.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(organization.Identifier))
|
||||||
|
{
|
||||||
|
var orgById = await _organizationRepository.GetByIdentifierAsync(organization.Identifier);
|
||||||
|
if (orgById != null && orgById.Id != organization.Id)
|
||||||
|
{
|
||||||
|
throw new BadRequestException("Identifier already in use by another organization.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await ReplaceAndUpdateCache(organization, EventType.Organization_Updated);
|
await ReplaceAndUpdateCache(organization, EventType.Organization_Updated);
|
||||||
|
|
||||||
if (updateBilling && !string.IsNullOrWhiteSpace(organization.GatewayCustomerId))
|
if (updateBilling && !string.IsNullOrWhiteSpace(organization.GatewayCustomerId))
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
CREATE PROCEDURE [dbo].[Organization_ReadByIdentifier]
|
||||||
|
@Identifier UNIQUEIDENTIFIER
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SET NOCOUNT ON
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
*
|
||||||
|
FROM
|
||||||
|
[dbo].[OrganizationView]
|
||||||
|
WHERE
|
||||||
|
[Identifier] = @Identifier
|
||||||
|
END
|
20
util/Migrator/DbScripts/2020-08-12_00_OrgIdentifierProc.sql
Normal file
20
util/Migrator/DbScripts/2020-08-12_00_OrgIdentifierProc.sql
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
IF OBJECT_ID('[dbo].[Organization_ReadByIdentifier]') IS NOT NULL
|
||||||
|
BEGIN
|
||||||
|
DROP PROCEDURE [dbo].[Organization_ReadByIdentifier]
|
||||||
|
END
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE PROCEDURE [dbo].[Organization_ReadByIdentifier]
|
||||||
|
@Identifier UNIQUEIDENTIFIER
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SET NOCOUNT ON
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
*
|
||||||
|
FROM
|
||||||
|
[dbo].[OrganizationView]
|
||||||
|
WHERE
|
||||||
|
[Identifier] = @Identifier
|
||||||
|
END
|
||||||
|
GO
|
Loading…
Reference in New Issue
Block a user