Skip to content

[PM-19145] refactor organization service.import async #5800

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 30 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
ad1b78d
initial lift and shift
BTreston May 6, 2025
eec8b76
extract function RemoveExistingExternalUsers
BTreston May 6, 2025
5582f25
Extract function RemoveExistingUsers()
BTreston May 6, 2025
2f4574f
extract function OverwriteExisting()
BTreston May 6, 2025
9801c63
create new model for sync data
BTreston May 7, 2025
1f5ea44
extract add users to function, rename
BTreston May 7, 2025
f47a65c
rename OrganizatinUserInvite for command, implement command
BTreston May 8, 2025
f76d6fd
implement command
BTreston May 9, 2025
15cff6c
refactor groups logic
BTreston May 9, 2025
99e405a
fix imports
BTreston May 9, 2025
0a2e8e5
remove old tests, fix imports
BTreston May 9, 2025
5b09101
Merge branch 'main' into ac/pm-19145-refactor-OrganizationService.Impโ€ฆ
BTreston May 12, 2025
fcf7bd8
fix namespace
BTreston May 12, 2025
be8bd57
fix CommandResult useage
BTreston May 12, 2025
31b7dcd
tests wip
BTreston May 13, 2025
04383a8
wip
BTreston May 14, 2025
2cac1c8
wip
BTreston May 14, 2025
be23fe6
remove redundant code, remove looping db call, refactor tests
BTreston May 15, 2025
3ae9fbd
clean up
BTreston May 15, 2025
57e035b
remove looping db call with bulk method
BTreston May 15, 2025
da7c961
clean up
BTreston May 15, 2025
94fc71e
remove orgId param to use id already in request
BTreston May 15, 2025
af11c07
change param
BTreston May 30, 2025
f6035d8
cleanup params
BTreston May 30, 2025
5a78067
Merge branch 'main' into ac/pm-19145-refactor-OrganizationService.Impโ€ฆ
BTreston Jun 3, 2025
7db1129
remove IReferenceEventService
BTreston Jun 3, 2025
ea02dfb
fix test
BTreston Jun 3, 2025
36879fe
fix tests
BTreston Jun 3, 2025
4af676e
cr feedback
BTreston Jun 3, 2025
7994f61
remove _timeProvider
BTreston Jun 4, 2025
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
4 changes: 2 additions & 2 deletions bitwarden_license/src/Scim/Models/ScimUserRequestModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Models.Business;
using Bit.Core.Models.Data;
using Bit.Core.Utilities;
using OrganizationUserInvite = Bit.Core.Models.Business.OrganizationUserInvite;

namespace Bit.Scim.Models;

