Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public interface IOrganizationUserRepository : IRepository<OrganizationUser, Gui
Task<ICollection<OrganizationUserUserDetails>> GetManyDetailsByOrganizationAsync_vNext(Guid organizationId, bool includeGroups = false, bool includeSharedCollections = false);
Task<ICollection<OrganizationUserOrganizationDetails>> GetManyDetailsByUserAsync(Guid userId,
OrganizationUserStatusType? status = null);
Task<ICollection<OrganizationUserOrganizationDetails>> GetManyConfirmedAcceptedDetailsByUserAsync(Guid userId);
Task<OrganizationUserOrganizationDetails?> GetDetailsByUserAsync(Guid userId, Guid organizationId,
OrganizationUserStatusType? status = null);
Task UpdateGroupsAsync(Guid orgUserId, IEnumerable<Guid> groupIds);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,19 @@ public async Task<ICollection<OrganizationUserOrganizationDetails>> GetManyDetai
}
}

public async Task<ICollection<OrganizationUserOrganizationDetails>> GetManyConfirmedAcceptedDetailsByUserAsync(Guid userId)
{
using (var connection = new SqlConnection(ConnectionString))
{
var results = await connection.QueryAsync<OrganizationUserOrganizationDetails>(
"[dbo].[OrganizationUserOrganizationDetails_ReadAcceptedConfirmedByUserId]",
new { UserId = userId },
commandType: CommandType.StoredProcedure);

return results.ToList();
}
}

