1
0
mirror of https://github.com/bitwarden/server.git synced 2024-11-21 12:05:42 +01:00

[AC-2286] Include the OrganizationUserId for each Organization in the user sync data (#4142)

* [AC-2286] Include the OrganizationUserId for each Organization in the user sync data

* Make OrganizationUserId property non-nullable
This commit is contained in:
Rui Tomé 2024-06-07 19:32:09 +01:00 committed by GitHub
parent 36705790ad
commit 308bd555a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 164 additions and 0 deletions

View File

@ -48,6 +48,7 @@ public class ProfileOrganizationResponseModel : ResponseModel
Permissions = CoreHelpers.LoadClassFromJsonData<Permissions>(organization.Permissions);
ResetPasswordEnrolled = organization.ResetPasswordKey != null;
UserId = organization.UserId;
OrganizationUserId = organization.OrganizationUserId;
ProviderId = organization.ProviderId;
ProviderName = organization.ProviderName;
ProviderType = organization.ProviderType;
@ -138,6 +139,7 @@ public class ProfileOrganizationResponseModel : ResponseModel
public Permissions Permissions { get; set; }
public bool ResetPasswordEnrolled { get; set; }
public Guid? UserId { get; set; }
public Guid OrganizationUserId { get; set; }
public bool HasPublicAndPrivateKeys { get; set; }
public Guid? ProviderId { get; set; }
[JsonConverter(typeof(HtmlEncodingStringConverter))]

View File

@ -8,6 +8,7 @@ public class OrganizationUserOrganizationDetails
{
public Guid OrganizationId { get; set; }
public Guid? UserId { get; set; }
public Guid OrganizationUserId { get; set; }
[JsonConverter(typeof(HtmlEncodingStringConverter))]
public string Name { get; set; }
public bool UsePolicies { get; set; }

View File

@ -23,6 +23,7 @@ public class OrganizationUserOrganizationDetailsViewQuery : IQuery<OrganizationU
{
UserId = ou.UserId,
OrganizationId = ou.OrganizationId,
OrganizationUserId = ou.Id,
Name = o.Name,
Enabled = o.Enabled,
PlanType = o.PlanType,

View File

@ -3,6 +3,7 @@ AS
SELECT
OU.[UserId],
OU.[OrganizationId],
OU.[Id] OrganizationUserId,
O.[Name],
O.[Enabled],
O.[PlanType],

View File

@ -176,4 +176,82 @@ public class OrganizationUserRepositoryTests
r.ResetPasswordKey == "resetpasswordkey2" &&
r.EncryptedPrivateKey == "privatekey");
}
[DatabaseTheory, DatabaseData]
public async Task GetManyDetailsByUserAsync_Works(IUserRepository userRepository,
IOrganizationRepository organizationRepository,
IOrganizationUserRepository organizationUserRepository)
{
var user1 = await userRepository.CreateAsync(new User
{
Name = "Test User 1",
Email = $"test+{Guid.NewGuid()}@example.com",
ApiKey = "TEST",
SecurityStamp = "stamp",
Kdf = KdfType.PBKDF2_SHA256,
KdfIterations = 1,
KdfMemory = 2,
KdfParallelism = 3
});
var organization = await organizationRepository.CreateAsync(new Organization
{
Name = "Test Org",
BillingEmail = user1.Email, // TODO: EF does not enforce this being NOT NULl
Plan = "Test", // TODO: EF does not enforce this being NOT NULl
PrivateKey = "privatekey",
});
var orgUser1 = await organizationUserRepository.CreateAsync(new OrganizationUser
{
OrganizationId = organization.Id,
UserId = user1.Id,
Status = OrganizationUserStatusType.Confirmed,
ResetPasswordKey = "resetpasswordkey1",
});
var responseModel = await organizationUserRepository.GetManyDetailsByUserAsync(user1.Id);
Assert.NotNull(responseModel);
Assert.Single(responseModel);
var result = responseModel.Single();
Assert.Equal(organization.Id, result.OrganizationId);
Assert.Equal(user1.Id, result.UserId);
Assert.Equal(orgUser1.Id, result.OrganizationUserId);
Assert.Equal(organization.Name, result.Name);
Assert.Equal(organization.UsePolicies, result.UsePolicies);
Assert.Equal(organization.UseSso, result.UseSso);
Assert.Equal(organization.UseKeyConnector, result.UseKeyConnector);
Assert.Equal(organization.UseScim, result.UseScim);
Assert.Equal(organization.UseGroups, result.UseGroups);
Assert.Equal(organization.UseDirectory, result.UseDirectory);
Assert.Equal(organization.UseEvents, result.UseEvents);
Assert.Equal(organization.UseTotp, result.UseTotp);
Assert.Equal(organization.Use2fa, result.Use2fa);
Assert.Equal(organization.UseApi, result.UseApi);
Assert.Equal(organization.UseResetPassword, result.UseResetPassword);
Assert.Equal(organization.UseSecretsManager, result.UseSecretsManager);
Assert.Equal(organization.UsePasswordManager, result.UsePasswordManager);
Assert.Equal(organization.UsersGetPremium, result.UsersGetPremium);
Assert.Equal(organization.UseCustomPermissions, result.UseCustomPermissions);
Assert.Equal(organization.SelfHost, result.SelfHost);
Assert.Equal(organization.Seats, result.Seats);
Assert.Equal(organization.MaxCollections, result.MaxCollections);
Assert.Equal(organization.MaxStorageGb, result.MaxStorageGb);
Assert.Equal(organization.Identifier, result.Identifier);
Assert.Equal(orgUser1.Key, result.Key);
Assert.Equal(orgUser1.ResetPasswordKey, result.ResetPasswordKey);
Assert.Equal(organization.PublicKey, result.PublicKey);
Assert.Equal(organization.PrivateKey, result.PrivateKey);
Assert.Equal(orgUser1.Status, result.Status);
Assert.Equal(orgUser1.Type, result.Type);
Assert.Equal(organization.Enabled, result.Enabled);
Assert.Equal(organization.PlanType, result.PlanType);
Assert.Equal(orgUser1.Permissions, result.Permissions);
Assert.Equal(organization.SmSeats, result.SmSeats);
Assert.Equal(organization.SmServiceAccounts, result.SmServiceAccounts);
Assert.Equal(organization.LimitCollectionCreationDeletion, result.LimitCollectionCreationDeletion);
Assert.Equal(organization.AllowAdminAccessToAllCollectionItems, result.AllowAdminAccessToAllCollectionItems);
Assert.Equal(organization.FlexibleCollections, result.FlexibleCollections);
}
}

