mirror of
https://github.com/bitwarden/server
synced 2025-12-15 07:43:54 +00:00
[PM-22839] Add SSO configuration fields to organization user details for hiding device approvals page (#6245)
* Add SsoEnabled field to OrganizationUserOrganizationDetailsView - Updated OrganizationUserOrganizationDetailsViewQuery to include SsoEnabled property. - Modified SQL view to select SsoEnabled from SsoConfig. - Created migration script to alter the view and refresh dependent views. * Enhance OrganizationUserRepositoryTests to include SSO configuration - Added ISsoConfigRepository dependency to GetManyDetailsByUserAsync test. - Created SsoConfigurationData instance and integrated SSO configuration checks in assertions. - Updated tests to validate SSO-related properties in the response model. * Add SSO properties to ProfileOrganizationResponseModel and OrganizationUserOrganizationDetails - Introduced SsoEnabled and SsoMemberDecryptionType fields in ProfileOrganizationResponseModel. - Added SsoEnabled property to OrganizationUserOrganizationDetails for enhanced SSO configuration support.
This commit is contained in:
@@ -78,12 +78,14 @@ public class ProfileOrganizationResponseModel : ResponseModel
|
|||||||
UseRiskInsights = organization.UseRiskInsights;
|
UseRiskInsights = organization.UseRiskInsights;
|
||||||
UseOrganizationDomains = organization.UseOrganizationDomains;
|
UseOrganizationDomains = organization.UseOrganizationDomains;
|
||||||
UseAdminSponsoredFamilies = organization.UseAdminSponsoredFamilies;
|
UseAdminSponsoredFamilies = organization.UseAdminSponsoredFamilies;
|
||||||
|
SsoEnabled = organization.SsoEnabled ?? false;
|
||||||
|
|
||||||
if (organization.SsoConfig != null)
|
if (organization.SsoConfig != null)
|
||||||
{
|
{
|
||||||
var ssoConfigData = SsoConfigurationData.Deserialize(organization.SsoConfig);
|
var ssoConfigData = SsoConfigurationData.Deserialize(organization.SsoConfig);
|
||||||
KeyConnectorEnabled = ssoConfigData.MemberDecryptionType == MemberDecryptionType.KeyConnector && !string.IsNullOrEmpty(ssoConfigData.KeyConnectorUrl);
|
KeyConnectorEnabled = ssoConfigData.MemberDecryptionType == MemberDecryptionType.KeyConnector && !string.IsNullOrEmpty(ssoConfigData.KeyConnectorUrl);
|
||||||
KeyConnectorUrl = ssoConfigData.KeyConnectorUrl;
|
KeyConnectorUrl = ssoConfigData.KeyConnectorUrl;
|
||||||
|
SsoMemberDecryptionType = ssoConfigData.MemberDecryptionType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,4 +162,6 @@ public class ProfileOrganizationResponseModel : ResponseModel
|
|||||||
public bool UseOrganizationDomains { get; set; }
|
public bool UseOrganizationDomains { get; set; }
|
||||||
public bool UseAdminSponsoredFamilies { get; set; }
|
public bool UseAdminSponsoredFamilies { get; set; }
|
||||||
public bool IsAdminInitiated { get; set; }
|
public bool IsAdminInitiated { get; set; }
|
||||||
|
public bool SsoEnabled { get; set; }
|
||||||
|
public MemberDecryptionType? SsoMemberDecryptionType { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ public class OrganizationUserOrganizationDetails
|
|||||||
public string ProviderName { get; set; }
|
public string ProviderName { get; set; }
|
||||||
public ProviderType? ProviderType { get; set; }
|
public ProviderType? ProviderType { get; set; }
|
||||||
public string FamilySponsorshipFriendlyName { get; set; }
|
public string FamilySponsorshipFriendlyName { get; set; }
|
||||||
|
public bool? SsoEnabled { get; set; }
|
||||||
public string SsoConfig { get; set; }
|
public string SsoConfig { get; set; }
|
||||||
public DateTime? FamilySponsorshipLastSyncDate { get; set; }
|
public DateTime? FamilySponsorshipLastSyncDate { get; set; }
|
||||||
public DateTime? FamilySponsorshipValidUntil { get; set; }
|
public DateTime? FamilySponsorshipValidUntil { get; set; }
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ public class OrganizationUserOrganizationDetailsViewQuery : IQuery<OrganizationU
|
|||||||
ProviderId = p.Id,
|
ProviderId = p.Id,
|
||||||
ProviderName = p.Name,
|
ProviderName = p.Name,
|
||||||
ProviderType = p.Type,
|
ProviderType = p.Type,
|
||||||
|
SsoEnabled = ss.Enabled,
|
||||||
SsoConfig = ss.Data,
|
SsoConfig = ss.Data,
|
||||||
FamilySponsorshipFriendlyName = os.FriendlyName,
|
FamilySponsorshipFriendlyName = os.FriendlyName,
|
||||||
FamilySponsorshipLastSyncDate = os.LastSyncDate,
|
FamilySponsorshipLastSyncDate = os.LastSyncDate,
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ SELECT
|
|||||||
PO.[ProviderId],
|
PO.[ProviderId],
|
||||||
P.[Name] ProviderName,
|
P.[Name] ProviderName,
|
||||||
P.[Type] ProviderType,
|
P.[Type] ProviderType,
|
||||||
|
SS.[Enabled] SsoEnabled,
|
||||||
SS.[Data] SsoConfig,
|
SS.[Data] SsoConfig,
|
||||||
OS.[FriendlyName] FamilySponsorshipFriendlyName,
|
OS.[FriendlyName] FamilySponsorshipFriendlyName,
|
||||||
OS.[LastSyncDate] FamilySponsorshipLastSyncDate,
|
OS.[LastSyncDate] FamilySponsorshipLastSyncDate,
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
using Bit.Core.AdminConsole.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models;
|
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models;
|
||||||
using Bit.Core.AdminConsole.Repositories;
|
using Bit.Core.AdminConsole.Repositories;
|
||||||
|
using Bit.Core.Auth.Entities;
|
||||||
|
using Bit.Core.Auth.Enums;
|
||||||
|
using Bit.Core.Auth.Models.Data;
|
||||||
|
using Bit.Core.Auth.Repositories;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Models.Data;
|
using Bit.Core.Models.Data;
|
||||||
@@ -442,7 +446,8 @@ public class OrganizationUserRepositoryTests
|
|||||||
[DatabaseTheory, DatabaseData]
|
[DatabaseTheory, DatabaseData]
|
||||||
public async Task GetManyDetailsByUserAsync_Works(IUserRepository userRepository,
|
public async Task GetManyDetailsByUserAsync_Works(IUserRepository userRepository,
|
||||||
IOrganizationRepository organizationRepository,
|
IOrganizationRepository organizationRepository,
|
||||||
IOrganizationUserRepository organizationUserRepository)
|
IOrganizationUserRepository organizationUserRepository,
|
||||||
|
ISsoConfigRepository ssoConfigRepository)
|
||||||
{
|
{
|
||||||
var user1 = await userRepository.CreateAsync(new User
|
var user1 = await userRepository.CreateAsync(new User
|
||||||
{
|
{
|
||||||
@@ -475,6 +480,18 @@ public class OrganizationUserRepositoryTests
|
|||||||
AccessSecretsManager = false
|
AccessSecretsManager = false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var ssoConfigData = new SsoConfigurationData
|
||||||
|
{
|
||||||
|
MemberDecryptionType = MemberDecryptionType.TrustedDeviceEncryption
|
||||||
|
};
|
||||||
|
|
||||||
|
var ssoConfig = await ssoConfigRepository.CreateAsync(new SsoConfig
|
||||||
|
{
|
||||||
|
OrganizationId = organization.Id,
|
||||||
|
Enabled = true,
|
||||||
|
Data = ssoConfigData.Serialize()
|
||||||
|
});
|
||||||
|
|
||||||
var responseModel = await organizationUserRepository.GetManyDetailsByUserAsync(user1.Id);
|
var responseModel = await organizationUserRepository.GetManyDetailsByUserAsync(user1.Id);
|
||||||
|
|
||||||
Assert.NotNull(responseModel);
|
Assert.NotNull(responseModel);
|
||||||
@@ -487,6 +504,8 @@ public class OrganizationUserRepositoryTests
|
|||||||
Assert.Equal(organization.UsePolicies, result.UsePolicies);
|
Assert.Equal(organization.UsePolicies, result.UsePolicies);
|
||||||
Assert.Equal(organization.UseSso, result.UseSso);
|
Assert.Equal(organization.UseSso, result.UseSso);
|
||||||
Assert.Equal(organization.UseKeyConnector, result.UseKeyConnector);
|
Assert.Equal(organization.UseKeyConnector, result.UseKeyConnector);
|
||||||
|
Assert.Equal(ssoConfig.Enabled, result.SsoEnabled);
|
||||||
|
Assert.Equal(ssoConfig.Data, result.SsoConfig);
|
||||||
Assert.Equal(organization.UseScim, result.UseScim);
|
Assert.Equal(organization.UseScim, result.UseScim);
|
||||||
Assert.Equal(organization.UseGroups, result.UseGroups);
|
Assert.Equal(organization.UseGroups, result.UseGroups);
|
||||||
Assert.Equal(organization.UseDirectory, result.UseDirectory);
|
Assert.Equal(organization.UseDirectory, result.UseDirectory);
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
CREATE OR ALTER VIEW [dbo].[OrganizationUserOrganizationDetailsView]
|
||||||
|
AS
|
||||||
|
SELECT
|
||||||
|
OU.[UserId],
|
||||||
|
OU.[OrganizationId],
|
||||||
|
OU.[Id] OrganizationUserId,
|
||||||
|
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.[Enabled] SsoEnabled,
|
||||||
|
SS.[Data] SsoConfig,
|
||||||
|
OS.[FriendlyName] FamilySponsorshipFriendlyName,
|
||||||
|
OS.[LastSyncDate] FamilySponsorshipLastSyncDate,
|
||||||
|
OS.[ToDelete] FamilySponsorshipToDelete,
|
||||||
|
OS.[ValidUntil] FamilySponsorshipValidUntil,
|
||||||
|
OU.[AccessSecretsManager],
|
||||||
|
O.[UsePasswordManager],
|
||||||
|
O.[SmSeats],
|
||||||
|
O.[SmServiceAccounts],
|
||||||
|
O.[LimitCollectionCreation],
|
||||||
|
O.[LimitCollectionDeletion],
|
||||||
|
O.[AllowAdminAccessToAllCollectionItems],
|
||||||
|
O.[UseRiskInsights],
|
||||||
|
O.[LimitItemDeletion],
|
||||||
|
O.[UseAdminSponsoredFamilies],
|
||||||
|
O.[UseOrganizationDomains],
|
||||||
|
OS.[IsAdminInitiated]
|
||||||
|
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
|
||||||
|
|
||||||
|
--Manually refresh [dbo].[OrganizationUserOrganizationDetails_ReadByUserIdStatus]
|
||||||
|
IF OBJECT_ID('[dbo].[OrganizationUserOrganizationDetails_ReadByUserIdStatus]') IS NOT NULL
|
||||||
|
BEGIN
|
||||||
|
EXECUTE sp_refreshsqlmodule N'[dbo].[OrganizationUserOrganizationDetails_ReadByUserIdStatus]';
|
||||||
|
END
|
||||||
|
GO
|
||||||
|
|
||||||
|
--Manually refresh [dbo].[OrganizationUserOrganizationDetails_ReadByUserIdStatusOrganizationId]
|
||||||
|
IF OBJECT_ID('[dbo].[OrganizationUserOrganizationDetails_ReadByUserIdStatusOrganizationId]') IS NOT NULL
|
||||||
|
BEGIN
|
||||||
|
EXECUTE sp_refreshsqlmodule N'[dbo].[OrganizationUserOrganizationDetails_ReadByUserIdStatusOrganizationId]';
|
||||||
|
END
|
||||||
|
GO
|
||||||
Reference in New Issue
Block a user