public async Task<OrganizationUserOrganizationDetails?> GetDetailsByUserAsync(Guid userId,
Guid organizationId, OrganizationUserStatusType? status = null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,6 @@ public async Task<OrganizationUserOrganizationDetails> GetDetailsByUserAsync(Gui
{
var dbContext = GetDatabaseContext(scope);
var view = new OrganizationUserOrganizationDetailsViewQuery();
var t = await (view.Run(dbContext)).ToArrayAsync();
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn’t related to my PR, but it’s dead code and not being used. It was introduced about five years ago. Since AC owns this code now, I think we should remove it.

var entity = await view.Run(dbContext)
.FirstOrDefaultAsync(o => o.UserId == userId &&
o.OrganizationId == organizationId &&
Expand Down Expand Up @@ -574,6 +573,22 @@ public async Task<ICollection<OrganizationUserOrganizationDetails>> GetManyDetai
}
}

public async Task<ICollection<OrganizationUserOrganizationDetails>> GetManyConfirmedAcceptedDetailsByUserAsync(Guid userId)
{
using (var scope = ServiceScopeFactory.CreateScope())
{
var dbContext = GetDatabaseContext(scope);
var view = new OrganizationUserOrganizationDetailsViewQuery();
var query = from organizationUserDetails in view.Run(dbContext)
where organizationUserDetails.UserId == userId &&
(organizationUserDetails.Status == OrganizationUserStatusType.Confirmed ||
organizationUserDetails.Status == OrganizationUserStatusType.Accepted)
select organizationUserDetails;
var organizationUsers = await query.ToListAsync();
return organizationUsers;
}
}

public async Task<IEnumerable<OrganizationUserPublicKey>> GetManyPublicKeysByOrganizationUserAsync(Guid organizationId, IEnumerable<Guid> Ids)
{
using (var scope = ServiceScopeFactory.CreateScope())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
CREATE PROCEDURE [dbo].[OrganizationUserOrganizationDetails_ReadAcceptedConfirmedByUserId]
@UserId UNIQUEIDENTIFIER
AS
BEGIN
SET NOCOUNT ON

SELECT
*
FROM
[dbo].[OrganizationUserOrganizationDetailsView]
WHERE
[UserId] = @UserId
AND [Status] IN (1, 2) -- Accepted = 1, Confirmed = 2
END
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
ο»Ώusing Bit.Core.Enums;
using Bit.Core.Repositories;
using Xunit;

namespace Bit.Infrastructure.IntegrationTest.AdminConsole.Repositories.OrganizationUserRepository;

public class GetManyConfirmedAcceptedDetailsByUserAsyncTests
{
[Theory, DatabaseData]
public async Task ReturnsDetails_WhenUserIsConfirmed(
IUserRepository userRepository,
IOrganizationRepository organizationRepository,
IOrganizationUserRepository organizationUserRepository)
{
// Arrange
var user = await userRepository.CreateTestUserAsync();
var organization = await organizationRepository.CreateTestOrganizationAsync();
await organizationUserRepository.CreateConfirmedTestOrganizationUserAsync(organization, user);

// Act
var results = await organizationUserRepository.GetManyConfirmedAcceptedDetailsByUserAsync(user.Id);

// Assert
Assert.Single(results);
var result = results.Single();
Assert.Equal(organization.Id, result.OrganizationId);
Assert.Equal(user.Id, result.UserId);
Assert.Equal(OrganizationUserStatusType.Confirmed, result.Status);

// Annul
await organizationRepository.DeleteAsync(organization);
await userRepository.DeleteAsync(user);
}

[Theory, DatabaseData]
public async Task ReturnsDetails_WhenUserIsAccepted(
IUserRepository userRepository,
IOrganizationRepository organizationRepository,
IOrganizationUserRepository organizationUserRepository)
{
// Arrange
var user = await userRepository.CreateTestUserAsync();
var organization = await organizationRepository.CreateTestOrganizationAsync();
await organizationUserRepository.CreateAcceptedTestOrganizationUserAsync(organization, user);

// Act
var results = await organizationUserRepository.GetManyConfirmedAcceptedDetailsByUserAsync(user.Id);

// Assert
Assert.Single(results);
var result = results.Single();
Assert.Equal(organization.Id, result.OrganizationId);
Assert.Equal(user.Id, result.UserId);
Assert.Equal(OrganizationUserStatusType.Accepted, result.Status);

// Annul
await organizationRepository.DeleteAsync(organization);
await userRepository.DeleteAsync(user);
}

[Theory, DatabaseData]
public async Task ReturnsDetailsAcrossMultipleOrganizations_WhenUserIsConfirmedOrAccepted(
IUserRepository userRepository,
IOrganizationRepository organizationRepository,
IOrganizationUserRepository organizationUserRepository)
{
// Arrange
var user = await userRepository.CreateTestUserAsync();

var confirmedOrg = await organizationRepository.CreateTestOrganizationAsync();
await organizationUserRepository.CreateConfirmedTestOrganizationUserAsync(confirmedOrg, user);

var acceptedOrg = await organizationRepository.CreateTestOrganizationAsync();
await organizationUserRepository.CreateAcceptedTestOrganizationUserAsync(acceptedOrg, user);

// Act
var results = await organizationUserRepository.GetManyConfirmedAcceptedDetailsByUserAsync(user.Id);

// Assert
Assert.Equal(2, results.Count);
Assert.Contains(results, r => r.OrganizationId == confirmedOrg.Id && r.Status == OrganizationUserStatusType.Confirmed);
Assert.Contains(results, r => r.OrganizationId == acceptedOrg.Id && r.Status == OrganizationUserStatusType.Accepted);

// Annul
await organizationRepository.DeleteAsync(confirmedOrg);
await organizationRepository.DeleteAsync(acceptedOrg);
await userRepository.DeleteAsync(user);
}

[Theory, DatabaseData]
public async Task DoesNotReturnDetails_WhenUserIsInvited(
IUserRepository userRepository,
IOrganizationRepository organizationRepository,
IOrganizationUserRepository organizationUserRepository)
{
// Arrange
var user = await userRepository.CreateTestUserAsync();
var organization = await organizationRepository.CreateTestOrganizationAsync();
await organizationUserRepository.CreateTestOrganizationUserInviteAsync(organization);

// Act
var results = await organizationUserRepository.GetManyConfirmedAcceptedDetailsByUserAsync(user.Id);

// Assert
Assert.DoesNotContain(results, r => r.OrganizationId == organization.Id);

// Annul
await organizationRepository.DeleteAsync(organization);
await userRepository.DeleteAsync(user);
}

[Theory, DatabaseData]
public async Task DoesNotReturnDetails_WhenUserIsRevoked(
IUserRepository userRepository,
IOrganizationRepository organizationRepository,
IOrganizationUserRepository organizationUserRepository)
{
// Arrange
var user = await userRepository.CreateTestUserAsync();
var organization = await organizationRepository.CreateTestOrganizationAsync();
await organizationUserRepository.CreateRevokedTestOrganizationUserAsync(organization, user);

// Act
var results = await organizationUserRepository.GetManyConfirmedAcceptedDetailsByUserAsync(user.Id);

// Assert
Assert.DoesNotContain(results, r => r.OrganizationId == organization.Id);

// Annul
await organizationRepository.DeleteAsync(organization);
await userRepository.DeleteAsync(user);
}

[Theory, DatabaseData]
public async Task DoesNotReturnDetails_ForOtherUsers(
IUserRepository userRepository,
IOrganizationRepository organizationRepository,
IOrganizationUserRepository organizationUserRepository)
{
// Arrange
var targetUser = await userRepository.CreateTestUserAsync();
var otherUser = await userRepository.CreateTestUserAsync();

var organization = await organizationRepository.CreateTestOrganizationAsync();
await organizationUserRepository.CreateConfirmedTestOrganizationUserAsync(organization, otherUser);

// Act
var results = await organizationUserRepository.GetManyConfirmedAcceptedDetailsByUserAsync(targetUser.Id);

// Assert
Assert.DoesNotContain(results, r => r.OrganizationId == organization.Id);

// Annul
await organizationRepository.DeleteAsync(organization);
await userRepository.DeleteManyAsync([targetUser, otherUser]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
CREATE OR ALTER PROCEDURE [dbo].[OrganizationUserOrganizationDetails_ReadAcceptedConfirmedByUserId]
@UserId UNIQUEIDENTIFIER
AS
BEGIN
SET NOCOUNT ON

SELECT
*
FROM
[dbo].[OrganizationUserOrganizationDetailsView]
WHERE
[UserId] = @UserId
AND [Status] IN (1,2) -- 1 = Accepted, 2 = Confirmed
END
GO
Loading