View File

@ -0,0 +1,81 @@
-- Add OrganizationUserId column to OrganizationUserOrganizationDetailsView
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.[Data] SsoConfig,
OS.[FriendlyName] FamilySponsorshipFriendlyName,
OS.[LastSyncDate] FamilySponsorshipLastSyncDate,
OS.[ToDelete] FamilySponsorshipToDelete,
OS.[ValidUntil] FamilySponsorshipValidUntil,
OU.[AccessSecretsManager],
O.[UsePasswordManager],
O.[SmSeats],
O.[SmServiceAccounts],
O.[LimitCollectionCreationDeletion],
O.[AllowAdminAccessToAllCollectionItems],
O.[FlexibleCollections]
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
-- Refresh modules for SPROCs reliant on 'OrganizationUserOrganizationDetailsView'.
IF OBJECT_ID('[dbo].[OrganizationUserOrganizationDetails_ReadByUserIdStatus]') IS NOT NULL
BEGIN
EXECUTE sp_refreshsqlmodule N'[dbo].[OrganizationUserOrganizationDetails_ReadByUserIdStatus]';
END
GO
IF OBJECT_ID('[dbo].[OrganizationUserOrganizationDetails_ReadByUserIdStatusOrganizationId]') IS NOT NULL
BEGIN
EXECUTE sp_refreshsqlmodule N'[dbo].[OrganizationUserOrganizationDetails_ReadByUserIdStatusOrganizationId]';
END
GO