1
0
mirror of https://github.com/bitwarden/server.git synced 2025-01-26 22:31:30 +01:00

[PS-1928] Fix User Delete (#2463)

* Fix User Delete

* Formatting
This commit is contained in:
Justin Baur 2022-12-02 19:35:26 -05:00 committed by GitHub
parent 1652669667
commit 85e75c43b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 56 additions and 76 deletions

View File

@ -179,8 +179,16 @@ public class OrganizationUserRepository : Repository<Core.Entities.OrganizationU
public async Task<int> GetCountByOnlyOwnerAsync(Guid userId)
{
var query = new OrganizationUserReadCountByOnlyOwnerQuery(userId);
return await GetCountFromQuery(query);
using (var scope = ServiceScopeFactory.CreateScope())
{
var dbContext = GetDatabaseContext(scope);
return await dbContext.OrganizationUsers
.Where(ou => ou.Type == OrganizationUserType.Owner && ou.Status == OrganizationUserStatusType.Confirmed)
.GroupBy(ou => ou.UserId)
.Select(g => new { UserId = g.Key, ConfirmedOwnerCount = g.Count() })
.Where(oc => oc.UserId == userId && oc.ConfirmedOwnerCount == 1)
.CountAsync();
}
}
public async Task<int> GetCountByOrganizationAsync(Guid organizationId, string email, bool onlyRegisteredUsers)

View File

@ -167,7 +167,15 @@ public class ProviderUserRepository :
public async Task<int> GetCountByOnlyOwnerAsync(Guid userId)
{
var query = new ProviderUserReadCountByOnlyOwnerQuery(userId);
return await GetCountFromQuery(query);
using (var scope = ServiceScopeFactory.CreateScope())
{
var dbContext = GetDatabaseContext(scope);
return await dbContext.ProviderUsers
.Where(pu => pu.Type == ProviderUserType.ProviderAdmin && pu.Status == ProviderUserStatusType.Confirmed)
.GroupBy(pu => pu.UserId)
.Select(g => new { UserId = g.Key, ConfirmedOwnerCount = g.Count() })
.Where(oc => oc.UserId == userId && oc.ConfirmedOwnerCount == 1)
.CountAsync();
}
}
}

View File

@ -1,36 +0,0 @@
using Bit.Core.Enums;
using Bit.Infrastructure.EntityFramework.Models;
namespace Bit.Infrastructure.EntityFramework.Repositories.Queries;
public class OrganizationUserReadCountByOnlyOwnerQuery : IQuery<OrganizationUser>
{
private readonly Guid _userId;
public OrganizationUserReadCountByOnlyOwnerQuery(Guid userId)
{
_userId = userId;
}
public IQueryable<OrganizationUser> Run(DatabaseContext dbContext)
{
var owners = from ou in dbContext.OrganizationUsers
where ou.Type == OrganizationUserType.Owner &&
ou.Status == OrganizationUserStatusType.Confirmed
group ou by ou.OrganizationId into g
select new
{
OrgUser = g.Select(x => new { x.UserId, x.Id }).FirstOrDefault(),
ConfirmedOwnerCount = g.Count(),
};
var query = from owner in owners
join ou in dbContext.OrganizationUsers
on owner.OrgUser.Id equals ou.Id
where owner.OrgUser.UserId == _userId &&
owner.ConfirmedOwnerCount == 1
select ou;
return query;
}
}

View File

@ -1,36 +0,0 @@
using Bit.Core.Enums.Provider;
using Bit.Infrastructure.EntityFramework.Models;
namespace Bit.Infrastructure.EntityFramework.Repositories.Queries;
public class ProviderUserReadCountByOnlyOwnerQuery : IQuery<ProviderUser>
{
private readonly Guid _userId;
public ProviderUserReadCountByOnlyOwnerQuery(Guid userId)
{
_userId = userId;
}
public IQueryable<ProviderUser> Run(DatabaseContext dbContext)
{
var owners = from pu in dbContext.ProviderUsers
where pu.Type == ProviderUserType.ProviderAdmin &&
pu.Status == ProviderUserStatusType.Confirmed
group pu by pu.ProviderId into g
select new
{
ProviderUser = g.Select(x => new { x.UserId, x.Id }).FirstOrDefault(),
ConfirmedOwnerCount = g.Count(),
};
var query = from owner in owners
join pu in dbContext.ProviderUsers
on owner.ProviderUser.Id equals pu.Id
where owner.ProviderUser.UserId == _userId &&
owner.ConfirmedOwnerCount == 1
select pu;
return query;
}
}

View File

@ -142,4 +142,40 @@ public class UserRepository : Repository<Core.Entities.User, User, Guid>, IUserR
return await users.ToListAsync();
}
}
public override async Task DeleteAsync(Core.Entities.User user)
{
using (var scope = ServiceScopeFactory.CreateScope())
{
var dbContext = GetDatabaseContext(scope);
var transaction = await dbContext.Database.BeginTransactionAsync();
dbContext.Ciphers.RemoveRange(dbContext.Ciphers.Where(c => c.UserId == user.Id));
dbContext.Folders.RemoveRange(dbContext.Folders.Where(f => f.UserId == user.Id));
dbContext.Devices.RemoveRange(dbContext.Devices.Where(d => d.UserId == user.Id));
var collectionUsers = from cu in dbContext.CollectionUsers
join ou in dbContext.OrganizationUsers on cu.OrganizationUserId equals ou.Id
where ou.UserId == user.Id
select cu;
dbContext.CollectionUsers.RemoveRange(collectionUsers);
var groupUsers = from gu in dbContext.GroupUsers
join ou in dbContext.OrganizationUsers on gu.OrganizationUserId equals ou.Id
where ou.UserId == user.Id
select gu;
dbContext.GroupUsers.RemoveRange(groupUsers);
dbContext.OrganizationUsers.RemoveRange(dbContext.OrganizationUsers.Where(ou => ou.UserId == user.Id));
dbContext.ProviderUsers.RemoveRange(dbContext.ProviderUsers.Where(pu => pu.UserId == user.Id));
dbContext.SsoUsers.RemoveRange(dbContext.SsoUsers.Where(su => su.UserId == user.Id));
dbContext.EmergencyAccesses.RemoveRange(
dbContext.EmergencyAccesses.Where(ea => ea.GrantorId == user.Id || ea.GranteeId == user.Id));
dbContext.Sends.RemoveRange(dbContext.Sends.Where(s => s.UserId == user.Id));
var mappedUser = Mapper.Map<User>(user);
dbContext.Users.Remove(mappedUser);
await transaction.CommitAsync();
await dbContext.SaveChangesAsync();
}
}
}