mirror of
https://github.com/bitwarden/server.git
synced 2025-07-01 08:02:49 -05:00
[AC-434] Hide Billing screen for Reseller clients (#2783)
* [AC-434] Added ProviderType to ProfileOrganizationResponseModel * [AC-434] Migration script * [AC-434] Fixed indentation on migration script * [AC-434] Hiding sensitive subscription data if the user does not have permissions * [AC-434] Fixed missing dependency in unit test * [AC-434] Altered BillingSubscription.Amount and BillingSubscriptionUpcomingInvoice.Amount to nullable * [AC-434] Replaced CurrentContext.ManageBilling with ViewBillingHistory, ViewSubscription, EditSubscription and EditPaymentMethods * [AC-434] Reverted change on BillingSubscription.Amount and now setting Subscription.Items = null when User does not have permission * [AC-434] Added ProviderOrganizationProviderDetails_ReadByUserId * [AC-434] Added IProviderOrganizationRepository.GetManyByUserAsync * [AC-434] Added CurrentContext.GetOrganizationProviderDetails * [AC-434] Remove unneeded join Organization table
This commit is contained in:
@ -28,6 +28,7 @@ public class OrganizationsController : Controller
|
||||
private readonly IOrganizationRepository _organizationRepository;
|
||||
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||
private readonly IPolicyRepository _policyRepository;
|
||||
private readonly IProviderRepository _providerRepository;
|
||||
private readonly IOrganizationService _organizationService;
|
||||
private readonly IUserService _userService;
|
||||
private readonly IPaymentService _paymentService;
|
||||
@ -46,6 +47,7 @@ public class OrganizationsController : Controller
|
||||
IOrganizationRepository organizationRepository,
|
||||
IOrganizationUserRepository organizationUserRepository,
|
||||
IPolicyRepository policyRepository,
|
||||
IProviderRepository providerRepository,
|
||||
IOrganizationService organizationService,
|
||||
IUserService userService,
|
||||
IPaymentService paymentService,
|
||||
@ -63,6 +65,7 @@ public class OrganizationsController : Controller
|
||||
_organizationRepository = organizationRepository;
|
||||
_organizationUserRepository = organizationUserRepository;
|
||||
_policyRepository = policyRepository;
|
||||
_providerRepository = providerRepository;
|
||||
_organizationService = organizationService;
|
||||
_userService = userService;
|
||||
_paymentService = paymentService;
|
||||
@ -101,7 +104,7 @@ public class OrganizationsController : Controller
|
||||
public async Task<BillingResponseModel> GetBilling(string id)
|
||||
{
|
||||
var orgIdGuid = new Guid(id);
|
||||
if (!await _currentContext.ManageBilling(orgIdGuid))
|
||||
if (!await _currentContext.ViewBillingHistory(orgIdGuid))
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
@ -120,7 +123,7 @@ public class OrganizationsController : Controller
|
||||
public async Task<OrganizationSubscriptionResponseModel> GetSubscription(string id)
|
||||
{
|
||||
var orgIdGuid = new Guid(id);
|
||||
if (!await _currentContext.ManageBilling(orgIdGuid))
|
||||
if (!await _currentContext.ViewSubscription(orgIdGuid))
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
@ -139,7 +142,9 @@ public class OrganizationsController : Controller
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
return new OrganizationSubscriptionResponseModel(organization, subscriptionInfo);
|
||||
var hideSensitiveData = !await _currentContext.EditSubscription(orgIdGuid);
|
||||
|
||||
return new OrganizationSubscriptionResponseModel(organization, subscriptionInfo, hideSensitiveData);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -240,7 +245,7 @@ public class OrganizationsController : Controller
|
||||
model.BillingEmail != organization.BillingEmail);
|
||||
|
||||
var hasRequiredPermissions = updateBilling
|
||||
? await _currentContext.ManageBilling(orgIdGuid)
|
||||
? await _currentContext.EditSubscription(orgIdGuid)
|
||||
: await _currentContext.OrganizationOwner(orgIdGuid);
|
||||
|
||||
if (!hasRequiredPermissions)
|
||||
@ -257,7 +262,7 @@ public class OrganizationsController : Controller
|
||||
public async Task PostPayment(string id, [FromBody] PaymentRequestModel model)
|
||||
{
|
||||
var orgIdGuid = new Guid(id);
|
||||
if (!await _currentContext.ManageBilling(orgIdGuid))
|
||||
if (!await _currentContext.EditPaymentMethods(orgIdGuid))
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
@ -280,7 +285,7 @@ public class OrganizationsController : Controller
|
||||
public async Task<PaymentResponseModel> PostUpgrade(string id, [FromBody] OrganizationUpgradeRequestModel model)
|
||||
{
|
||||
var orgIdGuid = new Guid(id);
|
||||
if (!await _currentContext.ManageBilling(orgIdGuid))
|
||||
if (!await _currentContext.EditSubscription(orgIdGuid))
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
@ -294,7 +299,7 @@ public class OrganizationsController : Controller
|
||||
public async Task PostSubscription(string id, [FromBody] OrganizationSubscriptionUpdateRequestModel model)
|
||||
{
|
||||
var orgIdGuid = new Guid(id);
|
||||
if (!await _currentContext.ManageBilling(orgIdGuid))
|
||||
if (!await _currentContext.EditSubscription(orgIdGuid))
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
@ -307,7 +312,7 @@ public class OrganizationsController : Controller
|
||||
public async Task<PaymentResponseModel> PostSeat(string id, [FromBody] OrganizationSeatRequestModel model)
|
||||
{
|
||||
var orgIdGuid = new Guid(id);
|
||||
if (!await _currentContext.ManageBilling(orgIdGuid))
|
||||
if (!await _currentContext.EditSubscription(orgIdGuid))
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
@ -321,7 +326,7 @@ public class OrganizationsController : Controller
|
||||
public async Task<PaymentResponseModel> PostStorage(string id, [FromBody] StorageRequestModel model)
|
||||
{
|
||||
var orgIdGuid = new Guid(id);
|
||||
if (!await _currentContext.ManageBilling(orgIdGuid))
|
||||
if (!await _currentContext.EditSubscription(orgIdGuid))
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
@ -335,7 +340,7 @@ public class OrganizationsController : Controller
|
||||
public async Task PostVerifyBank(string id, [FromBody] OrganizationVerifyBankRequestModel model)
|
||||
{
|
||||
var orgIdGuid = new Guid(id);
|
||||
if (!await _currentContext.ManageBilling(orgIdGuid))
|
||||
if (!await _currentContext.EditSubscription(orgIdGuid))
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
@ -348,7 +353,7 @@ public class OrganizationsController : Controller
|
||||
public async Task PostCancel(string id)
|
||||
{
|
||||
var orgIdGuid = new Guid(id);
|
||||
if (!await _currentContext.ManageBilling(orgIdGuid))
|
||||
if (!await _currentContext.EditSubscription(orgIdGuid))
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
@ -361,7 +366,7 @@ public class OrganizationsController : Controller
|
||||
public async Task PostReinstate(string id)
|
||||
{
|
||||
var orgIdGuid = new Guid(id);
|
||||
if (!await _currentContext.ManageBilling(orgIdGuid))
|
||||
if (!await _currentContext.EditSubscription(orgIdGuid))
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
@ -84,28 +84,30 @@ public class OrganizationResponseModel : ResponseModel
|
||||
|
||||
public class OrganizationSubscriptionResponseModel : OrganizationResponseModel
|
||||
{
|
||||
public OrganizationSubscriptionResponseModel(Organization organization, SubscriptionInfo subscription = null)
|
||||
: base(organization, "organizationSubscription")
|
||||
public OrganizationSubscriptionResponseModel(Organization organization) : base(organization, "organizationSubscription")
|
||||
{
|
||||
if (subscription != null)
|
||||
{
|
||||
Subscription = subscription.Subscription != null ?
|
||||
new BillingSubscription(subscription.Subscription) : null;
|
||||
UpcomingInvoice = subscription.UpcomingInvoice != null ?
|
||||
new BillingSubscriptionUpcomingInvoice(subscription.UpcomingInvoice) : null;
|
||||
Expiration = DateTime.UtcNow.AddYears(1); // Not used, so just give it a value.
|
||||
}
|
||||
else
|
||||
{
|
||||
Expiration = organization.ExpirationDate;
|
||||
}
|
||||
|
||||
Expiration = organization.ExpirationDate;
|
||||
StorageName = organization.Storage.HasValue ?
|
||||
CoreHelpers.ReadableBytesSize(organization.Storage.Value) : null;
|
||||
StorageGb = organization.Storage.HasValue ?
|
||||
Math.Round(organization.Storage.Value / 1073741824D, 2) : 0; // 1 GB
|
||||
}
|
||||
|
||||
public OrganizationSubscriptionResponseModel(Organization organization, SubscriptionInfo subscription, bool hideSensitiveData)
|
||||
: this(organization)
|
||||
{
|
||||
Subscription = subscription.Subscription != null ? new BillingSubscription(subscription.Subscription) : null;
|
||||
UpcomingInvoice = subscription.UpcomingInvoice != null ? new BillingSubscriptionUpcomingInvoice(subscription.UpcomingInvoice) : null;
|
||||
Expiration = DateTime.UtcNow.AddYears(1); // Not used, so just give it a value.
|
||||
|
||||
if (hideSensitiveData)
|
||||
{
|
||||
BillingEmail = null;
|
||||
Subscription.Items = null;
|
||||
UpcomingInvoice.Amount = null;
|
||||
}
|
||||
}
|
||||
|
||||
public string StorageName { get; set; }
|
||||
public double? StorageGb { get; set; }
|
||||
public BillingSubscription Subscription { get; set; }
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Enums.Provider;
|
||||
using Bit.Core.Models.Api;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
@ -46,6 +47,7 @@ public class ProfileOrganizationResponseModel : ResponseModel
|
||||
UserId = organization.UserId?.ToString();
|
||||
ProviderId = organization.ProviderId?.ToString();
|
||||
ProviderName = organization.ProviderName;
|
||||
ProviderType = organization.ProviderType;
|
||||
FamilySponsorshipFriendlyName = organization.FamilySponsorshipFriendlyName;
|
||||
FamilySponsorshipAvailable = FamilySponsorshipFriendlyName == null &&
|
||||
StaticStore.GetSponsoredPlan(PlanSponsorshipType.FamiliesForEnterprise)
|
||||
@ -97,6 +99,7 @@ public class ProfileOrganizationResponseModel : ResponseModel
|
||||
public bool HasPublicAndPrivateKeys { get; set; }
|
||||
public string ProviderId { get; set; }
|
||||
public string ProviderName { get; set; }
|
||||
public ProviderType? ProviderType { get; set; }
|
||||
public string FamilySponsorshipFriendlyName { get; set; }
|
||||
public bool FamilySponsorshipAvailable { get; set; }
|
||||
public ProductType PlanProductType { get; set; }
|
||||
|
@ -100,6 +100,6 @@ public class BillingSubscriptionUpcomingInvoice
|
||||
Date = inv.Date;
|
||||
}
|
||||
|
||||
public decimal Amount { get; set; }
|
||||
public decimal? Amount { get; set; }
|
||||
public DateTime? Date { get; set; }
|
||||
}
|
||||
|
@ -13,9 +13,11 @@ namespace Bit.Core.Context;
|
||||
|
||||
public class CurrentContext : ICurrentContext
|
||||
{
|
||||
private readonly IProviderOrganizationRepository _providerOrganizationRepository;
|
||||
private readonly IProviderUserRepository _providerUserRepository;
|
||||
private bool _builtHttpContext;
|
||||
private bool _builtClaimsPrincipal;
|
||||
private IEnumerable<ProviderOrganizationProviderDetails> _providerOrganizationProviderDetails;
|
||||
private IEnumerable<ProviderUserOrganizationDetails> _providerUserOrganizations;
|
||||
|
||||
public virtual HttpContext HttpContext { get; set; }
|
||||
@ -37,8 +39,11 @@ public class CurrentContext : ICurrentContext
|
||||
public virtual ClientType ClientType { get; set; }
|
||||
public virtual Guid? ServiceAccountOrganizationId { get; set; }
|
||||
|
||||
public CurrentContext(IProviderUserRepository providerUserRepository)
|
||||
public CurrentContext(
|
||||
IProviderOrganizationRepository providerOrganizationRepository,
|
||||
IProviderUserRepository providerUserRepository)
|
||||
{
|
||||
_providerOrganizationRepository = providerOrganizationRepository;
|
||||
_providerUserRepository = providerUserRepository;
|
||||
}
|
||||
|
||||
@ -392,15 +397,34 @@ public class CurrentContext : ICurrentContext
|
||||
&& (o.Permissions?.ManageResetPassword ?? false)) ?? false);
|
||||
}
|
||||
|
||||
public async Task<bool> ManageBilling(Guid orgId)
|
||||
public async Task<bool> ViewSubscription(Guid orgId)
|
||||
{
|
||||
var orgManagedByProvider = await ProviderIdForOrg(orgId) != null;
|
||||
var orgManagedByMspProvider = (await GetOrganizationProviderDetails()).Any(po => po.OrganizationId == orgId && po.ProviderType == ProviderType.Msp);
|
||||
|
||||
return orgManagedByMspProvider
|
||||
? await ProviderUserForOrgAsync(orgId)
|
||||
: await OrganizationOwner(orgId);
|
||||
}
|
||||
|
||||
public async Task<bool> EditSubscription(Guid orgId)
|
||||
{
|
||||
var orgManagedByProvider = (await GetOrganizationProviderDetails()).Any(po => po.OrganizationId == orgId);
|
||||
|
||||
return orgManagedByProvider
|
||||
? await ProviderUserForOrgAsync(orgId)
|
||||
: await OrganizationOwner(orgId);
|
||||
}
|
||||
|
||||
public async Task<bool> EditPaymentMethods(Guid orgId)
|
||||
{
|
||||
return await EditSubscription(orgId);
|
||||
}
|
||||
|
||||
public async Task<bool> ViewBillingHistory(Guid orgId)
|
||||
{
|
||||
return await EditSubscription(orgId);
|
||||
}
|
||||
|
||||
public bool ProviderProviderAdmin(Guid providerId)
|
||||
{
|
||||
return Providers?.Any(o => o.Id == providerId && o.Type == ProviderUserType.ProviderAdmin) ?? false;
|
||||
@ -433,7 +457,7 @@ public class CurrentContext : ICurrentContext
|
||||
|
||||
public async Task<bool> ProviderUserForOrgAsync(Guid orgId)
|
||||
{
|
||||
return (await GetProviderOrganizations()).Any(po => po.OrganizationId == orgId);
|
||||
return (await GetProviderUserOrganizations()).Any(po => po.OrganizationId == orgId);
|
||||
}
|
||||
|
||||
public async Task<Guid?> ProviderIdForOrg(Guid orgId)
|
||||
@ -443,7 +467,7 @@ public class CurrentContext : ICurrentContext
|
||||
return null;
|
||||
}
|
||||
|
||||
var po = (await GetProviderOrganizations())
|
||||
var po = (await GetProviderUserOrganizations())
|
||||
?.FirstOrDefault(po => po.OrganizationId == orgId);
|
||||
|
||||
return po?.ProviderId;
|
||||
@ -520,7 +544,7 @@ public class CurrentContext : ICurrentContext
|
||||
};
|
||||
}
|
||||
|
||||
protected async Task<IEnumerable<ProviderUserOrganizationDetails>> GetProviderOrganizations()
|
||||
protected async Task<IEnumerable<ProviderUserOrganizationDetails>> GetProviderUserOrganizations()
|
||||
{
|
||||
if (_providerUserOrganizations == null && UserId.HasValue)
|
||||
{
|
||||
@ -529,4 +553,14 @@ public class CurrentContext : ICurrentContext
|
||||
|
||||
return _providerUserOrganizations;
|
||||
}
|
||||
|
||||
protected async Task<IEnumerable<ProviderOrganizationProviderDetails>> GetOrganizationProviderDetails()
|
||||
{
|
||||
if (_providerOrganizationProviderDetails == null && UserId.HasValue)
|
||||
{
|
||||
_providerOrganizationProviderDetails = await _providerOrganizationRepository.GetManyByUserAsync(UserId.Value);
|
||||
}
|
||||
|
||||
return _providerOrganizationProviderDetails;
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,10 @@ public interface ICurrentContext
|
||||
Task<bool> ManageUsers(Guid orgId);
|
||||
Task<bool> ManageScim(Guid orgId);
|
||||
Task<bool> ManageResetPassword(Guid orgId);
|
||||
Task<bool> ManageBilling(Guid orgId);
|
||||
Task<bool> ViewSubscription(Guid orgId);
|
||||
Task<bool> EditSubscription(Guid orgId);
|
||||
Task<bool> EditPaymentMethods(Guid orgId);
|
||||
Task<bool> ViewBillingHistory(Guid orgId);
|
||||
Task<bool> ProviderUserForOrgAsync(Guid orgId);
|
||||
bool ProviderProviderAdmin(Guid providerId);
|
||||
bool ProviderUser(Guid providerId);
|
||||
|
@ -1,4 +1,6 @@
|
||||
namespace Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
using Bit.Core.Enums.Provider;
|
||||
|
||||
namespace Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
|
||||
public class OrganizationUserOrganizationDetails
|
||||
{
|
||||
@ -36,6 +38,7 @@ public class OrganizationUserOrganizationDetails
|
||||
public string PrivateKey { get; set; }
|
||||
public Guid? ProviderId { get; set; }
|
||||
public string ProviderName { get; set; }
|
||||
public ProviderType? ProviderType { get; set; }
|
||||
public string FamilySponsorshipFriendlyName { get; set; }
|
||||
public string SsoConfig { get; set; }
|
||||
public DateTime? FamilySponsorshipLastSyncDate { get; set; }
|
||||
|
@ -0,0 +1,12 @@
|
||||
using Bit.Core.Enums.Provider;
|
||||
|
||||
namespace Bit.Core.Models.Data;
|
||||
|
||||
public class ProviderOrganizationProviderDetails
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid ProviderId { get; set; }
|
||||
public Guid OrganizationId { get; set; }
|
||||
public string ProviderName { get; set; }
|
||||
public ProviderType ProviderType { get; set; }
|
||||
}
|
@ -8,4 +8,5 @@ public interface IProviderOrganizationRepository : IRepository<ProviderOrganizat
|
||||
Task<ICollection<ProviderOrganization>> CreateManyAsync(IEnumerable<ProviderOrganization> providerOrganizations);
|
||||
Task<ICollection<ProviderOrganizationOrganizationDetails>> GetManyDetailsByProviderAsync(Guid providerId);
|
||||
Task<ProviderOrganization> GetByOrganizationId(Guid organizationId);
|
||||
Task<IEnumerable<ProviderOrganizationProviderDetails>> GetManyByUserAsync(Guid userId);
|
||||
}
|
||||
|
@ -86,6 +86,19 @@ public class ProviderOrganizationRepository : Repository<ProviderOrganization, G
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ProviderOrganizationProviderDetails>> GetManyByUserAsync(Guid userId)
|
||||
{
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
var results = await connection.QueryAsync<ProviderOrganizationProviderDetails>(
|
||||
"[dbo].[ProviderOrganizationProviderDetails_ReadByUserId]",
|
||||
new { UserId = userId },
|
||||
commandType: CommandType.StoredProcedure);
|
||||
|
||||
return results.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
private DataTable BuildProviderOrganizationsTable(SqlBulkCopy bulkCopy, IEnumerable<ProviderOrganization> providerOrganizations)
|
||||
{
|
||||
var po = providerOrganizations.FirstOrDefault();
|
||||
|
@ -56,4 +56,15 @@ public class ProviderOrganizationRepository :
|
||||
var dbContext = GetDatabaseContext(scope);
|
||||
return await GetDbSet(dbContext).Where(po => po.OrganizationId == organizationId).FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ProviderOrganizationProviderDetails>> GetManyByUserAsync(Guid userId)
|
||||
{
|
||||
using (var scope = ServiceScopeFactory.CreateScope())
|
||||
{
|
||||
var dbContext = GetDatabaseContext(scope);
|
||||
var query = new ProviderOrganizationReadByUserIdQuery(userId);
|
||||
var data = await query.Run(dbContext).ToListAsync();
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ public class OrganizationUserOrganizationDetailsViewQuery : IQuery<OrganizationU
|
||||
Permissions = ou.Permissions,
|
||||
ProviderId = p.Id,
|
||||
ProviderName = p.Name,
|
||||
ProviderType = p.Type,
|
||||
SsoConfig = ss.Data,
|
||||
FamilySponsorshipFriendlyName = os.FriendlyName,
|
||||
FamilySponsorshipLastSyncDate = os.LastSyncDate,
|
||||
|
@ -0,0 +1,32 @@
|
||||
using Bit.Core.Models.Data;
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Repositories.Queries;
|
||||
|
||||
public class ProviderOrganizationReadByUserIdQuery : IQuery<ProviderOrganizationProviderDetails>
|
||||
{
|
||||
private readonly Guid _userId;
|
||||
|
||||
public ProviderOrganizationReadByUserIdQuery(Guid userId)
|
||||
{
|
||||
_userId = userId;
|
||||
}
|
||||
|
||||
public IQueryable<ProviderOrganizationProviderDetails> Run(DatabaseContext dbContext)
|
||||
{
|
||||
var query = from po in dbContext.ProviderOrganizations
|
||||
join ou in dbContext.OrganizationUsers
|
||||
on po.OrganizationId equals ou.OrganizationId
|
||||
join p in dbContext.Providers
|
||||
on po.ProviderId equals p.Id
|
||||
where ou.UserId == _userId
|
||||
select new ProviderOrganizationProviderDetails
|
||||
{
|
||||
Id = po.Id,
|
||||
OrganizationId = po.OrganizationId,
|
||||
ProviderId = po.ProviderId,
|
||||
ProviderName = p.Name,
|
||||
ProviderType = p.Type
|
||||
};
|
||||
return query;
|
||||
}
|
||||
}
|
@ -18,7 +18,7 @@ public class NotificationsHub : Microsoft.AspNetCore.SignalR.Hub
|
||||
|
||||
public override async Task OnConnectedAsync()
|
||||
{
|
||||
var currentContext = new CurrentContext(null);
|
||||
var currentContext = new CurrentContext(null, null);
|
||||
await currentContext.BuildAsync(Context.User, _globalSettings);
|
||||
if (currentContext.Organizations != null)
|
||||
{
|
||||
@ -33,7 +33,7 @@ public class NotificationsHub : Microsoft.AspNetCore.SignalR.Hub
|
||||
|
||||
public override async Task OnDisconnectedAsync(Exception exception)
|
||||
{
|
||||
var currentContext = new CurrentContext(null);
|
||||
var currentContext = new CurrentContext(null, null);
|
||||
await currentContext.BuildAsync(Context.User, _globalSettings);
|
||||
if (currentContext.Organizations != null)
|
||||
{
|
||||
|
@ -263,6 +263,7 @@
|
||||
<Build Include="dbo\Stored Procedures\Policy_ReadByUserId.sql" />
|
||||
<Build Include="dbo\Stored Procedures\Policy_Update.sql" />
|
||||
<Build Include="dbo\Stored Procedures\ProviderOrganizationOrganizationDetails_ReadByProviderId.sql" />
|
||||
<Build Include="dbo\Stored Procedures\ProviderOrganizationProviderDetails_ReadByUserId.sql" />
|
||||
<Build Include="dbo\Stored Procedures\Provider_ReadByOrganizationId.sql" />
|
||||
<Build Include="dbo\Stored Procedures\Organization_UnassignedToProviderSearch.sql" />
|
||||
<Build Include="dbo\Stored Procedures\ProviderOrganization_Create.sql" />
|
||||
|
@ -0,0 +1,21 @@
|
||||
CREATE PROCEDURE [dbo].[ProviderOrganizationProviderDetails_ReadByUserId]
|
||||
@UserId UNIQUEIDENTIFIER
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
|
||||
SELECT
|
||||
PO.Id,
|
||||
PO.OrganizationId,
|
||||
PO.ProviderId,
|
||||
P.Name as ProviderName,
|
||||
P.[Type] as ProviderType
|
||||
FROM
|
||||
[dbo].[ProviderOrganizationView] PO
|
||||
INNER JOIN
|
||||
[dbo].[OrganizationUser] OU ON PO.OrganizationId = OU.OrganizationId
|
||||
INNER JOIN
|
||||
[dbo].[Provider] P ON PO.ProviderId = P.Id
|
||||
WHERE
|
||||
OU.UserId = @UserId
|
||||
END
|
@ -35,6 +35,7 @@ SELECT
|
||||
OU.[Permissions],
|
||||
PO.[ProviderId],
|
||||
P.[Name] ProviderName,
|
||||
P.[Type] ProviderType,
|
||||
SS.[Data] SsoConfig,
|
||||
OS.[FriendlyName] FamilySponsorshipFriendlyName,
|
||||
OS.[LastSyncDate] FamilySponsorshipLastSyncDate,
|
||||
|
@ -24,6 +24,7 @@ public class OrganizationsControllerTests : IDisposable
|
||||
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||
private readonly IPaymentService _paymentService;
|
||||
private readonly IPolicyRepository _policyRepository;
|
||||
private readonly IProviderRepository _providerRepository;
|
||||
private readonly ISsoConfigRepository _ssoConfigRepository;
|
||||
private readonly ISsoConfigService _ssoConfigService;
|
||||
private readonly IUserService _userService;
|
||||
@ -46,6 +47,7 @@ public class OrganizationsControllerTests : IDisposable
|
||||
_organizationUserRepository = Substitute.For<IOrganizationUserRepository>();
|
||||
_paymentService = Substitute.For<IPaymentService>();
|
||||
_policyRepository = Substitute.For<IPolicyRepository>();
|
||||
_providerRepository = Substitute.For<IProviderRepository>();
|
||||
_ssoConfigRepository = Substitute.For<ISsoConfigRepository>();
|
||||
_ssoConfigService = Substitute.For<ISsoConfigService>();
|
||||
_getOrganizationApiKeyQuery = Substitute.For<IGetOrganizationApiKeyQuery>();
|
||||
@ -57,7 +59,7 @@ public class OrganizationsControllerTests : IDisposable
|
||||
_updateOrganizationLicenseCommand = Substitute.For<IUpdateOrganizationLicenseCommand>();
|
||||
|
||||
_sut = new OrganizationsController(_organizationRepository, _organizationUserRepository,
|
||||
_policyRepository, _organizationService, _userService, _paymentService, _currentContext,
|
||||
_policyRepository, _providerRepository, _organizationService, _userService, _paymentService, _currentContext,
|
||||
_ssoConfigRepository, _ssoConfigService, _getOrganizationApiKeyQuery, _rotateOrganizationApiKeyCommand,
|
||||
_createOrganizationApiKeyCommand, _organizationApiKeyRepository, _updateOrganizationLicenseCommand,
|
||||
_cloudGetOrganizationLicenseQuery, _globalSettings);
|
||||
|
@ -0,0 +1,82 @@
|
||||
CREATE OR ALTER VIEW [dbo].[OrganizationUserOrganizationDetailsView]
|
||||
AS
|
||||
SELECT
|
||||
OU.[UserId],
|
||||
OU.[OrganizationId],
|
||||
O.[Name],
|
||||
O.[Enabled],
|
||||
O.[PlanType],
|
||||
O.[UsePolicies],
|
||||
O.[UseSso],
|
||||
O.[UseKeyConnector],
|
||||
O.[UseScim],
|
||||
O.[UseGroups],
|
||||
O.[UseDirectory],
|
||||
O.[UseEvents],
|
||||
O.[UseTotp],
|
||||
O.[Use2fa],
|
||||
O.[UseApi],
|
||||
O.[UseResetPassword],
|
||||
O.[SelfHost],
|
||||
O.[UsersGetPremium],
|
||||
O.[UseCustomPermissions],
|
||||
O.[UseSecretsManager],
|
||||
O.[Seats],
|
||||
O.[MaxCollections],
|
||||
O.[MaxStorageGb],
|
||||
O.[Identifier],
|
||||
OU.[Key],
|
||||
OU.[ResetPasswordKey],
|
||||
O.[PublicKey],
|
||||
O.[PrivateKey],
|
||||
OU.[Status],
|
||||
OU.[Type],
|
||||
SU.[ExternalId] SsoExternalId,
|
||||
OU.[Permissions],
|
||||
PO.[ProviderId],
|
||||
P.[Name] ProviderName,
|
||||
P.[Type] ProviderType,
|
||||
SS.[Data] SsoConfig,
|
||||
OS.[FriendlyName] FamilySponsorshipFriendlyName,
|
||||
OS.[LastSyncDate] FamilySponsorshipLastSyncDate,
|
||||
OS.[ToDelete] FamilySponsorshipToDelete,
|
||||
OS.[ValidUntil] FamilySponsorshipValidUntil,
|
||||
OU.[AccessSecretsManager]
|
||||
FROM
|
||||
[dbo].[OrganizationUser] OU
|
||||
LEFT JOIN
|
||||
[dbo].[Organization] O ON O.[Id] = OU.[OrganizationId]
|
||||
LEFT JOIN
|
||||
[dbo].[SsoUser] SU ON SU.[UserId] = OU.[UserId] AND SU.[OrganizationId] = OU.[OrganizationId]
|
||||
LEFT JOIN
|
||||
[dbo].[ProviderOrganization] PO ON PO.[OrganizationId] = O.[Id]
|
||||
LEFT JOIN
|
||||
[dbo].[Provider] P ON P.[Id] = PO.[ProviderId]
|
||||
LEFT JOIN
|
||||
[dbo].[SsoConfig] SS ON SS.[OrganizationId] = OU.[OrganizationId]
|
||||
LEFT JOIN
|
||||
[dbo].[OrganizationSponsorship] OS ON OS.[SponsoringOrganizationUserID] = OU.[Id]
|
||||
GO
|
||||
|
||||
CREATE OR ALTER PROCEDURE [dbo].[ProviderOrganizationProviderDetails_ReadByUserId]
|
||||
@UserId UNIQUEIDENTIFIER
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
|
||||
SELECT
|
||||
PO.Id,
|
||||
PO.OrganizationId,
|
||||
PO.ProviderId,
|
||||
P.Name as ProviderName,
|
||||
P.[Type] as ProviderType
|
||||
FROM
|
||||
[dbo].[ProviderOrganizationView] PO
|
||||
INNER JOIN
|
||||
[dbo].[OrganizationUser] OU ON PO.OrganizationId = OU.OrganizationId
|
||||
INNER JOIN
|
||||
[dbo].[Provider] P ON PO.ProviderId = P.Id
|
||||
WHERE
|
||||
OU.UserId = @UserId
|
||||
END
|
||||
GO
|
Reference in New Issue
Block a user