2023-10-19 01:27:56 +10:00
|
|
|
|
using Bit.Api.AdminConsole.Models.Request.Organizations;
|
|
|
|
|
|
using Bit.Api.AdminConsole.Models.Response.Organizations;
|
|
|
|
|
|
using Bit.Api.Models.Request.Organizations;
|
2021-12-14 15:05:07 +00:00
|
|
|
|
using Bit.Api.Models.Response;
|
2023-10-27 07:47:44 +10:00
|
|
|
|
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
|
2023-10-20 06:37:46 +10:00
|
|
|
|
using Bit.Core.AdminConsole.Repositories;
|
2021-02-04 12:54:21 -06:00
|
|
|
|
using Bit.Core.Context;
|
2021-04-20 16:58:57 -05:00
|
|
|
|
using Bit.Core.Enums;
|
2017-03-04 21:28:41 -05:00
|
|
|
|
using Bit.Core.Exceptions;
|
2021-01-12 11:02:39 -05:00
|
|
|
|
using Bit.Core.Models.Business;
|
2022-05-10 17:12:09 -04:00
|
|
|
|
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
2022-06-08 08:44:28 -05:00
|
|
|
|
using Bit.Core.Models.Data.Organizations.Policies;
|
2023-08-05 07:51:12 +10:00
|
|
|
|
using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface;
|
Auth/PM-3275 - Changes to support TDE User without MP being able to Set a Password + misc refactoring (#3242)
* PM-3275 - Add new GetMasterPasswordPolicy endpoint which will allow authenticated clients to get an enabled MP org policy if it exists for the purposes of enforcing those policy requirements when setting a password.
* PM-3275 - AccountsController.cs - PostSetPasswordAsync - (1) Convert UserService.setPasswordAsync into new SetInitialMasterPasswordCommand (2) Refactor SetInitialMasterPasswordCommand to only accept post SSO users who are in the invited state
(3) Add TODOs for more cleanup work and more commands
* PM-3275 - Update AccountsControllerTests.cs to add new SetInitialMasterPasswordCommand
* PM-3275 - UserService.cs - Remove non implemented ChangePasswordAsync method
* PM-3275 - The new SetInitialMasterPasswordCommand leveraged the OrganizationService.cs AcceptUserAsync method so while I was in here I converted the AcceptUserAsync methods into a new AcceptOrgUserCommand.cs and turned the private method which accepted an existing org user public for use in the SetInitialMasterPasswordCommand
* PM-3275 - Dotnet format
* PM-3275 - Test SetInitialMasterPasswordCommand
* Dotnet format
* PM-3275 - In process AcceptOrgUserCommandTests.cs
* PM-3275 - Migrate changes from AC-244 / #3199 over into new AcceptOrgUserCommand
* PM-3275 - AcceptOrgUserCommand.cs - create data protector specifically for this command
* PM-3275 - Add TODO for renaming / removing overloading of methods to improve readability / clarity
* PM-3275 - AcceptOrgUserCommand.cs - refactor AcceptOrgUserAsync by OrgId to retrieve orgUser with _organizationUserRepository.GetByOrganizationAsync which gets a single user instead of a collection
* PM-3275 - AcceptOrgUserCommand.cs - update name in TODO for evaluation later
* PM-3275 / PM-1196 - (1) Slightly refactor SsoEmail2faSessionTokenable to provide public static GetTokenLifeTime() method for testing (2) Add missed tests to SsoEmail2faSessionTokenable in preparation for building tests for new OrgUserInviteTokenable.cs
* PM-3275 / PM-1196 - Removing SsoEmail2faSessionTokenable.cs changes + tests as I've handled that separately in a new PR (#3270) for newly created task PM-3925
* PM-3275 - ExpiringTokenable.cs - add clarifying comments to help distinguish between the Valid property and the TokenIsValid method.
* PM-3275 - Create OrgUserInviteTokenable.cs and add tests in OrgUserInviteTokenableTests.cs
* PM-3275 - OrganizationService.cs - Refactor Org User Invite methods to use new OrgUserInviteTokenable instead of manual creation of a token
* PM-3275 - OrgUserInviteTokenable.cs - clarify backwards compat note
* PM-3275 - AcceptOrgUserCommand.cs - Add TODOs + minor name refactor
* PM-3275 - AcceptOrgUserCommand.cs - replace method overloading with more easily readable names.
* PM-3275 - AcceptOrgUserCommand.cs - Update ValidateOrgUserInviteToken to add new token validation while maintaining backwards compatibility for 1 release.
* dotnet format
* PM-3275 - AcceptOrgUserCommand.cs - Move private method below where it is used
* PM-3275 - ServiceCollectionExtensions.cs - Must register IDataProtectorTokenFactory<OrgUserInviteTokenable> for new tokenable
* PM-3275 - OrgUserInviteTokenable needed access to global settings to set its token lifetime to the _globalSettings.OrganizationInviteExpirationHours value. Creating a factory seemed the most straightforward way to encapsulate the desired creation logic. Unsure if in the correct location in ServiceCollectionExtensions.cs but will figure that out later.
* PM-3275 - In process work of creating AcceptOrgUserCommandTests.cs
* PM-3275 - Remove no longer relevant AcceptOrgUser tests from OrganizationServiceTests.cs
* PM-3275 - Register OrgUserInviteTokenableFactory alongside tokenizer
* PM-3275 - AcceptOrgUserCommandTests.cs - AcceptOrgUserAsync basic test suite completed.
* PM-3275 - AcceptOrgUserCommandTests.cs - tweak test names
* PM-3275 - AcceptOrgUserCommandTests.cs - (1) Remove old tests from OrganizationServiceTests as no longer needed to reference (2) Add summary for SetupCommonAcceptOrgUserMocks (3) Get AcceptOrgUserByToken_OldToken_AcceptsUserAndVerifiesEmail passing
* PM-3275 - Create interface for OrgUserInviteTokenableFactory b/c that's the right thing to do + enables test substitution
* PM-3275 - AcceptOrgUserCommandTests.cs - (1) Start work on AcceptOrgUserByToken_NewToken_AcceptsUserAndVerifiesEmail (2) Create and use SetupCommonAcceptOrgUserByTokenMocks() (3) Create generic FakeDataProtectorTokenFactory for tokenable testing
* PM-3275 - (1) Get AcceptOrgUserByToken_NewToken_AcceptsUserAndVerifiesEmail test passing (2) Move FakeDataProtectorTokenFactory to own file
* PM-3275 - AcceptOrgUserCommandTests.cs - Finish up tests for AcceptOrgUserByTokenAsync
* PM-3275 - Add pseudo section comments
* PM-3275 - Clean up unused params on AcceptOrgUserByToken_EmailMismatch_ThrowsBadRequest test
* PM-3275 - (1) Tests written for AcceptOrgUserByOrgSsoIdAsync (2) Refactor happy path assertions into helper function AssertValidAcceptedOrgUser to reduce code duplication
* PM-3275 - Finish up testing AcceptOrgUserCommandTests.cs by adding tests for AcceptOrgUserByOrgIdAsync
* PM-3275 - Tweaking test naming to ensure consistency.
* PM-3275 - Bugfix - OrgUserInviteTokenableFactory implementation required when declaring singleton service in ServiceCollectionExtensions.cs
* PM-3275 - Resolve failing OrganizationServiceTests.cs
* dotnet format
* PM-3275 - PoliciesController.cs - GetMasterPasswordPolicy bugfix - for orgs without a MP policy, policy comes back as null and we should return notFound in that case.
* PM-3275 - Add PoliciesControllerTests.cs specifically for new GetMasterPasswordPolicy(...) endpoint.
* PM-3275 - dotnet format PoliciesControllerTests.cs
* PM-3275 - PoliciesController.cs - (1) Add tech debt task number (2) Properly flag endpoint as deprecated
* PM-3275 - Add new hasManageResetPasswordPermission property to ProfileResponseModel.cs primarily for sync so that we can condition client side if TDE user obtains elevated permissions
* PM-3275 - Fix AccountsControllerTests.cs
* PM-3275 - OrgUserInviteTokenable.cs - clarify TODO
* PM-3275 - AcceptOrgUserCommand.cs - Refactor token validation to use short circuiting to only run old token validation if new token validation fails.
* PM-3275 - OrgUserInviteTokenable.cs - (1) Add new static methods to centralize validation logic to avoid repetition (2) Add new token validation method so we can avoid having to pass in a full org user (and hitting the db to do so)
* PM-3275 - Realized that the old token validation was used in the PoliciesController.cs (existing user clicks invite link in email and goes to log in) and UserService.cs (user clicks invite link in email and registers for a new acct). Added tech debt item for cleaning up backwards compatibility in future.
* dotnet format
* PM-3275 - (1) AccountsController.cs - Update PostSetPasswordAsync SetPasswordRequestModel to allow null keys for the case where we have a TDE user who obtains elevated permissions - they already have a user public and user encrypted private key saved in the db. (2) AccountsControllerTests.cs - test PostSetPasswordAsync scenarios to ensure changes will work as expected.
* PM-3275 - PR review feedback - (1) set CurrentContext to private (2) Refactor GetProfile to use variables to improve clarity and simplify debugging.
* PM-3275 - SyncController.cs - PR Review Feedback - Set current context as private instead of protected.
* PM-3275 - CurrentContextExtensions.cs - PR Feedback - move parenthesis up from own line.
* PM-3275 - SetInitialMasterPasswordCommandTests.cs - Replace unnecessary variable
* PM-3275 - SetInitialMasterPasswordCommandTests.cs - PR Feedback - Add expected outcome statement to test name
* PM-3275 - Set Initial Password command and tests - PR Feedback changes - (1) Rename orgIdentifier --> OrgSsoIdentifier for clarity (2) Update SetInitialMasterPasswordAsync to not allow null orgSsoId with explicit message saying this vs letting null org trigger invalid organization (3) Add test to cover this new scenario.
* PM-3275 - SetInitialMasterPasswordCommand.cs - Move summary from implementation to interface to better respect standards and the fact that the interface is the more seen piece of code.
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, rename AcceptOrgUserByTokenAsync -> AcceptOrgUserByEmailTokenAsync + replace generic name token with emailToken
* PM-3275 - OrganizationService.cs - Per PR feedback, remove dupe line
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, remove new lines in error messages for consistency.
* PM-3275 - SetInitialMasterPasswordCommand.cs - Per PR feedback, adjust formatting of constructor for improved readability.
* PM-3275 - CurrentContextExtensions.cs - Refactor AnyOrgUserHasManageResetPasswordPermission per PR feedback to remove unnecessary var.
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, remove completed TODO
* PM-3275 - PoliciesController.cs - Per PR feedback, update GetByInvitedUser param to be guid instead of string.
* PM-3275 - OrgUserInviteTokenable.cs - per PR feedback, add tech debt item info.
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, use const purpose from tokenable instead of magic string.
* PM-3275 - Restore non duplicate line to fix tests
* PM-3275 - Per PR feedback, revert all sync controller changes as the ProfileResponseModel.organizations array has org objects which have permissions which have the ManageResetPassword permission. So, I have the information that I need clientside already to determine if the user has the ManageResetPassword in any org.
* PM-3275 - PoliciesControllerTests.cs - Update imports as the PoliciesController was moved under the admin console team's domain.
* PM-3275 - Resolve issues from merge conflict resolutions to get solution building.
* PM-3275 / PM-4633 - PoliciesController.cs - use orgUserId to look up user instead of orgId. Oops.
* Fix user service tests
* Resolve merge conflict
2023-11-02 11:02:25 -04:00
|
|
|
|
using Bit.Core.OrganizationFeatures.OrganizationUsers.Interfaces;
|
2017-03-04 21:28:41 -05:00
|
|
|
|
using Bit.Core.Repositories;
|
|
|
|
|
|
using Bit.Core.Services;
|
|
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
|
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
|
|
2023-10-19 01:27:56 +10:00
|
|
|
|
namespace Bit.Api.AdminConsole.Controllers;
|
2022-08-29 16:06:55 -04:00
|
|
|
|
|
2017-03-04 21:28:41 -05:00
|
|
|
|
[Route("organizations/{orgId}/users")]
|
|
|
|
|
|
[Authorize("Application")]
|
|
|
|
|
|
public class OrganizationUsersController : Controller
|
|
|
|
|
|
{
|
|
|
|
|
|
private readonly IOrganizationRepository _organizationRepository;
|
|
|
|
|
|
private readonly IOrganizationUserRepository _organizationUserRepository;
|
|
|
|
|
|
private readonly IOrganizationService _organizationService;
|
|
|
|
|
|
private readonly ICollectionRepository _collectionRepository;
|
|
|
|
|
|
private readonly IGroupRepository _groupRepository;
|
|
|
|
|
|
private readonly IUserService _userService;
|
2022-06-08 08:44:28 -05:00
|
|
|
|
private readonly IPolicyRepository _policyRepository;
|
2017-03-04 21:28:41 -05:00
|
|
|
|
private readonly ICurrentContext _currentContext;
|
2023-08-05 07:51:12 +10:00
|
|
|
|
private readonly ICountNewSmSeatsRequiredQuery _countNewSmSeatsRequiredQuery;
|
|
|
|
|
|
private readonly IUpdateSecretsManagerSubscriptionCommand _updateSecretsManagerSubscriptionCommand;
|
2023-09-01 09:10:02 +01:00
|
|
|
|
private readonly IUpdateOrganizationUserGroupsCommand _updateOrganizationUserGroupsCommand;
|
Auth/PM-3275 - Changes to support TDE User without MP being able to Set a Password + misc refactoring (#3242)
* PM-3275 - Add new GetMasterPasswordPolicy endpoint which will allow authenticated clients to get an enabled MP org policy if it exists for the purposes of enforcing those policy requirements when setting a password.
* PM-3275 - AccountsController.cs - PostSetPasswordAsync - (1) Convert UserService.setPasswordAsync into new SetInitialMasterPasswordCommand (2) Refactor SetInitialMasterPasswordCommand to only accept post SSO users who are in the invited state
(3) Add TODOs for more cleanup work and more commands
* PM-3275 - Update AccountsControllerTests.cs to add new SetInitialMasterPasswordCommand
* PM-3275 - UserService.cs - Remove non implemented ChangePasswordAsync method
* PM-3275 - The new SetInitialMasterPasswordCommand leveraged the OrganizationService.cs AcceptUserAsync method so while I was in here I converted the AcceptUserAsync methods into a new AcceptOrgUserCommand.cs and turned the private method which accepted an existing org user public for use in the SetInitialMasterPasswordCommand
* PM-3275 - Dotnet format
* PM-3275 - Test SetInitialMasterPasswordCommand
* Dotnet format
* PM-3275 - In process AcceptOrgUserCommandTests.cs
* PM-3275 - Migrate changes from AC-244 / #3199 over into new AcceptOrgUserCommand
* PM-3275 - AcceptOrgUserCommand.cs - create data protector specifically for this command
* PM-3275 - Add TODO for renaming / removing overloading of methods to improve readability / clarity
* PM-3275 - AcceptOrgUserCommand.cs - refactor AcceptOrgUserAsync by OrgId to retrieve orgUser with _organizationUserRepository.GetByOrganizationAsync which gets a single user instead of a collection
* PM-3275 - AcceptOrgUserCommand.cs - update name in TODO for evaluation later
* PM-3275 / PM-1196 - (1) Slightly refactor SsoEmail2faSessionTokenable to provide public static GetTokenLifeTime() method for testing (2) Add missed tests to SsoEmail2faSessionTokenable in preparation for building tests for new OrgUserInviteTokenable.cs
* PM-3275 / PM-1196 - Removing SsoEmail2faSessionTokenable.cs changes + tests as I've handled that separately in a new PR (#3270) for newly created task PM-3925
* PM-3275 - ExpiringTokenable.cs - add clarifying comments to help distinguish between the Valid property and the TokenIsValid method.
* PM-3275 - Create OrgUserInviteTokenable.cs and add tests in OrgUserInviteTokenableTests.cs
* PM-3275 - OrganizationService.cs - Refactor Org User Invite methods to use new OrgUserInviteTokenable instead of manual creation of a token
* PM-3275 - OrgUserInviteTokenable.cs - clarify backwards compat note
* PM-3275 - AcceptOrgUserCommand.cs - Add TODOs + minor name refactor
* PM-3275 - AcceptOrgUserCommand.cs - replace method overloading with more easily readable names.
* PM-3275 - AcceptOrgUserCommand.cs - Update ValidateOrgUserInviteToken to add new token validation while maintaining backwards compatibility for 1 release.
* dotnet format
* PM-3275 - AcceptOrgUserCommand.cs - Move private method below where it is used
* PM-3275 - ServiceCollectionExtensions.cs - Must register IDataProtectorTokenFactory<OrgUserInviteTokenable> for new tokenable
* PM-3275 - OrgUserInviteTokenable needed access to global settings to set its token lifetime to the _globalSettings.OrganizationInviteExpirationHours value. Creating a factory seemed the most straightforward way to encapsulate the desired creation logic. Unsure if in the correct location in ServiceCollectionExtensions.cs but will figure that out later.
* PM-3275 - In process work of creating AcceptOrgUserCommandTests.cs
* PM-3275 - Remove no longer relevant AcceptOrgUser tests from OrganizationServiceTests.cs
* PM-3275 - Register OrgUserInviteTokenableFactory alongside tokenizer
* PM-3275 - AcceptOrgUserCommandTests.cs - AcceptOrgUserAsync basic test suite completed.
* PM-3275 - AcceptOrgUserCommandTests.cs - tweak test names
* PM-3275 - AcceptOrgUserCommandTests.cs - (1) Remove old tests from OrganizationServiceTests as no longer needed to reference (2) Add summary for SetupCommonAcceptOrgUserMocks (3) Get AcceptOrgUserByToken_OldToken_AcceptsUserAndVerifiesEmail passing
* PM-3275 - Create interface for OrgUserInviteTokenableFactory b/c that's the right thing to do + enables test substitution
* PM-3275 - AcceptOrgUserCommandTests.cs - (1) Start work on AcceptOrgUserByToken_NewToken_AcceptsUserAndVerifiesEmail (2) Create and use SetupCommonAcceptOrgUserByTokenMocks() (3) Create generic FakeDataProtectorTokenFactory for tokenable testing
* PM-3275 - (1) Get AcceptOrgUserByToken_NewToken_AcceptsUserAndVerifiesEmail test passing (2) Move FakeDataProtectorTokenFactory to own file
* PM-3275 - AcceptOrgUserCommandTests.cs - Finish up tests for AcceptOrgUserByTokenAsync
* PM-3275 - Add pseudo section comments
* PM-3275 - Clean up unused params on AcceptOrgUserByToken_EmailMismatch_ThrowsBadRequest test
* PM-3275 - (1) Tests written for AcceptOrgUserByOrgSsoIdAsync (2) Refactor happy path assertions into helper function AssertValidAcceptedOrgUser to reduce code duplication
* PM-3275 - Finish up testing AcceptOrgUserCommandTests.cs by adding tests for AcceptOrgUserByOrgIdAsync
* PM-3275 - Tweaking test naming to ensure consistency.
* PM-3275 - Bugfix - OrgUserInviteTokenableFactory implementation required when declaring singleton service in ServiceCollectionExtensions.cs
* PM-3275 - Resolve failing OrganizationServiceTests.cs
* dotnet format
* PM-3275 - PoliciesController.cs - GetMasterPasswordPolicy bugfix - for orgs without a MP policy, policy comes back as null and we should return notFound in that case.
* PM-3275 - Add PoliciesControllerTests.cs specifically for new GetMasterPasswordPolicy(...) endpoint.
* PM-3275 - dotnet format PoliciesControllerTests.cs
* PM-3275 - PoliciesController.cs - (1) Add tech debt task number (2) Properly flag endpoint as deprecated
* PM-3275 - Add new hasManageResetPasswordPermission property to ProfileResponseModel.cs primarily for sync so that we can condition client side if TDE user obtains elevated permissions
* PM-3275 - Fix AccountsControllerTests.cs
* PM-3275 - OrgUserInviteTokenable.cs - clarify TODO
* PM-3275 - AcceptOrgUserCommand.cs - Refactor token validation to use short circuiting to only run old token validation if new token validation fails.
* PM-3275 - OrgUserInviteTokenable.cs - (1) Add new static methods to centralize validation logic to avoid repetition (2) Add new token validation method so we can avoid having to pass in a full org user (and hitting the db to do so)
* PM-3275 - Realized that the old token validation was used in the PoliciesController.cs (existing user clicks invite link in email and goes to log in) and UserService.cs (user clicks invite link in email and registers for a new acct). Added tech debt item for cleaning up backwards compatibility in future.
* dotnet format
* PM-3275 - (1) AccountsController.cs - Update PostSetPasswordAsync SetPasswordRequestModel to allow null keys for the case where we have a TDE user who obtains elevated permissions - they already have a user public and user encrypted private key saved in the db. (2) AccountsControllerTests.cs - test PostSetPasswordAsync scenarios to ensure changes will work as expected.
* PM-3275 - PR review feedback - (1) set CurrentContext to private (2) Refactor GetProfile to use variables to improve clarity and simplify debugging.
* PM-3275 - SyncController.cs - PR Review Feedback - Set current context as private instead of protected.
* PM-3275 - CurrentContextExtensions.cs - PR Feedback - move parenthesis up from own line.
* PM-3275 - SetInitialMasterPasswordCommandTests.cs - Replace unnecessary variable
* PM-3275 - SetInitialMasterPasswordCommandTests.cs - PR Feedback - Add expected outcome statement to test name
* PM-3275 - Set Initial Password command and tests - PR Feedback changes - (1) Rename orgIdentifier --> OrgSsoIdentifier for clarity (2) Update SetInitialMasterPasswordAsync to not allow null orgSsoId with explicit message saying this vs letting null org trigger invalid organization (3) Add test to cover this new scenario.
* PM-3275 - SetInitialMasterPasswordCommand.cs - Move summary from implementation to interface to better respect standards and the fact that the interface is the more seen piece of code.
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, rename AcceptOrgUserByTokenAsync -> AcceptOrgUserByEmailTokenAsync + replace generic name token with emailToken
* PM-3275 - OrganizationService.cs - Per PR feedback, remove dupe line
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, remove new lines in error messages for consistency.
* PM-3275 - SetInitialMasterPasswordCommand.cs - Per PR feedback, adjust formatting of constructor for improved readability.
* PM-3275 - CurrentContextExtensions.cs - Refactor AnyOrgUserHasManageResetPasswordPermission per PR feedback to remove unnecessary var.
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, remove completed TODO
* PM-3275 - PoliciesController.cs - Per PR feedback, update GetByInvitedUser param to be guid instead of string.
* PM-3275 - OrgUserInviteTokenable.cs - per PR feedback, add tech debt item info.
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, use const purpose from tokenable instead of magic string.
* PM-3275 - Restore non duplicate line to fix tests
* PM-3275 - Per PR feedback, revert all sync controller changes as the ProfileResponseModel.organizations array has org objects which have permissions which have the ManageResetPassword permission. So, I have the information that I need clientside already to determine if the user has the ManageResetPassword in any org.
* PM-3275 - PoliciesControllerTests.cs - Update imports as the PoliciesController was moved under the admin console team's domain.
* PM-3275 - Resolve issues from merge conflict resolutions to get solution building.
* PM-3275 / PM-4633 - PoliciesController.cs - use orgUserId to look up user instead of orgId. Oops.
* Fix user service tests
* Resolve merge conflict
2023-11-02 11:02:25 -04:00
|
|
|
|
private readonly IAcceptOrgUserCommand _acceptOrgUserCommand;
|
2022-08-29 16:06:55 -04:00
|
|
|
|
|
2017-03-04 21:28:41 -05:00
|
|
|
|
public OrganizationUsersController(
|
|
|
|
|
|
IOrganizationRepository organizationRepository,
|
|
|
|
|
|
IOrganizationUserRepository organizationUserRepository,
|
|
|
|
|
|
IOrganizationService organizationService,
|
|
|
|
|
|
ICollectionRepository collectionRepository,
|
2017-05-09 19:04:01 -04:00
|
|
|
|
IGroupRepository groupRepository,
|
2017-04-05 16:29:46 -04:00
|
|
|
|
IUserService userService,
|
2022-06-08 08:44:28 -05:00
|
|
|
|
IPolicyRepository policyRepository,
|
2023-08-05 07:51:12 +10:00
|
|
|
|
ICurrentContext currentContext,
|
|
|
|
|
|
ICountNewSmSeatsRequiredQuery countNewSmSeatsRequiredQuery,
|
2023-09-01 09:10:02 +01:00
|
|
|
|
IUpdateSecretsManagerSubscriptionCommand updateSecretsManagerSubscriptionCommand,
|
Auth/PM-3275 - Changes to support TDE User without MP being able to Set a Password + misc refactoring (#3242)
* PM-3275 - Add new GetMasterPasswordPolicy endpoint which will allow authenticated clients to get an enabled MP org policy if it exists for the purposes of enforcing those policy requirements when setting a password.
* PM-3275 - AccountsController.cs - PostSetPasswordAsync - (1) Convert UserService.setPasswordAsync into new SetInitialMasterPasswordCommand (2) Refactor SetInitialMasterPasswordCommand to only accept post SSO users who are in the invited state
(3) Add TODOs for more cleanup work and more commands
* PM-3275 - Update AccountsControllerTests.cs to add new SetInitialMasterPasswordCommand
* PM-3275 - UserService.cs - Remove non implemented ChangePasswordAsync method
* PM-3275 - The new SetInitialMasterPasswordCommand leveraged the OrganizationService.cs AcceptUserAsync method so while I was in here I converted the AcceptUserAsync methods into a new AcceptOrgUserCommand.cs and turned the private method which accepted an existing org user public for use in the SetInitialMasterPasswordCommand
* PM-3275 - Dotnet format
* PM-3275 - Test SetInitialMasterPasswordCommand
* Dotnet format
* PM-3275 - In process AcceptOrgUserCommandTests.cs
* PM-3275 - Migrate changes from AC-244 / #3199 over into new AcceptOrgUserCommand
* PM-3275 - AcceptOrgUserCommand.cs - create data protector specifically for this command
* PM-3275 - Add TODO for renaming / removing overloading of methods to improve readability / clarity
* PM-3275 - AcceptOrgUserCommand.cs - refactor AcceptOrgUserAsync by OrgId to retrieve orgUser with _organizationUserRepository.GetByOrganizationAsync which gets a single user instead of a collection
* PM-3275 - AcceptOrgUserCommand.cs - update name in TODO for evaluation later
* PM-3275 / PM-1196 - (1) Slightly refactor SsoEmail2faSessionTokenable to provide public static GetTokenLifeTime() method for testing (2) Add missed tests to SsoEmail2faSessionTokenable in preparation for building tests for new OrgUserInviteTokenable.cs
* PM-3275 / PM-1196 - Removing SsoEmail2faSessionTokenable.cs changes + tests as I've handled that separately in a new PR (#3270) for newly created task PM-3925
* PM-3275 - ExpiringTokenable.cs - add clarifying comments to help distinguish between the Valid property and the TokenIsValid method.
* PM-3275 - Create OrgUserInviteTokenable.cs and add tests in OrgUserInviteTokenableTests.cs
* PM-3275 - OrganizationService.cs - Refactor Org User Invite methods to use new OrgUserInviteTokenable instead of manual creation of a token
* PM-3275 - OrgUserInviteTokenable.cs - clarify backwards compat note
* PM-3275 - AcceptOrgUserCommand.cs - Add TODOs + minor name refactor
* PM-3275 - AcceptOrgUserCommand.cs - replace method overloading with more easily readable names.
* PM-3275 - AcceptOrgUserCommand.cs - Update ValidateOrgUserInviteToken to add new token validation while maintaining backwards compatibility for 1 release.
* dotnet format
* PM-3275 - AcceptOrgUserCommand.cs - Move private method below where it is used
* PM-3275 - ServiceCollectionExtensions.cs - Must register IDataProtectorTokenFactory<OrgUserInviteTokenable> for new tokenable
* PM-3275 - OrgUserInviteTokenable needed access to global settings to set its token lifetime to the _globalSettings.OrganizationInviteExpirationHours value. Creating a factory seemed the most straightforward way to encapsulate the desired creation logic. Unsure if in the correct location in ServiceCollectionExtensions.cs but will figure that out later.
* PM-3275 - In process work of creating AcceptOrgUserCommandTests.cs
* PM-3275 - Remove no longer relevant AcceptOrgUser tests from OrganizationServiceTests.cs
* PM-3275 - Register OrgUserInviteTokenableFactory alongside tokenizer
* PM-3275 - AcceptOrgUserCommandTests.cs - AcceptOrgUserAsync basic test suite completed.
* PM-3275 - AcceptOrgUserCommandTests.cs - tweak test names
* PM-3275 - AcceptOrgUserCommandTests.cs - (1) Remove old tests from OrganizationServiceTests as no longer needed to reference (2) Add summary for SetupCommonAcceptOrgUserMocks (3) Get AcceptOrgUserByToken_OldToken_AcceptsUserAndVerifiesEmail passing
* PM-3275 - Create interface for OrgUserInviteTokenableFactory b/c that's the right thing to do + enables test substitution
* PM-3275 - AcceptOrgUserCommandTests.cs - (1) Start work on AcceptOrgUserByToken_NewToken_AcceptsUserAndVerifiesEmail (2) Create and use SetupCommonAcceptOrgUserByTokenMocks() (3) Create generic FakeDataProtectorTokenFactory for tokenable testing
* PM-3275 - (1) Get AcceptOrgUserByToken_NewToken_AcceptsUserAndVerifiesEmail test passing (2) Move FakeDataProtectorTokenFactory to own file
* PM-3275 - AcceptOrgUserCommandTests.cs - Finish up tests for AcceptOrgUserByTokenAsync
* PM-3275 - Add pseudo section comments
* PM-3275 - Clean up unused params on AcceptOrgUserByToken_EmailMismatch_ThrowsBadRequest test
* PM-3275 - (1) Tests written for AcceptOrgUserByOrgSsoIdAsync (2) Refactor happy path assertions into helper function AssertValidAcceptedOrgUser to reduce code duplication
* PM-3275 - Finish up testing AcceptOrgUserCommandTests.cs by adding tests for AcceptOrgUserByOrgIdAsync
* PM-3275 - Tweaking test naming to ensure consistency.
* PM-3275 - Bugfix - OrgUserInviteTokenableFactory implementation required when declaring singleton service in ServiceCollectionExtensions.cs
* PM-3275 - Resolve failing OrganizationServiceTests.cs
* dotnet format
* PM-3275 - PoliciesController.cs - GetMasterPasswordPolicy bugfix - for orgs without a MP policy, policy comes back as null and we should return notFound in that case.
* PM-3275 - Add PoliciesControllerTests.cs specifically for new GetMasterPasswordPolicy(...) endpoint.
* PM-3275 - dotnet format PoliciesControllerTests.cs
* PM-3275 - PoliciesController.cs - (1) Add tech debt task number (2) Properly flag endpoint as deprecated
* PM-3275 - Add new hasManageResetPasswordPermission property to ProfileResponseModel.cs primarily for sync so that we can condition client side if TDE user obtains elevated permissions
* PM-3275 - Fix AccountsControllerTests.cs
* PM-3275 - OrgUserInviteTokenable.cs - clarify TODO
* PM-3275 - AcceptOrgUserCommand.cs - Refactor token validation to use short circuiting to only run old token validation if new token validation fails.
* PM-3275 - OrgUserInviteTokenable.cs - (1) Add new static methods to centralize validation logic to avoid repetition (2) Add new token validation method so we can avoid having to pass in a full org user (and hitting the db to do so)
* PM-3275 - Realized that the old token validation was used in the PoliciesController.cs (existing user clicks invite link in email and goes to log in) and UserService.cs (user clicks invite link in email and registers for a new acct). Added tech debt item for cleaning up backwards compatibility in future.
* dotnet format
* PM-3275 - (1) AccountsController.cs - Update PostSetPasswordAsync SetPasswordRequestModel to allow null keys for the case where we have a TDE user who obtains elevated permissions - they already have a user public and user encrypted private key saved in the db. (2) AccountsControllerTests.cs - test PostSetPasswordAsync scenarios to ensure changes will work as expected.
* PM-3275 - PR review feedback - (1) set CurrentContext to private (2) Refactor GetProfile to use variables to improve clarity and simplify debugging.
* PM-3275 - SyncController.cs - PR Review Feedback - Set current context as private instead of protected.
* PM-3275 - CurrentContextExtensions.cs - PR Feedback - move parenthesis up from own line.
* PM-3275 - SetInitialMasterPasswordCommandTests.cs - Replace unnecessary variable
* PM-3275 - SetInitialMasterPasswordCommandTests.cs - PR Feedback - Add expected outcome statement to test name
* PM-3275 - Set Initial Password command and tests - PR Feedback changes - (1) Rename orgIdentifier --> OrgSsoIdentifier for clarity (2) Update SetInitialMasterPasswordAsync to not allow null orgSsoId with explicit message saying this vs letting null org trigger invalid organization (3) Add test to cover this new scenario.
* PM-3275 - SetInitialMasterPasswordCommand.cs - Move summary from implementation to interface to better respect standards and the fact that the interface is the more seen piece of code.
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, rename AcceptOrgUserByTokenAsync -> AcceptOrgUserByEmailTokenAsync + replace generic name token with emailToken
* PM-3275 - OrganizationService.cs - Per PR feedback, remove dupe line
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, remove new lines in error messages for consistency.
* PM-3275 - SetInitialMasterPasswordCommand.cs - Per PR feedback, adjust formatting of constructor for improved readability.
* PM-3275 - CurrentContextExtensions.cs - Refactor AnyOrgUserHasManageResetPasswordPermission per PR feedback to remove unnecessary var.
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, remove completed TODO
* PM-3275 - PoliciesController.cs - Per PR feedback, update GetByInvitedUser param to be guid instead of string.
* PM-3275 - OrgUserInviteTokenable.cs - per PR feedback, add tech debt item info.
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, use const purpose from tokenable instead of magic string.
* PM-3275 - Restore non duplicate line to fix tests
* PM-3275 - Per PR feedback, revert all sync controller changes as the ProfileResponseModel.organizations array has org objects which have permissions which have the ManageResetPassword permission. So, I have the information that I need clientside already to determine if the user has the ManageResetPassword in any org.
* PM-3275 - PoliciesControllerTests.cs - Update imports as the PoliciesController was moved under the admin console team's domain.
* PM-3275 - Resolve issues from merge conflict resolutions to get solution building.
* PM-3275 / PM-4633 - PoliciesController.cs - use orgUserId to look up user instead of orgId. Oops.
* Fix user service tests
* Resolve merge conflict
2023-11-02 11:02:25 -04:00
|
|
|
|
IUpdateOrganizationUserGroupsCommand updateOrganizationUserGroupsCommand,
|
|
|
|
|
|
IAcceptOrgUserCommand acceptOrgUserCommand)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2017-03-04 21:28:41 -05:00
|
|
|
|
_organizationRepository = organizationRepository;
|
|
|
|
|
|
_organizationUserRepository = organizationUserRepository;
|
|
|
|
|
|
_organizationService = organizationService;
|
|
|
|
|
|
_collectionRepository = collectionRepository;
|
2017-05-09 19:04:01 -04:00
|
|
|
|
_groupRepository = groupRepository;
|
2017-03-04 21:28:41 -05:00
|
|
|
|
_userService = userService;
|
2022-06-08 08:44:28 -05:00
|
|
|
|
_policyRepository = policyRepository;
|
2017-04-05 16:29:46 -04:00
|
|
|
|
_currentContext = currentContext;
|
2023-08-05 07:51:12 +10:00
|
|
|
|
_countNewSmSeatsRequiredQuery = countNewSmSeatsRequiredQuery;
|
|
|
|
|
|
_updateSecretsManagerSubscriptionCommand = updateSecretsManagerSubscriptionCommand;
|
2023-09-01 09:10:02 +01:00
|
|
|
|
_updateOrganizationUserGroupsCommand = updateOrganizationUserGroupsCommand;
|
Auth/PM-3275 - Changes to support TDE User without MP being able to Set a Password + misc refactoring (#3242)
* PM-3275 - Add new GetMasterPasswordPolicy endpoint which will allow authenticated clients to get an enabled MP org policy if it exists for the purposes of enforcing those policy requirements when setting a password.
* PM-3275 - AccountsController.cs - PostSetPasswordAsync - (1) Convert UserService.setPasswordAsync into new SetInitialMasterPasswordCommand (2) Refactor SetInitialMasterPasswordCommand to only accept post SSO users who are in the invited state
(3) Add TODOs for more cleanup work and more commands
* PM-3275 - Update AccountsControllerTests.cs to add new SetInitialMasterPasswordCommand
* PM-3275 - UserService.cs - Remove non implemented ChangePasswordAsync method
* PM-3275 - The new SetInitialMasterPasswordCommand leveraged the OrganizationService.cs AcceptUserAsync method so while I was in here I converted the AcceptUserAsync methods into a new AcceptOrgUserCommand.cs and turned the private method which accepted an existing org user public for use in the SetInitialMasterPasswordCommand
* PM-3275 - Dotnet format
* PM-3275 - Test SetInitialMasterPasswordCommand
* Dotnet format
* PM-3275 - In process AcceptOrgUserCommandTests.cs
* PM-3275 - Migrate changes from AC-244 / #3199 over into new AcceptOrgUserCommand
* PM-3275 - AcceptOrgUserCommand.cs - create data protector specifically for this command
* PM-3275 - Add TODO for renaming / removing overloading of methods to improve readability / clarity
* PM-3275 - AcceptOrgUserCommand.cs - refactor AcceptOrgUserAsync by OrgId to retrieve orgUser with _organizationUserRepository.GetByOrganizationAsync which gets a single user instead of a collection
* PM-3275 - AcceptOrgUserCommand.cs - update name in TODO for evaluation later
* PM-3275 / PM-1196 - (1) Slightly refactor SsoEmail2faSessionTokenable to provide public static GetTokenLifeTime() method for testing (2) Add missed tests to SsoEmail2faSessionTokenable in preparation for building tests for new OrgUserInviteTokenable.cs
* PM-3275 / PM-1196 - Removing SsoEmail2faSessionTokenable.cs changes + tests as I've handled that separately in a new PR (#3270) for newly created task PM-3925
* PM-3275 - ExpiringTokenable.cs - add clarifying comments to help distinguish between the Valid property and the TokenIsValid method.
* PM-3275 - Create OrgUserInviteTokenable.cs and add tests in OrgUserInviteTokenableTests.cs
* PM-3275 - OrganizationService.cs - Refactor Org User Invite methods to use new OrgUserInviteTokenable instead of manual creation of a token
* PM-3275 - OrgUserInviteTokenable.cs - clarify backwards compat note
* PM-3275 - AcceptOrgUserCommand.cs - Add TODOs + minor name refactor
* PM-3275 - AcceptOrgUserCommand.cs - replace method overloading with more easily readable names.
* PM-3275 - AcceptOrgUserCommand.cs - Update ValidateOrgUserInviteToken to add new token validation while maintaining backwards compatibility for 1 release.
* dotnet format
* PM-3275 - AcceptOrgUserCommand.cs - Move private method below where it is used
* PM-3275 - ServiceCollectionExtensions.cs - Must register IDataProtectorTokenFactory<OrgUserInviteTokenable> for new tokenable
* PM-3275 - OrgUserInviteTokenable needed access to global settings to set its token lifetime to the _globalSettings.OrganizationInviteExpirationHours value. Creating a factory seemed the most straightforward way to encapsulate the desired creation logic. Unsure if in the correct location in ServiceCollectionExtensions.cs but will figure that out later.
* PM-3275 - In process work of creating AcceptOrgUserCommandTests.cs
* PM-3275 - Remove no longer relevant AcceptOrgUser tests from OrganizationServiceTests.cs
* PM-3275 - Register OrgUserInviteTokenableFactory alongside tokenizer
* PM-3275 - AcceptOrgUserCommandTests.cs - AcceptOrgUserAsync basic test suite completed.
* PM-3275 - AcceptOrgUserCommandTests.cs - tweak test names
* PM-3275 - AcceptOrgUserCommandTests.cs - (1) Remove old tests from OrganizationServiceTests as no longer needed to reference (2) Add summary for SetupCommonAcceptOrgUserMocks (3) Get AcceptOrgUserByToken_OldToken_AcceptsUserAndVerifiesEmail passing
* PM-3275 - Create interface for OrgUserInviteTokenableFactory b/c that's the right thing to do + enables test substitution
* PM-3275 - AcceptOrgUserCommandTests.cs - (1) Start work on AcceptOrgUserByToken_NewToken_AcceptsUserAndVerifiesEmail (2) Create and use SetupCommonAcceptOrgUserByTokenMocks() (3) Create generic FakeDataProtectorTokenFactory for tokenable testing
* PM-3275 - (1) Get AcceptOrgUserByToken_NewToken_AcceptsUserAndVerifiesEmail test passing (2) Move FakeDataProtectorTokenFactory to own file
* PM-3275 - AcceptOrgUserCommandTests.cs - Finish up tests for AcceptOrgUserByTokenAsync
* PM-3275 - Add pseudo section comments
* PM-3275 - Clean up unused params on AcceptOrgUserByToken_EmailMismatch_ThrowsBadRequest test
* PM-3275 - (1) Tests written for AcceptOrgUserByOrgSsoIdAsync (2) Refactor happy path assertions into helper function AssertValidAcceptedOrgUser to reduce code duplication
* PM-3275 - Finish up testing AcceptOrgUserCommandTests.cs by adding tests for AcceptOrgUserByOrgIdAsync
* PM-3275 - Tweaking test naming to ensure consistency.
* PM-3275 - Bugfix - OrgUserInviteTokenableFactory implementation required when declaring singleton service in ServiceCollectionExtensions.cs
* PM-3275 - Resolve failing OrganizationServiceTests.cs
* dotnet format
* PM-3275 - PoliciesController.cs - GetMasterPasswordPolicy bugfix - for orgs without a MP policy, policy comes back as null and we should return notFound in that case.
* PM-3275 - Add PoliciesControllerTests.cs specifically for new GetMasterPasswordPolicy(...) endpoint.
* PM-3275 - dotnet format PoliciesControllerTests.cs
* PM-3275 - PoliciesController.cs - (1) Add tech debt task number (2) Properly flag endpoint as deprecated
* PM-3275 - Add new hasManageResetPasswordPermission property to ProfileResponseModel.cs primarily for sync so that we can condition client side if TDE user obtains elevated permissions
* PM-3275 - Fix AccountsControllerTests.cs
* PM-3275 - OrgUserInviteTokenable.cs - clarify TODO
* PM-3275 - AcceptOrgUserCommand.cs - Refactor token validation to use short circuiting to only run old token validation if new token validation fails.
* PM-3275 - OrgUserInviteTokenable.cs - (1) Add new static methods to centralize validation logic to avoid repetition (2) Add new token validation method so we can avoid having to pass in a full org user (and hitting the db to do so)
* PM-3275 - Realized that the old token validation was used in the PoliciesController.cs (existing user clicks invite link in email and goes to log in) and UserService.cs (user clicks invite link in email and registers for a new acct). Added tech debt item for cleaning up backwards compatibility in future.
* dotnet format
* PM-3275 - (1) AccountsController.cs - Update PostSetPasswordAsync SetPasswordRequestModel to allow null keys for the case where we have a TDE user who obtains elevated permissions - they already have a user public and user encrypted private key saved in the db. (2) AccountsControllerTests.cs - test PostSetPasswordAsync scenarios to ensure changes will work as expected.
* PM-3275 - PR review feedback - (1) set CurrentContext to private (2) Refactor GetProfile to use variables to improve clarity and simplify debugging.
* PM-3275 - SyncController.cs - PR Review Feedback - Set current context as private instead of protected.
* PM-3275 - CurrentContextExtensions.cs - PR Feedback - move parenthesis up from own line.
* PM-3275 - SetInitialMasterPasswordCommandTests.cs - Replace unnecessary variable
* PM-3275 - SetInitialMasterPasswordCommandTests.cs - PR Feedback - Add expected outcome statement to test name
* PM-3275 - Set Initial Password command and tests - PR Feedback changes - (1) Rename orgIdentifier --> OrgSsoIdentifier for clarity (2) Update SetInitialMasterPasswordAsync to not allow null orgSsoId with explicit message saying this vs letting null org trigger invalid organization (3) Add test to cover this new scenario.
* PM-3275 - SetInitialMasterPasswordCommand.cs - Move summary from implementation to interface to better respect standards and the fact that the interface is the more seen piece of code.
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, rename AcceptOrgUserByTokenAsync -> AcceptOrgUserByEmailTokenAsync + replace generic name token with emailToken
* PM-3275 - OrganizationService.cs - Per PR feedback, remove dupe line
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, remove new lines in error messages for consistency.
* PM-3275 - SetInitialMasterPasswordCommand.cs - Per PR feedback, adjust formatting of constructor for improved readability.
* PM-3275 - CurrentContextExtensions.cs - Refactor AnyOrgUserHasManageResetPasswordPermission per PR feedback to remove unnecessary var.
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, remove completed TODO
* PM-3275 - PoliciesController.cs - Per PR feedback, update GetByInvitedUser param to be guid instead of string.
* PM-3275 - OrgUserInviteTokenable.cs - per PR feedback, add tech debt item info.
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, use const purpose from tokenable instead of magic string.
* PM-3275 - Restore non duplicate line to fix tests
* PM-3275 - Per PR feedback, revert all sync controller changes as the ProfileResponseModel.organizations array has org objects which have permissions which have the ManageResetPassword permission. So, I have the information that I need clientside already to determine if the user has the ManageResetPassword in any org.
* PM-3275 - PoliciesControllerTests.cs - Update imports as the PoliciesController was moved under the admin console team's domain.
* PM-3275 - Resolve issues from merge conflict resolutions to get solution building.
* PM-3275 / PM-4633 - PoliciesController.cs - use orgUserId to look up user instead of orgId. Oops.
* Fix user service tests
* Resolve merge conflict
2023-11-02 11:02:25 -04:00
|
|
|
|
_acceptOrgUserCommand = acceptOrgUserCommand;
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-03-04 21:28:41 -05:00
|
|
|
|
[HttpGet("{id}")]
|
2023-01-19 17:00:54 +01:00
|
|
|
|
public async Task<OrganizationUserDetailsResponseModel> Get(string id, bool includeGroups = false)
|
2017-03-04 21:28:41 -05:00
|
|
|
|
{
|
2023-06-16 16:38:58 +01:00
|
|
|
|
var organizationUser = await _organizationUserRepository.GetDetailsByIdWithCollectionsAsync(new Guid(id));
|
2017-03-23 00:17:34 -04:00
|
|
|
|
if (organizationUser == null || !await _currentContext.ManageUsers(organizationUser.Item1.OrganizationId))
|
2017-03-04 21:28:41 -05:00
|
|
|
|
{
|
2017-04-05 16:29:46 -04:00
|
|
|
|
throw new NotFoundException();
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-19 17:00:54 +01:00
|
|
|
|
var response = new OrganizationUserDetailsResponseModel(organizationUser.Item1, organizationUser.Item2);
|
|
|
|
|
|
|
|
|
|
|
|
if (includeGroups)
|
|
|
|
|
|
{
|
|
|
|
|
|
response.Groups = await _groupRepository.GetManyIdsByUserIdAsync(organizationUser.Item1.Id);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return response;
|
2017-04-05 16:29:46 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-09-23 06:36:08 -04:00
|
|
|
|
[HttpGet("")]
|
2023-01-19 17:00:54 +01:00
|
|
|
|
public async Task<ListResponseModel<OrganizationUserUserDetailsResponseModel>> Get(string orgId, bool includeGroups = false, bool includeCollections = false)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2021-09-23 06:36:08 -04:00
|
|
|
|
var orgGuidId = new Guid(orgId);
|
|
|
|
|
|
if (!await _currentContext.ViewAllCollections(orgGuidId) &&
|
|
|
|
|
|
!await _currentContext.ViewAssignedCollections(orgGuidId) &&
|
2021-07-08 17:05:32 +02:00
|
|
|
|
!await _currentContext.ManageGroups(orgGuidId) &&
|
2021-09-23 06:36:08 -04:00
|
|
|
|
!await _currentContext.ManageUsers(orgGuidId))
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new NotFoundException();
|
2017-03-04 21:28:41 -05:00
|
|
|
|
}
|
2021-12-16 15:35:09 +01:00
|
|
|
|
|
2023-01-19 17:00:54 +01:00
|
|
|
|
var organizationUsers = await _organizationUserRepository.GetManyDetailsByOrganizationAsync(orgGuidId, includeGroups, includeCollections);
|
2021-05-25 19:23:47 +02:00
|
|
|
|
var responseTasks = organizationUsers.Select(async o => new OrganizationUserUserDetailsResponseModel(o,
|
|
|
|
|
|
await _userService.TwoFactorIsEnabledAsync(o)));
|
2018-12-19 11:48:36 -05:00
|
|
|
|
var responses = await Task.WhenAll(responseTasks);
|
2021-05-25 19:23:47 +02:00
|
|
|
|
return new ListResponseModel<OrganizationUserUserDetailsResponseModel>(responses);
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-05-25 19:23:47 +02:00
|
|
|
|
[HttpGet("{id}/groups")]
|
|
|
|
|
|
public async Task<IEnumerable<string>> GetGroups(string orgId, string id)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2017-05-09 19:04:01 -04:00
|
|
|
|
var organizationUser = await _organizationUserRepository.GetByIdAsync(new Guid(id));
|
2021-05-25 19:23:47 +02:00
|
|
|
|
if (organizationUser == null || (!await _currentContext.ManageGroups(organizationUser.OrganizationId) &&
|
2021-07-08 17:05:32 +02:00
|
|
|
|
!await _currentContext.ManageUsers(organizationUser.OrganizationId)))
|
2021-05-12 11:18:25 +02:00
|
|
|
|
{
|
|
|
|
|
|
throw new NotFoundException();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-05-25 19:23:47 +02:00
|
|
|
|
var groupIds = await _groupRepository.GetManyIdsByUserIdAsync(organizationUser.Id);
|
|
|
|
|
|
var responses = groupIds.Select(g => g.ToString());
|
|
|
|
|
|
return responses;
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-04-20 16:58:57 -05:00
|
|
|
|
[HttpGet("{id}/reset-password-details")]
|
2021-05-25 19:23:47 +02:00
|
|
|
|
public async Task<OrganizationUserResetPasswordDetailsResponseModel> GetResetPasswordDetails(string orgId, string id)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2021-05-25 19:23:47 +02:00
|
|
|
|
// Make sure the calling user can reset passwords for this org
|
|
|
|
|
|
var orgGuidId = new Guid(orgId);
|
|
|
|
|
|
if (!await _currentContext.ManageResetPassword(orgGuidId))
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2021-05-25 19:23:47 +02:00
|
|
|
|
throw new NotFoundException();
|
2021-05-12 11:18:25 +02:00
|
|
|
|
}
|
2017-03-04 21:28:41 -05:00
|
|
|
|
|
2017-03-23 00:17:34 -04:00
|
|
|
|
var organizationUser = await _organizationUserRepository.GetByIdAsync(new Guid(id));
|
|
|
|
|
|
if (organizationUser == null || !organizationUser.UserId.HasValue)
|
|
|
|
|
|
{
|
2017-04-05 16:29:46 -04:00
|
|
|
|
throw new NotFoundException();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Retrieve data necessary for response (KDF, KDF Iterations, ResetPasswordKey)
|
|
|
|
|
|
// TODO Reset Password - Revisit this and create SPROC to reduce DB calls
|
|
|
|
|
|
var user = await _userService.GetUserByIdAsync(organizationUser.UserId.Value);
|
2021-04-20 16:58:57 -05:00
|
|
|
|
if (user == null)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2017-04-05 16:29:46 -04:00
|
|
|
|
throw new NotFoundException();
|
2017-03-23 00:17:34 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-06-08 08:44:28 -05:00
|
|
|
|
// Retrieve Encrypted Private Key from organization
|
|
|
|
|
|
var org = await _organizationRepository.GetByIdAsync(orgGuidId);
|
|
|
|
|
|
if (org == null)
|
2017-03-04 21:28:41 -05:00
|
|
|
|
{
|
2017-06-02 13:17:46 -04:00
|
|
|
|
throw new NotFoundException();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-06-09 18:57:56 -05:00
|
|
|
|
return new OrganizationUserResetPasswordDetailsResponseModel(new OrganizationUserResetPasswordDetails(organizationUser, user, org));
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2022-06-08 08:44:28 -05:00
|
|
|
|
|
|
|
|
|
|
[HttpPost("invite")]
|
|
|
|
|
|
public async Task Invite(string orgId, [FromBody] OrganizationUserInviteRequestModel model)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2022-06-08 08:44:28 -05:00
|
|
|
|
var orgGuidId = new Guid(orgId);
|
|
|
|
|
|
if (!await _currentContext.ManageUsers(orgGuidId))
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2022-06-08 08:44:28 -05:00
|
|
|
|
throw new NotFoundException();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var userId = _userService.GetProperUserId(User);
|
|
|
|
|
|
var result = await _organizationService.InviteUsersAsync(orgGuidId, userId.Value,
|
|
|
|
|
|
new (OrganizationUserInvite, string)[] { (new OrganizationUserInvite(model.ToData()), null) });
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2022-06-08 08:44:28 -05:00
|
|
|
|
|
|
|
|
|
|
[HttpPost("reinvite")]
|
|
|
|
|
|
public async Task<ListResponseModel<OrganizationUserBulkResponseModel>> BulkReinvite(string orgId, [FromBody] OrganizationUserBulkRequestModel model)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2022-06-08 08:44:28 -05:00
|
|
|
|
var orgGuidId = new Guid(orgId);
|
|
|
|
|
|
if (!await _currentContext.ManageUsers(orgGuidId))
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2022-06-08 08:44:28 -05:00
|
|
|
|
throw new NotFoundException();
|
2017-03-04 21:28:41 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-03-23 00:17:34 -04:00
|
|
|
|
var userId = _userService.GetProperUserId(User);
|
2020-03-09 15:13:40 -04:00
|
|
|
|
var result = await _organizationService.ResendInvitesAsync(orgGuidId, userId.Value, model.Ids);
|
|
|
|
|
|
return new ListResponseModel<OrganizationUserBulkResponseModel>(
|
2017-03-23 00:17:34 -04:00
|
|
|
|
result.Select(t => new OrganizationUserBulkResponseModel(t.Item1.Id, t.Item2)));
|
2017-03-04 21:28:41 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-03-23 00:17:34 -04:00
|
|
|
|
[HttpPost("{id}/reinvite")]
|
2017-04-05 16:29:46 -04:00
|
|
|
|
public async Task Reinvite(string orgId, string id)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2017-04-05 16:29:46 -04:00
|
|
|
|
var orgGuidId = new Guid(orgId);
|
|
|
|
|
|
if (!await _currentContext.ManageUsers(orgGuidId))
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2017-04-05 16:29:46 -04:00
|
|
|
|
throw new NotFoundException();
|
2021-05-25 19:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-04-05 16:29:46 -04:00
|
|
|
|
var userId = _userService.GetProperUserId(User);
|
2021-05-25 19:23:47 +02:00
|
|
|
|
await _organizationService.ResendInviteAsync(orgGuidId, userId.Value, new Guid(id));
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-04-14 11:13:16 +01:00
|
|
|
|
[HttpPost("{organizationUserId}/accept-init")]
|
|
|
|
|
|
public async Task AcceptInit(Guid orgId, Guid organizationUserId, [FromBody] OrganizationUserAcceptInitRequestModel model)
|
|
|
|
|
|
{
|
|
|
|
|
|
var user = await _userService.GetUserByPrincipalAsync(User);
|
|
|
|
|
|
if (user == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new UnauthorizedAccessException();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await _organizationService.InitPendingOrganization(user.Id, orgId, model.Keys.PublicKey, model.Keys.EncryptedPrivateKey, model.CollectionName);
|
Auth/PM-3275 - Changes to support TDE User without MP being able to Set a Password + misc refactoring (#3242)
* PM-3275 - Add new GetMasterPasswordPolicy endpoint which will allow authenticated clients to get an enabled MP org policy if it exists for the purposes of enforcing those policy requirements when setting a password.
* PM-3275 - AccountsController.cs - PostSetPasswordAsync - (1) Convert UserService.setPasswordAsync into new SetInitialMasterPasswordCommand (2) Refactor SetInitialMasterPasswordCommand to only accept post SSO users who are in the invited state
(3) Add TODOs for more cleanup work and more commands
* PM-3275 - Update AccountsControllerTests.cs to add new SetInitialMasterPasswordCommand
* PM-3275 - UserService.cs - Remove non implemented ChangePasswordAsync method
* PM-3275 - The new SetInitialMasterPasswordCommand leveraged the OrganizationService.cs AcceptUserAsync method so while I was in here I converted the AcceptUserAsync methods into a new AcceptOrgUserCommand.cs and turned the private method which accepted an existing org user public for use in the SetInitialMasterPasswordCommand
* PM-3275 - Dotnet format
* PM-3275 - Test SetInitialMasterPasswordCommand
* Dotnet format
* PM-3275 - In process AcceptOrgUserCommandTests.cs
* PM-3275 - Migrate changes from AC-244 / #3199 over into new AcceptOrgUserCommand
* PM-3275 - AcceptOrgUserCommand.cs - create data protector specifically for this command
* PM-3275 - Add TODO for renaming / removing overloading of methods to improve readability / clarity
* PM-3275 - AcceptOrgUserCommand.cs - refactor AcceptOrgUserAsync by OrgId to retrieve orgUser with _organizationUserRepository.GetByOrganizationAsync which gets a single user instead of a collection
* PM-3275 - AcceptOrgUserCommand.cs - update name in TODO for evaluation later
* PM-3275 / PM-1196 - (1) Slightly refactor SsoEmail2faSessionTokenable to provide public static GetTokenLifeTime() method for testing (2) Add missed tests to SsoEmail2faSessionTokenable in preparation for building tests for new OrgUserInviteTokenable.cs
* PM-3275 / PM-1196 - Removing SsoEmail2faSessionTokenable.cs changes + tests as I've handled that separately in a new PR (#3270) for newly created task PM-3925
* PM-3275 - ExpiringTokenable.cs - add clarifying comments to help distinguish between the Valid property and the TokenIsValid method.
* PM-3275 - Create OrgUserInviteTokenable.cs and add tests in OrgUserInviteTokenableTests.cs
* PM-3275 - OrganizationService.cs - Refactor Org User Invite methods to use new OrgUserInviteTokenable instead of manual creation of a token
* PM-3275 - OrgUserInviteTokenable.cs - clarify backwards compat note
* PM-3275 - AcceptOrgUserCommand.cs - Add TODOs + minor name refactor
* PM-3275 - AcceptOrgUserCommand.cs - replace method overloading with more easily readable names.
* PM-3275 - AcceptOrgUserCommand.cs - Update ValidateOrgUserInviteToken to add new token validation while maintaining backwards compatibility for 1 release.
* dotnet format
* PM-3275 - AcceptOrgUserCommand.cs - Move private method below where it is used
* PM-3275 - ServiceCollectionExtensions.cs - Must register IDataProtectorTokenFactory<OrgUserInviteTokenable> for new tokenable
* PM-3275 - OrgUserInviteTokenable needed access to global settings to set its token lifetime to the _globalSettings.OrganizationInviteExpirationHours value. Creating a factory seemed the most straightforward way to encapsulate the desired creation logic. Unsure if in the correct location in ServiceCollectionExtensions.cs but will figure that out later.
* PM-3275 - In process work of creating AcceptOrgUserCommandTests.cs
* PM-3275 - Remove no longer relevant AcceptOrgUser tests from OrganizationServiceTests.cs
* PM-3275 - Register OrgUserInviteTokenableFactory alongside tokenizer
* PM-3275 - AcceptOrgUserCommandTests.cs - AcceptOrgUserAsync basic test suite completed.
* PM-3275 - AcceptOrgUserCommandTests.cs - tweak test names
* PM-3275 - AcceptOrgUserCommandTests.cs - (1) Remove old tests from OrganizationServiceTests as no longer needed to reference (2) Add summary for SetupCommonAcceptOrgUserMocks (3) Get AcceptOrgUserByToken_OldToken_AcceptsUserAndVerifiesEmail passing
* PM-3275 - Create interface for OrgUserInviteTokenableFactory b/c that's the right thing to do + enables test substitution
* PM-3275 - AcceptOrgUserCommandTests.cs - (1) Start work on AcceptOrgUserByToken_NewToken_AcceptsUserAndVerifiesEmail (2) Create and use SetupCommonAcceptOrgUserByTokenMocks() (3) Create generic FakeDataProtectorTokenFactory for tokenable testing
* PM-3275 - (1) Get AcceptOrgUserByToken_NewToken_AcceptsUserAndVerifiesEmail test passing (2) Move FakeDataProtectorTokenFactory to own file
* PM-3275 - AcceptOrgUserCommandTests.cs - Finish up tests for AcceptOrgUserByTokenAsync
* PM-3275 - Add pseudo section comments
* PM-3275 - Clean up unused params on AcceptOrgUserByToken_EmailMismatch_ThrowsBadRequest test
* PM-3275 - (1) Tests written for AcceptOrgUserByOrgSsoIdAsync (2) Refactor happy path assertions into helper function AssertValidAcceptedOrgUser to reduce code duplication
* PM-3275 - Finish up testing AcceptOrgUserCommandTests.cs by adding tests for AcceptOrgUserByOrgIdAsync
* PM-3275 - Tweaking test naming to ensure consistency.
* PM-3275 - Bugfix - OrgUserInviteTokenableFactory implementation required when declaring singleton service in ServiceCollectionExtensions.cs
* PM-3275 - Resolve failing OrganizationServiceTests.cs
* dotnet format
* PM-3275 - PoliciesController.cs - GetMasterPasswordPolicy bugfix - for orgs without a MP policy, policy comes back as null and we should return notFound in that case.
* PM-3275 - Add PoliciesControllerTests.cs specifically for new GetMasterPasswordPolicy(...) endpoint.
* PM-3275 - dotnet format PoliciesControllerTests.cs
* PM-3275 - PoliciesController.cs - (1) Add tech debt task number (2) Properly flag endpoint as deprecated
* PM-3275 - Add new hasManageResetPasswordPermission property to ProfileResponseModel.cs primarily for sync so that we can condition client side if TDE user obtains elevated permissions
* PM-3275 - Fix AccountsControllerTests.cs
* PM-3275 - OrgUserInviteTokenable.cs - clarify TODO
* PM-3275 - AcceptOrgUserCommand.cs - Refactor token validation to use short circuiting to only run old token validation if new token validation fails.
* PM-3275 - OrgUserInviteTokenable.cs - (1) Add new static methods to centralize validation logic to avoid repetition (2) Add new token validation method so we can avoid having to pass in a full org user (and hitting the db to do so)
* PM-3275 - Realized that the old token validation was used in the PoliciesController.cs (existing user clicks invite link in email and goes to log in) and UserService.cs (user clicks invite link in email and registers for a new acct). Added tech debt item for cleaning up backwards compatibility in future.
* dotnet format
* PM-3275 - (1) AccountsController.cs - Update PostSetPasswordAsync SetPasswordRequestModel to allow null keys for the case where we have a TDE user who obtains elevated permissions - they already have a user public and user encrypted private key saved in the db. (2) AccountsControllerTests.cs - test PostSetPasswordAsync scenarios to ensure changes will work as expected.
* PM-3275 - PR review feedback - (1) set CurrentContext to private (2) Refactor GetProfile to use variables to improve clarity and simplify debugging.
* PM-3275 - SyncController.cs - PR Review Feedback - Set current context as private instead of protected.
* PM-3275 - CurrentContextExtensions.cs - PR Feedback - move parenthesis up from own line.
* PM-3275 - SetInitialMasterPasswordCommandTests.cs - Replace unnecessary variable
* PM-3275 - SetInitialMasterPasswordCommandTests.cs - PR Feedback - Add expected outcome statement to test name
* PM-3275 - Set Initial Password command and tests - PR Feedback changes - (1) Rename orgIdentifier --> OrgSsoIdentifier for clarity (2) Update SetInitialMasterPasswordAsync to not allow null orgSsoId with explicit message saying this vs letting null org trigger invalid organization (3) Add test to cover this new scenario.
* PM-3275 - SetInitialMasterPasswordCommand.cs - Move summary from implementation to interface to better respect standards and the fact that the interface is the more seen piece of code.
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, rename AcceptOrgUserByTokenAsync -> AcceptOrgUserByEmailTokenAsync + replace generic name token with emailToken
* PM-3275 - OrganizationService.cs - Per PR feedback, remove dupe line
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, remove new lines in error messages for consistency.
* PM-3275 - SetInitialMasterPasswordCommand.cs - Per PR feedback, adjust formatting of constructor for improved readability.
* PM-3275 - CurrentContextExtensions.cs - Refactor AnyOrgUserHasManageResetPasswordPermission per PR feedback to remove unnecessary var.
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, remove completed TODO
* PM-3275 - PoliciesController.cs - Per PR feedback, update GetByInvitedUser param to be guid instead of string.
* PM-3275 - OrgUserInviteTokenable.cs - per PR feedback, add tech debt item info.
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, use const purpose from tokenable instead of magic string.
* PM-3275 - Restore non duplicate line to fix tests
* PM-3275 - Per PR feedback, revert all sync controller changes as the ProfileResponseModel.organizations array has org objects which have permissions which have the ManageResetPassword permission. So, I have the information that I need clientside already to determine if the user has the ManageResetPassword in any org.
* PM-3275 - PoliciesControllerTests.cs - Update imports as the PoliciesController was moved under the admin console team's domain.
* PM-3275 - Resolve issues from merge conflict resolutions to get solution building.
* PM-3275 / PM-4633 - PoliciesController.cs - use orgUserId to look up user instead of orgId. Oops.
* Fix user service tests
* Resolve merge conflict
2023-11-02 11:02:25 -04:00
|
|
|
|
await _acceptOrgUserCommand.AcceptOrgUserByEmailTokenAsync(organizationUserId, user, model.Token, _userService);
|
2023-04-14 11:13:16 +01:00
|
|
|
|
await _organizationService.ConfirmUserAsync(orgId, organizationUserId, model.Key, user.Id, _userService);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-05-25 19:23:47 +02:00
|
|
|
|
[HttpPost("{organizationUserId}/accept")]
|
|
|
|
|
|
public async Task Accept(Guid orgId, Guid organizationUserId, [FromBody] OrganizationUserAcceptRequestModel model)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2021-05-25 19:23:47 +02:00
|
|
|
|
var user = await _userService.GetUserByPrincipalAsync(User);
|
|
|
|
|
|
if (user == null)
|
2022-08-29 14:53:16 -04:00
|
|
|
|
{
|
2021-05-25 19:23:47 +02:00
|
|
|
|
throw new UnauthorizedAccessException();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var masterPasswordPolicy = await _policyRepository.GetByOrganizationIdTypeAsync(orgId, PolicyType.ResetPassword);
|
|
|
|
|
|
var useMasterPasswordPolicy = masterPasswordPolicy != null &&
|
2023-04-14 11:13:16 +01:00
|
|
|
|
masterPasswordPolicy.Enabled &&
|
|
|
|
|
|
masterPasswordPolicy.GetDataModel<ResetPasswordDataModel>().AutoEnrollEnabled;
|
|
|
|
|
|
if (useMasterPasswordPolicy && string.IsNullOrWhiteSpace(model.ResetPasswordKey))
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2021-05-25 19:23:47 +02:00
|
|
|
|
throw new BadRequestException(string.Empty, "Master Password reset is required, but not provided.");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
Auth/PM-3275 - Changes to support TDE User without MP being able to Set a Password + misc refactoring (#3242)
* PM-3275 - Add new GetMasterPasswordPolicy endpoint which will allow authenticated clients to get an enabled MP org policy if it exists for the purposes of enforcing those policy requirements when setting a password.
* PM-3275 - AccountsController.cs - PostSetPasswordAsync - (1) Convert UserService.setPasswordAsync into new SetInitialMasterPasswordCommand (2) Refactor SetInitialMasterPasswordCommand to only accept post SSO users who are in the invited state
(3) Add TODOs for more cleanup work and more commands
* PM-3275 - Update AccountsControllerTests.cs to add new SetInitialMasterPasswordCommand
* PM-3275 - UserService.cs - Remove non implemented ChangePasswordAsync method
* PM-3275 - The new SetInitialMasterPasswordCommand leveraged the OrganizationService.cs AcceptUserAsync method so while I was in here I converted the AcceptUserAsync methods into a new AcceptOrgUserCommand.cs and turned the private method which accepted an existing org user public for use in the SetInitialMasterPasswordCommand
* PM-3275 - Dotnet format
* PM-3275 - Test SetInitialMasterPasswordCommand
* Dotnet format
* PM-3275 - In process AcceptOrgUserCommandTests.cs
* PM-3275 - Migrate changes from AC-244 / #3199 over into new AcceptOrgUserCommand
* PM-3275 - AcceptOrgUserCommand.cs - create data protector specifically for this command
* PM-3275 - Add TODO for renaming / removing overloading of methods to improve readability / clarity
* PM-3275 - AcceptOrgUserCommand.cs - refactor AcceptOrgUserAsync by OrgId to retrieve orgUser with _organizationUserRepository.GetByOrganizationAsync which gets a single user instead of a collection
* PM-3275 - AcceptOrgUserCommand.cs - update name in TODO for evaluation later
* PM-3275 / PM-1196 - (1) Slightly refactor SsoEmail2faSessionTokenable to provide public static GetTokenLifeTime() method for testing (2) Add missed tests to SsoEmail2faSessionTokenable in preparation for building tests for new OrgUserInviteTokenable.cs
* PM-3275 / PM-1196 - Removing SsoEmail2faSessionTokenable.cs changes + tests as I've handled that separately in a new PR (#3270) for newly created task PM-3925
* PM-3275 - ExpiringTokenable.cs - add clarifying comments to help distinguish between the Valid property and the TokenIsValid method.
* PM-3275 - Create OrgUserInviteTokenable.cs and add tests in OrgUserInviteTokenableTests.cs
* PM-3275 - OrganizationService.cs - Refactor Org User Invite methods to use new OrgUserInviteTokenable instead of manual creation of a token
* PM-3275 - OrgUserInviteTokenable.cs - clarify backwards compat note
* PM-3275 - AcceptOrgUserCommand.cs - Add TODOs + minor name refactor
* PM-3275 - AcceptOrgUserCommand.cs - replace method overloading with more easily readable names.
* PM-3275 - AcceptOrgUserCommand.cs - Update ValidateOrgUserInviteToken to add new token validation while maintaining backwards compatibility for 1 release.
* dotnet format
* PM-3275 - AcceptOrgUserCommand.cs - Move private method below where it is used
* PM-3275 - ServiceCollectionExtensions.cs - Must register IDataProtectorTokenFactory<OrgUserInviteTokenable> for new tokenable
* PM-3275 - OrgUserInviteTokenable needed access to global settings to set its token lifetime to the _globalSettings.OrganizationInviteExpirationHours value. Creating a factory seemed the most straightforward way to encapsulate the desired creation logic. Unsure if in the correct location in ServiceCollectionExtensions.cs but will figure that out later.
* PM-3275 - In process work of creating AcceptOrgUserCommandTests.cs
* PM-3275 - Remove no longer relevant AcceptOrgUser tests from OrganizationServiceTests.cs
* PM-3275 - Register OrgUserInviteTokenableFactory alongside tokenizer
* PM-3275 - AcceptOrgUserCommandTests.cs - AcceptOrgUserAsync basic test suite completed.
* PM-3275 - AcceptOrgUserCommandTests.cs - tweak test names
* PM-3275 - AcceptOrgUserCommandTests.cs - (1) Remove old tests from OrganizationServiceTests as no longer needed to reference (2) Add summary for SetupCommonAcceptOrgUserMocks (3) Get AcceptOrgUserByToken_OldToken_AcceptsUserAndVerifiesEmail passing
* PM-3275 - Create interface for OrgUserInviteTokenableFactory b/c that's the right thing to do + enables test substitution
* PM-3275 - AcceptOrgUserCommandTests.cs - (1) Start work on AcceptOrgUserByToken_NewToken_AcceptsUserAndVerifiesEmail (2) Create and use SetupCommonAcceptOrgUserByTokenMocks() (3) Create generic FakeDataProtectorTokenFactory for tokenable testing
* PM-3275 - (1) Get AcceptOrgUserByToken_NewToken_AcceptsUserAndVerifiesEmail test passing (2) Move FakeDataProtectorTokenFactory to own file
* PM-3275 - AcceptOrgUserCommandTests.cs - Finish up tests for AcceptOrgUserByTokenAsync
* PM-3275 - Add pseudo section comments
* PM-3275 - Clean up unused params on AcceptOrgUserByToken_EmailMismatch_ThrowsBadRequest test
* PM-3275 - (1) Tests written for AcceptOrgUserByOrgSsoIdAsync (2) Refactor happy path assertions into helper function AssertValidAcceptedOrgUser to reduce code duplication
* PM-3275 - Finish up testing AcceptOrgUserCommandTests.cs by adding tests for AcceptOrgUserByOrgIdAsync
* PM-3275 - Tweaking test naming to ensure consistency.
* PM-3275 - Bugfix - OrgUserInviteTokenableFactory implementation required when declaring singleton service in ServiceCollectionExtensions.cs
* PM-3275 - Resolve failing OrganizationServiceTests.cs
* dotnet format
* PM-3275 - PoliciesController.cs - GetMasterPasswordPolicy bugfix - for orgs without a MP policy, policy comes back as null and we should return notFound in that case.
* PM-3275 - Add PoliciesControllerTests.cs specifically for new GetMasterPasswordPolicy(...) endpoint.
* PM-3275 - dotnet format PoliciesControllerTests.cs
* PM-3275 - PoliciesController.cs - (1) Add tech debt task number (2) Properly flag endpoint as deprecated
* PM-3275 - Add new hasManageResetPasswordPermission property to ProfileResponseModel.cs primarily for sync so that we can condition client side if TDE user obtains elevated permissions
* PM-3275 - Fix AccountsControllerTests.cs
* PM-3275 - OrgUserInviteTokenable.cs - clarify TODO
* PM-3275 - AcceptOrgUserCommand.cs - Refactor token validation to use short circuiting to only run old token validation if new token validation fails.
* PM-3275 - OrgUserInviteTokenable.cs - (1) Add new static methods to centralize validation logic to avoid repetition (2) Add new token validation method so we can avoid having to pass in a full org user (and hitting the db to do so)
* PM-3275 - Realized that the old token validation was used in the PoliciesController.cs (existing user clicks invite link in email and goes to log in) and UserService.cs (user clicks invite link in email and registers for a new acct). Added tech debt item for cleaning up backwards compatibility in future.
* dotnet format
* PM-3275 - (1) AccountsController.cs - Update PostSetPasswordAsync SetPasswordRequestModel to allow null keys for the case where we have a TDE user who obtains elevated permissions - they already have a user public and user encrypted private key saved in the db. (2) AccountsControllerTests.cs - test PostSetPasswordAsync scenarios to ensure changes will work as expected.
* PM-3275 - PR review feedback - (1) set CurrentContext to private (2) Refactor GetProfile to use variables to improve clarity and simplify debugging.
* PM-3275 - SyncController.cs - PR Review Feedback - Set current context as private instead of protected.
* PM-3275 - CurrentContextExtensions.cs - PR Feedback - move parenthesis up from own line.
* PM-3275 - SetInitialMasterPasswordCommandTests.cs - Replace unnecessary variable
* PM-3275 - SetInitialMasterPasswordCommandTests.cs - PR Feedback - Add expected outcome statement to test name
* PM-3275 - Set Initial Password command and tests - PR Feedback changes - (1) Rename orgIdentifier --> OrgSsoIdentifier for clarity (2) Update SetInitialMasterPasswordAsync to not allow null orgSsoId with explicit message saying this vs letting null org trigger invalid organization (3) Add test to cover this new scenario.
* PM-3275 - SetInitialMasterPasswordCommand.cs - Move summary from implementation to interface to better respect standards and the fact that the interface is the more seen piece of code.
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, rename AcceptOrgUserByTokenAsync -> AcceptOrgUserByEmailTokenAsync + replace generic name token with emailToken
* PM-3275 - OrganizationService.cs - Per PR feedback, remove dupe line
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, remove new lines in error messages for consistency.
* PM-3275 - SetInitialMasterPasswordCommand.cs - Per PR feedback, adjust formatting of constructor for improved readability.
* PM-3275 - CurrentContextExtensions.cs - Refactor AnyOrgUserHasManageResetPasswordPermission per PR feedback to remove unnecessary var.
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, remove completed TODO
* PM-3275 - PoliciesController.cs - Per PR feedback, update GetByInvitedUser param to be guid instead of string.
* PM-3275 - OrgUserInviteTokenable.cs - per PR feedback, add tech debt item info.
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, use const purpose from tokenable instead of magic string.
* PM-3275 - Restore non duplicate line to fix tests
* PM-3275 - Per PR feedback, revert all sync controller changes as the ProfileResponseModel.organizations array has org objects which have permissions which have the ManageResetPassword permission. So, I have the information that I need clientside already to determine if the user has the ManageResetPassword in any org.
* PM-3275 - PoliciesControllerTests.cs - Update imports as the PoliciesController was moved under the admin console team's domain.
* PM-3275 - Resolve issues from merge conflict resolutions to get solution building.
* PM-3275 / PM-4633 - PoliciesController.cs - use orgUserId to look up user instead of orgId. Oops.
* Fix user service tests
* Resolve merge conflict
2023-11-02 11:02:25 -04:00
|
|
|
|
await _acceptOrgUserCommand.AcceptOrgUserByEmailTokenAsync(organizationUserId, user, model.Token, _userService);
|
2017-04-05 16:29:46 -04:00
|
|
|
|
|
2017-03-09 23:58:43 -05:00
|
|
|
|
if (useMasterPasswordPolicy)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2017-03-09 23:58:43 -05:00
|
|
|
|
await _organizationService.UpdateUserResetPasswordEnrollmentAsync(orgId, user.Id, model.ResetPasswordKey, user.Id);
|
|
|
|
|
|
}
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2017-03-09 23:58:43 -05:00
|
|
|
|
|
2017-03-23 00:17:34 -04:00
|
|
|
|
[HttpPost("{id}/confirm")]
|
|
|
|
|
|
public async Task Confirm(string orgId, string id, [FromBody] OrganizationUserConfirmRequestModel model)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2017-04-05 16:29:46 -04:00
|
|
|
|
var orgGuidId = new Guid(orgId);
|
2017-03-23 00:17:34 -04:00
|
|
|
|
if (!await _currentContext.ManageUsers(orgGuidId))
|
2022-08-29 14:53:16 -04:00
|
|
|
|
{
|
2017-05-11 14:52:35 -04:00
|
|
|
|
throw new NotFoundException();
|
2017-03-09 23:58:43 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-05-09 19:04:01 -04:00
|
|
|
|
var userId = _userService.GetProperUserId(User);
|
|
|
|
|
|
var result = await _organizationService.ConfirmUserAsync(orgGuidId, new Guid(id), model.Key, userId.Value,
|
|
|
|
|
|
_userService);
|
2022-08-29 15:53:48 -04:00
|
|
|
|
}
|
2017-05-09 19:04:01 -04:00
|
|
|
|
|
2021-01-12 11:02:39 -05:00
|
|
|
|
[HttpPost("confirm")]
|
|
|
|
|
|
public async Task<ListResponseModel<OrganizationUserBulkResponseModel>> BulkConfirm(string orgId,
|
|
|
|
|
|
[FromBody] OrganizationUserBulkConfirmRequestModel model)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2021-01-12 11:02:39 -05:00
|
|
|
|
var orgGuidId = new Guid(orgId);
|
|
|
|
|
|
if (!await _currentContext.ManageUsers(orgGuidId))
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2021-01-12 11:02:39 -05:00
|
|
|
|
throw new NotFoundException();
|
2017-05-09 19:04:01 -04:00
|
|
|
|
}
|
2021-12-16 15:35:09 +01:00
|
|
|
|
|
2017-04-05 16:29:46 -04:00
|
|
|
|
var userId = _userService.GetProperUserId(User);
|
2017-03-04 21:28:41 -05:00
|
|
|
|
var results = await _organizationService.ConfirmUsersAsync(orgGuidId, model.ToDictionary(), userId.Value,
|
|
|
|
|
|
_userService);
|
2022-08-29 14:53:16 -04:00
|
|
|
|
|
2022-05-19 15:55:42 -04:00
|
|
|
|
return new ListResponseModel<OrganizationUserBulkResponseModel>(results.Select(r =>
|
|
|
|
|
|
new OrganizationUserBulkResponseModel(r.Item1.Id, r.Item2)));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-06-08 08:44:28 -05:00
|
|
|
|
[HttpPost("public-keys")]
|
2022-05-19 15:55:42 -04:00
|
|
|
|
public async Task<ListResponseModel<OrganizationUserPublicKeyResponseModel>> UserPublicKeys(string orgId, [FromBody] OrganizationUserBulkRequestModel model)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2021-05-25 19:23:47 +02:00
|
|
|
|
var orgGuidId = new Guid(orgId);
|
2022-05-19 15:55:42 -04:00
|
|
|
|
if (!await _currentContext.ManageUsers(orgGuidId))
|
2022-08-29 14:53:16 -04:00
|
|
|
|
{
|
2021-05-25 19:23:47 +02:00
|
|
|
|
throw new NotFoundException();
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-05-25 19:23:47 +02:00
|
|
|
|
var result = await _organizationUserRepository.GetManyPublicKeysByOrganizationUserAsync(orgGuidId, model.Ids);
|
2022-05-19 15:55:42 -04:00
|
|
|
|
var responses = result.Select(r => new OrganizationUserPublicKeyResponseModel(r.Id, r.UserId, r.PublicKey)).ToList();
|
|
|
|
|
|
return new ListResponseModel<OrganizationUserPublicKeyResponseModel>(responses);
|
2022-08-29 15:53:48 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-05-19 15:55:42 -04:00
|
|
|
|
[HttpPut("{id}")]
|
2022-07-25 10:47:44 +10:00
|
|
|
|
[HttpPost("{id}")]
|
|
|
|
|
|
public async Task Put(string orgId, string id, [FromBody] OrganizationUserUpdateRequestModel model)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2022-07-25 10:47:44 +10:00
|
|
|
|
var orgGuidId = new Guid(orgId);
|
|
|
|
|
|
if (!await _currentContext.ManageUsers(orgGuidId))
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2022-07-25 10:47:44 +10:00
|
|
|
|
throw new NotFoundException();
|
2021-03-30 09:48:52 -05:00
|
|
|
|
}
|
2021-12-16 15:35:09 +01:00
|
|
|
|
|
2021-04-20 16:58:57 -05:00
|
|
|
|
var organizationUser = await _organizationUserRepository.GetByIdAsync(new Guid(id));
|
|
|
|
|
|
if (organizationUser == null || organizationUser.OrganizationId != orgGuidId)
|
|
|
|
|
|
{
|
2020-03-27 14:36:37 -04:00
|
|
|
|
throw new NotFoundException();
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2021-12-16 15:35:09 +01:00
|
|
|
|
|
2021-10-14 17:44:20 +02:00
|
|
|
|
var userId = _userService.GetProperUserId(User);
|
|
|
|
|
|
await _organizationService.SaveUserAsync(model.ToOrganizationUser(organizationUser), userId.Value,
|
2023-01-19 17:00:54 +01:00
|
|
|
|
model.Collections?.Select(c => c.ToSelectionReadOnly()), model.Groups);
|
2021-04-20 16:58:57 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-03-30 09:48:52 -05:00
|
|
|
|
[HttpPut("{id}/groups")]
|
|
|
|
|
|
[HttpPost("{id}/groups")]
|
2021-04-20 16:58:57 -05:00
|
|
|
|
public async Task PutGroups(string orgId, string id, [FromBody] OrganizationUserUpdateGroupsRequestModel model)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2022-05-19 15:55:42 -04:00
|
|
|
|
var orgGuidId = new Guid(orgId);
|
2021-04-20 16:58:57 -05:00
|
|
|
|
if (!await _currentContext.ManageUsers(orgGuidId))
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2021-04-20 16:58:57 -05:00
|
|
|
|
throw new NotFoundException();
|
2021-05-19 09:40:32 -05:00
|
|
|
|
}
|
2017-05-09 19:04:01 -04:00
|
|
|
|
|
2017-03-04 21:28:41 -05:00
|
|
|
|
var organizationUser = await _organizationUserRepository.GetByIdAsync(new Guid(id));
|
|
|
|
|
|
if (organizationUser == null || organizationUser.OrganizationId != orgGuidId)
|
|
|
|
|
|
{
|
2017-04-05 16:29:46 -04:00
|
|
|
|
throw new NotFoundException();
|
2021-05-17 10:10:44 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var loggedInUserId = _userService.GetProperUserId(User);
|
2023-09-01 09:10:02 +01:00
|
|
|
|
await _updateOrganizationUserGroupsCommand.UpdateUserGroupsAsync(organizationUser, model.GroupIds.Select(g => new Guid(g)), loggedInUserId);
|
2022-08-29 15:53:48 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-07-25 10:47:44 +10:00
|
|
|
|
[HttpPut("{userId}/reset-password-enrollment")]
|
2023-08-17 16:03:06 -04:00
|
|
|
|
public async Task PutResetPasswordEnrollment(Guid orgId, Guid userId, [FromBody] OrganizationUserResetPasswordEnrollmentRequestModel model)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2021-05-25 19:23:47 +02:00
|
|
|
|
var user = await _userService.GetUserByPrincipalAsync(User);
|
2022-07-25 10:47:44 +10:00
|
|
|
|
if (user == null)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2022-06-16 15:59:57 -04:00
|
|
|
|
throw new UnauthorizedAccessException();
|
2021-05-17 10:10:44 +02:00
|
|
|
|
}
|
2022-06-16 15:59:57 -04:00
|
|
|
|
|
2023-08-17 16:03:06 -04:00
|
|
|
|
var callingUserId = user.Id;
|
|
|
|
|
|
await _organizationService.UpdateUserResetPasswordEnrollmentAsync(
|
|
|
|
|
|
orgId, userId, model.ResetPasswordKey, callingUserId);
|
|
|
|
|
|
|
|
|
|
|
|
var orgUser = await _organizationUserRepository.GetByOrganizationAsync(orgId, user.Id);
|
|
|
|
|
|
if (orgUser.Status == OrganizationUserStatusType.Invited)
|
2022-06-16 15:59:57 -04:00
|
|
|
|
{
|
Auth/PM-3275 - Changes to support TDE User without MP being able to Set a Password + misc refactoring (#3242)
* PM-3275 - Add new GetMasterPasswordPolicy endpoint which will allow authenticated clients to get an enabled MP org policy if it exists for the purposes of enforcing those policy requirements when setting a password.
* PM-3275 - AccountsController.cs - PostSetPasswordAsync - (1) Convert UserService.setPasswordAsync into new SetInitialMasterPasswordCommand (2) Refactor SetInitialMasterPasswordCommand to only accept post SSO users who are in the invited state
(3) Add TODOs for more cleanup work and more commands
* PM-3275 - Update AccountsControllerTests.cs to add new SetInitialMasterPasswordCommand
* PM-3275 - UserService.cs - Remove non implemented ChangePasswordAsync method
* PM-3275 - The new SetInitialMasterPasswordCommand leveraged the OrganizationService.cs AcceptUserAsync method so while I was in here I converted the AcceptUserAsync methods into a new AcceptOrgUserCommand.cs and turned the private method which accepted an existing org user public for use in the SetInitialMasterPasswordCommand
* PM-3275 - Dotnet format
* PM-3275 - Test SetInitialMasterPasswordCommand
* Dotnet format
* PM-3275 - In process AcceptOrgUserCommandTests.cs
* PM-3275 - Migrate changes from AC-244 / #3199 over into new AcceptOrgUserCommand
* PM-3275 - AcceptOrgUserCommand.cs - create data protector specifically for this command
* PM-3275 - Add TODO for renaming / removing overloading of methods to improve readability / clarity
* PM-3275 - AcceptOrgUserCommand.cs - refactor AcceptOrgUserAsync by OrgId to retrieve orgUser with _organizationUserRepository.GetByOrganizationAsync which gets a single user instead of a collection
* PM-3275 - AcceptOrgUserCommand.cs - update name in TODO for evaluation later
* PM-3275 / PM-1196 - (1) Slightly refactor SsoEmail2faSessionTokenable to provide public static GetTokenLifeTime() method for testing (2) Add missed tests to SsoEmail2faSessionTokenable in preparation for building tests for new OrgUserInviteTokenable.cs
* PM-3275 / PM-1196 - Removing SsoEmail2faSessionTokenable.cs changes + tests as I've handled that separately in a new PR (#3270) for newly created task PM-3925
* PM-3275 - ExpiringTokenable.cs - add clarifying comments to help distinguish between the Valid property and the TokenIsValid method.
* PM-3275 - Create OrgUserInviteTokenable.cs and add tests in OrgUserInviteTokenableTests.cs
* PM-3275 - OrganizationService.cs - Refactor Org User Invite methods to use new OrgUserInviteTokenable instead of manual creation of a token
* PM-3275 - OrgUserInviteTokenable.cs - clarify backwards compat note
* PM-3275 - AcceptOrgUserCommand.cs - Add TODOs + minor name refactor
* PM-3275 - AcceptOrgUserCommand.cs - replace method overloading with more easily readable names.
* PM-3275 - AcceptOrgUserCommand.cs - Update ValidateOrgUserInviteToken to add new token validation while maintaining backwards compatibility for 1 release.
* dotnet format
* PM-3275 - AcceptOrgUserCommand.cs - Move private method below where it is used
* PM-3275 - ServiceCollectionExtensions.cs - Must register IDataProtectorTokenFactory<OrgUserInviteTokenable> for new tokenable
* PM-3275 - OrgUserInviteTokenable needed access to global settings to set its token lifetime to the _globalSettings.OrganizationInviteExpirationHours value. Creating a factory seemed the most straightforward way to encapsulate the desired creation logic. Unsure if in the correct location in ServiceCollectionExtensions.cs but will figure that out later.
* PM-3275 - In process work of creating AcceptOrgUserCommandTests.cs
* PM-3275 - Remove no longer relevant AcceptOrgUser tests from OrganizationServiceTests.cs
* PM-3275 - Register OrgUserInviteTokenableFactory alongside tokenizer
* PM-3275 - AcceptOrgUserCommandTests.cs - AcceptOrgUserAsync basic test suite completed.
* PM-3275 - AcceptOrgUserCommandTests.cs - tweak test names
* PM-3275 - AcceptOrgUserCommandTests.cs - (1) Remove old tests from OrganizationServiceTests as no longer needed to reference (2) Add summary for SetupCommonAcceptOrgUserMocks (3) Get AcceptOrgUserByToken_OldToken_AcceptsUserAndVerifiesEmail passing
* PM-3275 - Create interface for OrgUserInviteTokenableFactory b/c that's the right thing to do + enables test substitution
* PM-3275 - AcceptOrgUserCommandTests.cs - (1) Start work on AcceptOrgUserByToken_NewToken_AcceptsUserAndVerifiesEmail (2) Create and use SetupCommonAcceptOrgUserByTokenMocks() (3) Create generic FakeDataProtectorTokenFactory for tokenable testing
* PM-3275 - (1) Get AcceptOrgUserByToken_NewToken_AcceptsUserAndVerifiesEmail test passing (2) Move FakeDataProtectorTokenFactory to own file
* PM-3275 - AcceptOrgUserCommandTests.cs - Finish up tests for AcceptOrgUserByTokenAsync
* PM-3275 - Add pseudo section comments
* PM-3275 - Clean up unused params on AcceptOrgUserByToken_EmailMismatch_ThrowsBadRequest test
* PM-3275 - (1) Tests written for AcceptOrgUserByOrgSsoIdAsync (2) Refactor happy path assertions into helper function AssertValidAcceptedOrgUser to reduce code duplication
* PM-3275 - Finish up testing AcceptOrgUserCommandTests.cs by adding tests for AcceptOrgUserByOrgIdAsync
* PM-3275 - Tweaking test naming to ensure consistency.
* PM-3275 - Bugfix - OrgUserInviteTokenableFactory implementation required when declaring singleton service in ServiceCollectionExtensions.cs
* PM-3275 - Resolve failing OrganizationServiceTests.cs
* dotnet format
* PM-3275 - PoliciesController.cs - GetMasterPasswordPolicy bugfix - for orgs without a MP policy, policy comes back as null and we should return notFound in that case.
* PM-3275 - Add PoliciesControllerTests.cs specifically for new GetMasterPasswordPolicy(...) endpoint.
* PM-3275 - dotnet format PoliciesControllerTests.cs
* PM-3275 - PoliciesController.cs - (1) Add tech debt task number (2) Properly flag endpoint as deprecated
* PM-3275 - Add new hasManageResetPasswordPermission property to ProfileResponseModel.cs primarily for sync so that we can condition client side if TDE user obtains elevated permissions
* PM-3275 - Fix AccountsControllerTests.cs
* PM-3275 - OrgUserInviteTokenable.cs - clarify TODO
* PM-3275 - AcceptOrgUserCommand.cs - Refactor token validation to use short circuiting to only run old token validation if new token validation fails.
* PM-3275 - OrgUserInviteTokenable.cs - (1) Add new static methods to centralize validation logic to avoid repetition (2) Add new token validation method so we can avoid having to pass in a full org user (and hitting the db to do so)
* PM-3275 - Realized that the old token validation was used in the PoliciesController.cs (existing user clicks invite link in email and goes to log in) and UserService.cs (user clicks invite link in email and registers for a new acct). Added tech debt item for cleaning up backwards compatibility in future.
* dotnet format
* PM-3275 - (1) AccountsController.cs - Update PostSetPasswordAsync SetPasswordRequestModel to allow null keys for the case where we have a TDE user who obtains elevated permissions - they already have a user public and user encrypted private key saved in the db. (2) AccountsControllerTests.cs - test PostSetPasswordAsync scenarios to ensure changes will work as expected.
* PM-3275 - PR review feedback - (1) set CurrentContext to private (2) Refactor GetProfile to use variables to improve clarity and simplify debugging.
* PM-3275 - SyncController.cs - PR Review Feedback - Set current context as private instead of protected.
* PM-3275 - CurrentContextExtensions.cs - PR Feedback - move parenthesis up from own line.
* PM-3275 - SetInitialMasterPasswordCommandTests.cs - Replace unnecessary variable
* PM-3275 - SetInitialMasterPasswordCommandTests.cs - PR Feedback - Add expected outcome statement to test name
* PM-3275 - Set Initial Password command and tests - PR Feedback changes - (1) Rename orgIdentifier --> OrgSsoIdentifier for clarity (2) Update SetInitialMasterPasswordAsync to not allow null orgSsoId with explicit message saying this vs letting null org trigger invalid organization (3) Add test to cover this new scenario.
* PM-3275 - SetInitialMasterPasswordCommand.cs - Move summary from implementation to interface to better respect standards and the fact that the interface is the more seen piece of code.
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, rename AcceptOrgUserByTokenAsync -> AcceptOrgUserByEmailTokenAsync + replace generic name token with emailToken
* PM-3275 - OrganizationService.cs - Per PR feedback, remove dupe line
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, remove new lines in error messages for consistency.
* PM-3275 - SetInitialMasterPasswordCommand.cs - Per PR feedback, adjust formatting of constructor for improved readability.
* PM-3275 - CurrentContextExtensions.cs - Refactor AnyOrgUserHasManageResetPasswordPermission per PR feedback to remove unnecessary var.
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, remove completed TODO
* PM-3275 - PoliciesController.cs - Per PR feedback, update GetByInvitedUser param to be guid instead of string.
* PM-3275 - OrgUserInviteTokenable.cs - per PR feedback, add tech debt item info.
* PM-3275 - AcceptOrgUserCommand.cs - Per PR feedback, use const purpose from tokenable instead of magic string.
* PM-3275 - Restore non duplicate line to fix tests
* PM-3275 - Per PR feedback, revert all sync controller changes as the ProfileResponseModel.organizations array has org objects which have permissions which have the ManageResetPassword permission. So, I have the information that I need clientside already to determine if the user has the ManageResetPassword in any org.
* PM-3275 - PoliciesControllerTests.cs - Update imports as the PoliciesController was moved under the admin console team's domain.
* PM-3275 - Resolve issues from merge conflict resolutions to get solution building.
* PM-3275 / PM-4633 - PoliciesController.cs - use orgUserId to look up user instead of orgId. Oops.
* Fix user service tests
* Resolve merge conflict
2023-11-02 11:02:25 -04:00
|
|
|
|
await _acceptOrgUserCommand.AcceptOrgUserByOrgIdAsync(orgId, user, _userService);
|
2022-06-16 15:59:57 -04:00
|
|
|
|
}
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-04-20 16:58:57 -05:00
|
|
|
|
[HttpPut("{id}/reset-password")]
|
2021-03-30 09:48:52 -05:00
|
|
|
|
public async Task PutResetPassword(string orgId, string id, [FromBody] OrganizationUserResetPasswordRequestModel model)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2022-06-16 15:59:57 -04:00
|
|
|
|
|
|
|
|
|
|
var orgGuidId = new Guid(orgId);
|
2022-08-29 16:06:55 -04:00
|
|
|
|
|
2022-06-16 15:59:57 -04:00
|
|
|
|
// Calling user must have Manage Reset Password permission
|
|
|
|
|
|
if (!await _currentContext.ManageResetPassword(orgGuidId))
|
|
|
|
|
|
{
|
2022-07-25 10:47:44 +10:00
|
|
|
|
throw new NotFoundException();
|
2022-06-16 15:59:57 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Get the users role, since provider users aren't a member of the organization we use the owner check
|
|
|
|
|
|
var orgUserType = await _currentContext.OrganizationOwner(orgGuidId)
|
|
|
|
|
|
? OrganizationUserType.Owner
|
|
|
|
|
|
: _currentContext.Organizations?.FirstOrDefault(o => o.Id == orgGuidId)?.Type;
|
|
|
|
|
|
if (orgUserType == null)
|
|
|
|
|
|
{
|
2022-07-25 10:47:44 +10:00
|
|
|
|
throw new NotFoundException();
|
2022-06-16 15:59:57 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-07-25 10:47:44 +10:00
|
|
|
|
var result = await _userService.AdminResetPasswordAsync(orgUserType.Value, orgGuidId, new Guid(id), model.NewMasterPasswordHash, model.Key);
|
|
|
|
|
|
if (result.Succeeded)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var error in result.Errors)
|
|
|
|
|
|
{
|
|
|
|
|
|
ModelState.AddModelError(string.Empty, error.Description);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-04-20 16:58:57 -05:00
|
|
|
|
await Task.Delay(2000);
|
2022-07-25 10:47:44 +10:00
|
|
|
|
throw new BadRequestException(ModelState);
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-07-25 10:47:44 +10:00
|
|
|
|
[HttpDelete("{id}")]
|
|
|
|
|
|
[HttpPost("{id}/delete")]
|
|
|
|
|
|
public async Task Delete(string orgId, string id)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2022-07-25 10:47:44 +10:00
|
|
|
|
var orgGuidId = new Guid(orgId);
|
|
|
|
|
|
if (!await _currentContext.ManageUsers(orgGuidId))
|
|
|
|
|
|
{
|
2022-08-03 07:09:22 +10:00
|
|
|
|
throw new NotFoundException();
|
2022-07-25 10:47:44 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-05-17 10:10:44 +02:00
|
|
|
|
var userId = _userService.GetProperUserId(User);
|
2022-07-25 10:47:44 +10:00
|
|
|
|
await _organizationService.DeleteUserAsync(orgGuidId, new Guid(id), userId.Value);
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-05-17 10:10:44 +02:00
|
|
|
|
[HttpDelete("")]
|
2017-03-04 21:28:41 -05:00
|
|
|
|
[HttpPost("delete")]
|
2022-07-25 10:47:44 +10:00
|
|
|
|
public async Task<ListResponseModel<OrganizationUserBulkResponseModel>> BulkDelete(string orgId, [FromBody] OrganizationUserBulkRequestModel model)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2022-07-25 10:47:44 +10:00
|
|
|
|
var orgGuidId = new Guid(orgId);
|
|
|
|
|
|
if (!await _currentContext.ManageUsers(orgGuidId))
|
|
|
|
|
|
{
|
2022-08-03 07:09:22 +10:00
|
|
|
|
throw new NotFoundException();
|
2022-07-25 10:47:44 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var userId = _userService.GetProperUserId(User);
|
|
|
|
|
|
var result = await _organizationService.DeleteUsersAsync(orgGuidId, model.Ids, userId.Value);
|
|
|
|
|
|
return new ListResponseModel<OrganizationUserBulkResponseModel>(result.Select(r =>
|
2022-06-16 15:59:57 -04:00
|
|
|
|
new OrganizationUserBulkResponseModel(r.Item1.Id, r.Item2)));
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-08-03 07:09:22 +10:00
|
|
|
|
[HttpPatch("{id}/revoke")]
|
2022-07-25 10:47:44 +10:00
|
|
|
|
[HttpPut("{id}/revoke")]
|
2022-08-03 07:09:22 +10:00
|
|
|
|
public async Task RevokeAsync(Guid orgId, Guid id)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2022-08-03 07:09:22 +10:00
|
|
|
|
await RestoreOrRevokeUserAsync(orgId, id, _organizationService.RevokeUserAsync);
|
2022-08-29 14:53:16 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-07-25 10:47:44 +10:00
|
|
|
|
[HttpPatch("revoke")]
|
|
|
|
|
|
[HttpPut("revoke")]
|
2022-06-16 15:59:57 -04:00
|
|
|
|
public async Task<ListResponseModel<OrganizationUserBulkResponseModel>> BulkRevokeAsync(Guid orgId, [FromBody] OrganizationUserBulkRequestModel model)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2022-06-16 15:59:57 -04:00
|
|
|
|
return await RestoreOrRevokeUsersAsync(orgId, model, _organizationService.RevokeUsersAsync);
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-07-25 10:47:44 +10:00
|
|
|
|
[HttpPatch("{id}/restore")]
|
2021-04-20 16:58:57 -05:00
|
|
|
|
[HttpPut("{id}/restore")]
|
2022-07-25 10:47:44 +10:00
|
|
|
|
public async Task RestoreAsync(Guid orgId, Guid id)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2022-06-16 15:59:57 -04:00
|
|
|
|
await RestoreOrRevokeUserAsync(orgId, id, (orgUser, userId) => _organizationService.RestoreUserAsync(orgUser, userId, _userService));
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-05-17 10:10:44 +02:00
|
|
|
|
[HttpPatch("restore")]
|
2018-07-16 17:32:08 -04:00
|
|
|
|
[HttpPut("restore")]
|
2022-07-25 10:47:44 +10:00
|
|
|
|
public async Task<ListResponseModel<OrganizationUserBulkResponseModel>> BulkRestoreAsync(Guid orgId, [FromBody] OrganizationUserBulkRequestModel model)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2022-08-03 07:09:22 +10:00
|
|
|
|
return await RestoreOrRevokeUsersAsync(orgId, model, (orgId, orgUserIds, restoringUserId) => _organizationService.RestoreUsersAsync(orgId, orgUserIds, restoringUserId, _userService));
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-06-29 11:42:44 -05:00
|
|
|
|
[HttpPatch("enable-secrets-manager")]
|
|
|
|
|
|
[HttpPut("enable-secrets-manager")]
|
2023-08-05 07:51:12 +10:00
|
|
|
|
public async Task BulkEnableSecretsManagerAsync(Guid orgId,
|
2023-06-29 11:42:44 -05:00
|
|
|
|
[FromBody] OrganizationUserBulkRequestModel model)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!await _currentContext.ManageUsers(orgId))
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new NotFoundException();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var orgUsers = (await _organizationUserRepository.GetManyAsync(model.Ids))
|
2023-08-05 07:51:12 +10:00
|
|
|
|
.Where(ou => ou.OrganizationId == orgId && !ou.AccessSecretsManager).ToList();
|
2023-06-29 11:42:44 -05:00
|
|
|
|
if (orgUsers.Count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new BadRequestException("Users invalid.");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-08-05 07:51:12 +10:00
|
|
|
|
var additionalSmSeatsRequired = await _countNewSmSeatsRequiredQuery.CountNewSmSeatsRequiredAsync(orgId,
|
|
|
|
|
|
orgUsers.Count);
|
|
|
|
|
|
if (additionalSmSeatsRequired > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
var organization = await _organizationRepository.GetByIdAsync(orgId);
|
2023-08-28 08:05:23 +10:00
|
|
|
|
var update = new SecretsManagerSubscriptionUpdate(organization, true)
|
|
|
|
|
|
.AdjustSeats(additionalSmSeatsRequired);
|
2023-08-05 07:51:12 +10:00
|
|
|
|
await _updateSecretsManagerSubscriptionCommand.UpdateSubscriptionAsync(update);
|
|
|
|
|
|
}
|
2023-06-29 11:42:44 -05:00
|
|
|
|
|
2023-08-05 07:51:12 +10:00
|
|
|
|
foreach (var orgUser in orgUsers)
|
|
|
|
|
|
{
|
|
|
|
|
|
orgUser.AccessSecretsManager = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await _organizationUserRepository.ReplaceManyAsync(orgUsers);
|
2023-06-29 11:42:44 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-07-25 10:47:44 +10:00
|
|
|
|
private async Task RestoreOrRevokeUserAsync(
|
|
|
|
|
|
Guid orgId,
|
2022-08-29 16:06:55 -04:00
|
|
|
|
Guid id,
|
2023-08-17 16:03:06 -04:00
|
|
|
|
Func<Core.Entities.OrganizationUser, Guid?, Task> statusAction)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2022-06-16 15:59:57 -04:00
|
|
|
|
if (!await _currentContext.ManageUsers(orgId))
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2022-06-16 15:59:57 -04:00
|
|
|
|
throw new NotFoundException();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-07-25 10:47:44 +10:00
|
|
|
|
var userId = _userService.GetProperUserId(User);
|
|
|
|
|
|
var orgUser = await _organizationUserRepository.GetByIdAsync(id);
|
2022-06-16 15:59:57 -04:00
|
|
|
|
if (orgUser == null || orgUser.OrganizationId != orgId)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new NotFoundException();
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-06-16 15:59:57 -04:00
|
|
|
|
await statusAction(orgUser, userId);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async Task<ListResponseModel<OrganizationUserBulkResponseModel>> RestoreOrRevokeUsersAsync(
|
|
|
|
|
|
Guid orgId,
|
|
|
|
|
|
OrganizationUserBulkRequestModel model,
|
2023-08-17 16:03:06 -04:00
|
|
|
|
Func<Guid, IEnumerable<Guid>, Guid?, Task<List<Tuple<Core.Entities.OrganizationUser, string>>>> statusAction)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2022-06-16 15:59:57 -04:00
|
|
|
|
if (!await _currentContext.ManageUsers(orgId))
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2022-06-16 15:59:57 -04:00
|
|
|
|
throw new NotFoundException();
|
|
|
|
|
|
}
|
2022-08-29 16:06:55 -04:00
|
|
|
|
|
2022-06-16 15:59:57 -04:00
|
|
|
|
var userId = _userService.GetProperUserId(User);
|
|
|
|
|
|
var result = await statusAction(orgId, model.Ids, userId.Value);
|
2022-07-25 10:47:44 +10:00
|
|
|
|
return new ListResponseModel<OrganizationUserBulkResponseModel>(result.Select(r =>
|
2021-05-25 19:23:47 +02:00
|
|
|
|
new OrganizationUserBulkResponseModel(r.Item1.Id, r.Item2)));
|
2017-03-04 21:28:41 -05:00
|
|
|
|
}
|
|
|
|
|
|
}
|