Expand Down Expand Up @@ -44,7 +44,7 @@ public InviteOrganizationUsersRequest ToRequest(
return new InviteOrganizationUsersRequest(
invites:
[
new Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models.OrganizationUserInvite(
new OrganizationUserInviteCommandModel(
email: email,
externalId: ExternalIdForInvite()
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
๏ปฟusing System.Net;
using Bit.Api.AdminConsole.Public.Models.Request;
using Bit.Api.Models.Public.Response;
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
using Bit.Core.Context;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Services;
using Bit.Core.Settings;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
Expand All @@ -15,18 +14,18 @@
[Authorize("Organization")]
public class OrganizationController : Controller
{
private readonly IOrganizationService _organizationService;
private readonly ICurrentContext _currentContext;
private readonly GlobalSettings _globalSettings;
private readonly IImportOrganizationUserCommand _importOrganizationUserCommand;

public OrganizationController(
IOrganizationService organizationService,
ICurrentContext currentContext,
GlobalSettings globalSettings)
GlobalSettings globalSettings,
IImportOrganizationUserCommand importOrganizationUserCommand)

Check warning on line 24 in src/Api/AdminConsole/Public/Controllers/OrganizationController.cs

View check run for this annotation

Codecov / codecov/patch

src/Api/AdminConsole/Public/Controllers/OrganizationController.cs#L23-L24

Added lines #L23 - L24 were not covered by tests
{
_organizationService = organizationService;
_currentContext = currentContext;
_globalSettings = globalSettings;
_importOrganizationUserCommand = importOrganizationUserCommand;

Check warning on line 28 in src/Api/AdminConsole/Public/Controllers/OrganizationController.cs

View check run for this annotation

Codecov / codecov/patch

src/Api/AdminConsole/Public/Controllers/OrganizationController.cs#L28

Added line #L28 was not covered by tests
}

/// <summary>
Expand All @@ -47,13 +46,12 @@
throw new BadRequestException("You cannot import this much data at once.");
}

await _organizationService.ImportAsync(
await _importOrganizationUserCommand.ImportAsync(

Check warning on line 49 in src/Api/AdminConsole/Public/Controllers/OrganizationController.cs

View check run for this annotation

Codecov / codecov/patch

src/Api/AdminConsole/Public/Controllers/OrganizationController.cs#L49

Added line #L49 was not covered by tests
_currentContext.OrganizationId.Value,
model.Groups.Select(g => g.ToImportedGroup(_currentContext.OrganizationId.Value)),
model.Members.Where(u => !u.Deleted).Select(u => u.ToImportedOrganizationUser()),
model.Members.Where(u => u.Deleted).Select(u => u.ExternalId),
model.OverwriteExisting.GetValueOrDefault(),
EventSystemUser.PublicApi);
model.OverwriteExisting.GetValueOrDefault());

Check warning on line 54 in src/Api/AdminConsole/Public/Controllers/OrganizationController.cs

View check run for this annotation

Codecov / codecov/patch

src/Api/AdminConsole/Public/Controllers/OrganizationController.cs#L54

Added line #L54 was not covered by tests
return new OkResult();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
๏ปฟusing Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.Models.Business;

namespace Bit.Core.Models.Data.Organizations;

public class OrganizationGroupImportData
{
public IEnumerable<ImportedGroup> Groups { get; init; }
public ICollection<Group> ExistingGroups { get; init; }
public IEnumerable<Group> ExistingExternalGroups { get; init; }
public IDictionary<string, ImportedGroup> GroupsDict { get; init; }

public OrganizationGroupImportData(IEnumerable<ImportedGroup> groups, ICollection<Group> existingGroups)
{
Groups = groups;
GroupsDict = groups.ToDictionary(g => g.Group.ExternalId);
ExistingGroups = existingGroups;
ExistingExternalGroups = GetExistingExternalGroups(existingGroups);
}

private IEnumerable<Group> GetExistingExternalGroups(ICollection<Group> existingGroups)
{
return existingGroups
.Where(u => !string.IsNullOrWhiteSpace(u.ExternalId))

Check warning on line 24 in src/Core/AdminConsole/Models/Data/Organizations/OrganizationGroupImportData.cs

View check run for this annotation

Codecov / codecov/patch

src/Core/AdminConsole/Models/Data/Organizations/OrganizationGroupImportData.cs#L24

Added line #L24 was not covered by tests
.ToList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
๏ปฟnamespace Bit.Core.Models.Data.Organizations.OrganizationUsers;

public class OrganizationUserImportData
{
public HashSet<string> NewUsersSet { get; init; }
public ICollection<OrganizationUserUserDetails> ExistingUsers { get; init; }
public IEnumerable<OrganizationUserUserDetails> ExistingExternalUsers { get; init; }
public Dictionary<string, Guid> ExistingExternalUsersIdDict { get; init; }
Comment on lines +5 to +8
Copy link
Member

Choose a reason for hiding this comment

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

I think these all can/should be readonly. xmldoc would also be really useful (e.g. HashSet<string> is pretty vague)


public OrganizationUserImportData(ICollection<OrganizationUserUserDetails> existingUsers, HashSet<string> newUsersSet)
{
NewUsersSet = newUsersSet;
ExistingUsers = existingUsers;
ExistingExternalUsers = GetExistingExternalUsers(existingUsers);
ExistingExternalUsersIdDict = GetExistingExternalUsers(existingUsers).ToDictionary(u => u.ExternalId, u => u.Id);
Copy link
Member

Choose a reason for hiding this comment

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

This is calling GetExistingExternalUsers twice. Instead:

ExistingExternalUsers = GetExistingExternalUsers(existingUsers);
ExistingExternalUsersIdDict = ExistingExternalUsers.ToDictionary(u => u.ExternalId, u => u.Id);

}

private IEnumerable<OrganizationUserUserDetails> GetExistingExternalUsers(ICollection<OrganizationUserUserDetails> existingUsers)
{
return existingUsers
.Where(u => !string.IsNullOrWhiteSpace(u.ExternalId))
.ToList();
}
}
Loading
Loading