2023-06-08 08:41:36 -05:00
|
|
|
|
using System.Net;
|
|
|
|
|
|
using System.Reflection;
|
2021-01-11 11:03:46 -05:00
|
|
|
|
using System.Security.Claims;
|
|
|
|
|
|
using System.Security.Cryptography.X509Certificates;
|
2022-07-19 11:58:32 -07:00
|
|
|
|
using AspNetCoreRateLimit;
|
2024-04-17 10:09:53 +01:00
|
|
|
|
using Bit.Core.AdminConsole.Models.Business.Tokenables;
|
2024-10-22 09:18:34 +10:00
|
|
|
|
using Bit.Core.AdminConsole.OrganizationFeatures.Policies;
|
2023-10-20 06:37:46 +10:00
|
|
|
|
using Bit.Core.AdminConsole.Services;
|
|
|
|
|
|
using Bit.Core.AdminConsole.Services.Implementations;
|
2023-10-27 03:38:29 +10:00
|
|
|
|
using Bit.Core.AdminConsole.Services.NoopImplementations;
|
2023-04-14 13:25:56 -04:00
|
|
|
|
using Bit.Core.Auth.Enums;
|
|
|
|
|
|
using Bit.Core.Auth.Identity;
|
2024-11-18 15:58:05 -08:00
|
|
|
|
using Bit.Core.Auth.Identity.TokenProviders;
|
2023-04-14 13:25:56 -04:00
|
|
|
|
using Bit.Core.Auth.IdentityServer;
|
|
|
|
|
|
using Bit.Core.Auth.LoginFeatures;
|
|
|
|
|
|
using Bit.Core.Auth.Models.Business.Tokenables;
|
2024-02-07 14:50:23 -05:00
|
|
|
|
using Bit.Core.Auth.Repositories;
|
2023-04-14 13:25:56 -04:00
|
|
|
|
using Bit.Core.Auth.Services;
|
2023-05-09 12:39:33 -04:00
|
|
|
|
using Bit.Core.Auth.Services.Implementations;
|
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.Auth.UserFeatures;
|
2024-09-09 09:38:58 -04:00
|
|
|
|
using Bit.Core.Billing.Services;
|
|
|
|
|
|
using Bit.Core.Billing.Services.Implementations;
|
2024-07-29 14:18:12 -04:00
|
|
|
|
using Bit.Core.Billing.TrialInitiation;
|
2022-01-11 10:40:51 +01:00
|
|
|
|
using Bit.Core.Entities;
|
2021-01-11 11:03:46 -05:00
|
|
|
|
using Bit.Core.Enums;
|
2022-07-19 11:58:32 -07:00
|
|
|
|
using Bit.Core.HostedServices;
|
2017-05-05 20:57:33 -04:00
|
|
|
|
using Bit.Core.Identity;
|
|
|
|
|
|
using Bit.Core.IdentityServer;
|
2024-10-22 09:20:57 -07:00
|
|
|
|
using Bit.Core.NotificationHub;
|
2022-05-10 17:12:09 -04:00
|
|
|
|
using Bit.Core.OrganizationFeatures;
|
2017-05-05 20:57:33 -04:00
|
|
|
|
using Bit.Core.Repositories;
|
2021-01-11 11:03:46 -05:00
|
|
|
|
using Bit.Core.Resources;
|
2023-07-24 23:05:05 +01:00
|
|
|
|
using Bit.Core.SecretsManager.Repositories;
|
|
|
|
|
|
using Bit.Core.SecretsManager.Repositories.Noop;
|
2017-05-05 20:57:33 -04:00
|
|
|
|
using Bit.Core.Services;
|
2021-02-22 15:35:16 -06:00
|
|
|
|
using Bit.Core.Settings;
|
2022-01-10 10:58:16 -05:00
|
|
|
|
using Bit.Core.Tokens;
|
2024-11-11 11:18:10 -05:00
|
|
|
|
using Bit.Core.Tools.ReportFeatures;
|
2023-04-18 14:05:17 +02:00
|
|
|
|
using Bit.Core.Tools.Services;
|
2021-01-11 11:03:46 -05:00
|
|
|
|
using Bit.Core.Utilities;
|
2024-02-08 14:07:58 -08:00
|
|
|
|
using Bit.Core.Vault;
|
2023-03-02 13:23:38 -05:00
|
|
|
|
using Bit.Core.Vault.Services;
|
2022-01-11 10:40:51 +01:00
|
|
|
|
using Bit.Infrastructure.Dapper;
|
2023-03-30 15:37:19 +02:00
|
|
|
|
using Bit.Infrastructure.EntityFramework;
|
2023-04-06 15:31:45 -04:00
|
|
|
|
using DnsClient;
|
2017-06-06 23:19:42 -04:00
|
|
|
|
using IdentityModel;
|
2024-01-18 09:47:34 -05:00
|
|
|
|
using LaunchDarkly.Sdk.Server;
|
|
|
|
|
|
using LaunchDarkly.Sdk.Server.Interfaces;
|
2021-01-11 11:03:46 -05:00
|
|
|
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
2023-11-20 16:32:23 -05:00
|
|
|
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
2021-01-11 11:03:46 -05:00
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
2017-07-21 12:53:26 -04:00
|
|
|
|
using Microsoft.AspNetCore.Builder;
|
2017-05-05 20:57:33 -04:00
|
|
|
|
using Microsoft.AspNetCore.DataProtection;
|
|
|
|
|
|
using Microsoft.AspNetCore.Hosting;
|
2021-01-11 11:03:46 -05:00
|
|
|
|
using Microsoft.AspNetCore.HttpOverrides;
|
2017-05-05 20:57:33 -04:00
|
|
|
|
using Microsoft.AspNetCore.Identity;
|
2021-01-11 11:03:46 -05:00
|
|
|
|
using Microsoft.AspNetCore.Mvc.Localization;
|
2024-02-08 14:34:53 -05:00
|
|
|
|
using Microsoft.Azure.Cosmos.Fluent;
|
|
|
|
|
|
using Microsoft.Extensions.Caching.Cosmos;
|
2022-07-19 11:58:32 -07:00
|
|
|
|
using Microsoft.Extensions.Caching.Distributed;
|
2017-05-05 20:57:33 -04:00
|
|
|
|
using Microsoft.Extensions.Configuration;
|
|
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
2021-01-11 11:03:46 -05:00
|
|
|
|
using Microsoft.Extensions.Hosting;
|
2022-09-26 15:22:02 -04:00
|
|
|
|
using Microsoft.Extensions.Logging;
|
2021-01-11 11:03:46 -05:00
|
|
|
|
using Microsoft.Extensions.Options;
|
2022-07-19 11:58:32 -07:00
|
|
|
|
using StackExchange.Redis;
|
2019-03-19 00:39:03 -04:00
|
|
|
|
using NoopRepos = Bit.Core.Repositories.Noop;
|
2022-07-19 11:58:32 -07:00
|
|
|
|
using Role = Bit.Core.Entities.Role;
|
2017-12-08 16:03:20 -05:00
|
|
|
|
using TableStorageRepos = Bit.Core.Repositories.TableStorage;
|
2017-05-05 20:57:33 -04:00
|
|
|
|
|
2022-01-11 10:40:51 +01:00
|
|
|
|
namespace Bit.SharedWeb.Utilities;
|
2022-08-29 16:06:55 -04:00
|
|
|
|
|
2022-01-11 10:40:51 +01:00
|
|
|
|
public static class ServiceCollectionExtensions
|
2017-05-05 20:57:33 -04:00
|
|
|
|
{
|
2022-11-18 14:39:01 -05:00
|
|
|
|
public static SupportedDatabaseProviders AddDatabaseRepositories(this IServiceCollection services, GlobalSettings globalSettings)
|
2017-05-05 20:57:33 -04:00
|
|
|
|
{
|
2024-07-03 12:48:23 -04:00
|
|
|
|
var (provider, connectionString) = GetDatabaseProvider(globalSettings);
|
2023-01-13 15:02:53 +01:00
|
|
|
|
services.SetupEntityFramework(connectionString, provider);
|
2020-01-10 08:33:13 -05:00
|
|
|
|
|
2023-01-13 15:02:53 +01:00
|
|
|
|
if (provider != SupportedDatabaseProviders.SqlServer)
|
2019-01-15 22:07:13 -05:00
|
|
|
|
{
|
2023-01-13 15:02:53 +01:00
|
|
|
|
services.AddPasswordManagerEFRepositories(globalSettings.SelfHosted);
|
2017-05-05 20:57:33 -04:00
|
|
|
|
}
|
2021-09-27 23:01:13 +02:00
|
|
|
|
else
|
2022-08-29 14:53:16 -04:00
|
|
|
|
{
|
2019-06-13 00:10:37 -04:00
|
|
|
|
services.AddDapperRepositories(globalSettings.SelfHosted);
|
2021-05-13 15:18:42 -04:00
|
|
|
|
}
|
2017-08-07 16:31:00 -04:00
|
|
|
|
|
2018-08-02 17:23:37 -04:00
|
|
|
|
if (globalSettings.SelfHosted)
|
2022-08-29 15:53:48 -04:00
|
|
|
|
{
|
2017-08-07 16:31:00 -04:00
|
|
|
|
services.AddSingleton<IInstallationDeviceRepository, NoopRepos.InstallationDeviceRepository>();
|
2022-08-29 15:53:48 -04:00
|
|
|
|
}
|
2021-09-27 23:01:13 +02:00
|
|
|
|
else
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2017-08-11 10:04:59 -04:00
|
|
|
|
services.AddSingleton<IEventRepository, TableStorageRepos.EventRepository>();
|
2021-06-16 12:47:41 -04:00
|
|
|
|
services.AddSingleton<IInstallationDeviceRepository, TableStorageRepos.InstallationDeviceRepository>();
|
2024-02-07 14:50:23 -05:00
|
|
|
|
services.AddKeyedSingleton<IGrantRepository, Core.Auth.Repositories.Cosmos.GrantRepository>("cosmos");
|
2022-08-29 15:53:48 -04:00
|
|
|
|
}
|
2022-11-18 14:39:01 -05:00
|
|
|
|
|
|
|
|
|
|
return provider;
|
2022-08-29 15:53:48 -04:00
|
|
|
|
}
|
2017-08-07 16:31:00 -04:00
|
|
|
|
|
2021-05-17 09:43:02 -05:00
|
|
|
|
public static void AddBaseServices(this IServiceCollection services, IGlobalSettings globalSettings)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2021-05-17 09:43:02 -05:00
|
|
|
|
services.AddScoped<ICipherService, CipherService>();
|
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
|
|
|
|
services.AddUserServices(globalSettings);
|
2024-07-29 14:18:12 -04:00
|
|
|
|
services.AddTrialInitiationServices();
|
2021-05-17 09:43:02 -05:00
|
|
|
|
services.AddOrganizationServices(globalSettings);
|
2024-10-22 09:18:34 +10:00
|
|
|
|
services.AddPolicyServices();
|
2021-05-17 09:43:02 -05:00
|
|
|
|
services.AddScoped<ICollectionService, CollectionService>();
|
|
|
|
|
|
services.AddScoped<IGroupService, GroupService>();
|
|
|
|
|
|
services.AddScoped<IEventService, EventService>();
|
2020-12-16 20:36:47 +01:00
|
|
|
|
services.AddScoped<IEmergencyAccessService, EmergencyAccessService>();
|
2021-05-17 09:43:02 -05:00
|
|
|
|
services.AddSingleton<IDeviceService, DeviceService>();
|
|
|
|
|
|
services.AddScoped<ISsoConfigService, SsoConfigService>();
|
2023-05-09 12:39:33 -04:00
|
|
|
|
services.AddScoped<IAuthRequestService, AuthRequestService>();
|
2024-11-18 15:58:05 -08:00
|
|
|
|
services.AddScoped<IDuoUniversalTokenService, DuoUniversalTokenService>();
|
2021-05-17 09:43:02 -05:00
|
|
|
|
services.AddScoped<ISendService, SendService>();
|
2022-10-18 14:50:48 -04:00
|
|
|
|
services.AddLoginServices();
|
[SG-147] Organization Domain Claiming Feature (#2704)
* [SG-696] Organization Domain Claiming DB Objects and Migrations (#2394)
* model organization domain claiming
* Added migration scripts and db objects for mssql
* create and implement sql repository abstraction
* Added ef migrations for mysql and postgres. Removed time without timezone in previous migration
* made update on sql migration to use create or alter statement
* removed active column from OrganizationDomain table and decided to go with the hard delete approach
* Ran dotnet restore evaluate
* created DNS service verification using DNSClient (#2401)
* [SG-678] Api Endpoints for Domain Claiming (#2430)
* Added stored procedure to read claimed domains
* Updated Organization Domain Repository to include method to get claimed domains
* Updated domain entity and added request model
* Implemented organization domain respository and regsitered it in the various extensions
* Added create endpoint, request, responses and command
* Added endpoint to get domain by domain entry id
* Ran lint fix
* Added new stored procedure to get domains by organizattion id
* Moved migration scripts to init migration and added new procedure
* Renamed from domainId to Id
* Added and implemented GetDomainByOrganizationId
* Completed GetDomainByOrgId endpoint and started work on verify domain endpoint
* Updated the OrganizationDomain update procedure
* Added delete command and include other endpoints in the controller
* Remove test item from controller
* Remove test item from controller
* Changed access to allow admin, owners and manage sso roles
* changed logic for setting the initial value for the NextRunCount
* Renamed NextRunCount to JobRunCount
* Renamed NextRunCount to JobRunCount on mysql
* Renamed NextRunCount to JobRunCount on postgres
* Removed chaining pattern and added logic to get next run date
* Lint fix
* Added stored procedure to get organization sso details by email address
* Added endpoint to get sso details of an organization with email
* Added organizationDomainRepository to OrganizationController test
* merged with master and fixed conflicts
* [SG-661] Background Domain Verification Service (#2455)
* Added stored procedure to read claimed domains
* Updated Organization Domain Repository to include method to get claimed domains
* Updated domain entity and added request model
* Implemented organization domain respository and regsitered it in the various extensions
* Added create endpoint, request, responses and command
* Added endpoint to get domain by domain entry id
* Ran lint fix
* Added new stored procedure to get domains by organizattion id
* Moved migration scripts to init migration and added new procedure
* Renamed from domainId to Id
* Added and implemented GetDomainByOrganizationId
* Completed GetDomainByOrgId endpoint and started work on verify domain endpoint
* Updated the OrganizationDomain update procedure
* Added delete command and include other endpoints in the controller
* Remove test item from controller
* Remove test item from controller
* Changed access to allow admin, owners and manage sso roles
* Added stored procedure to get unverified domains by nextrundate
* Renamed stored procedure name
* Added domain verification service interface
* Added GetManyByNextRunDate to repository
* Added verification domain service implementation
* changed logic for setting the initial value for the NextRunCount
* This commit should be signed using my SSH key
* Renamed NextRunCount to JobRunCount
* Renamed NextRunCount to JobRunCount on mysql
* Renamed NextRunCount to JobRunCount on postgres
* Removed chaining pattern and added logic to get next run date
* Lint fix
* Implemented EF core version on the repository
* Created background job implementation and logic
* popped stash
* Updated stored procedure and EF script
* Lint fix
* Added logic to set next job count and the next run date when a verification is false
* Added logic to set next job count and the next run date when a verification is false
* Updated stored procedure name on repository
* Removed test trigger
* Lint fix
* Added trigger for job
* Added job count update after successful domain verification
* Lint fix
* Lint fix
* [SG-682] Add Event Log Entries to Organization Domain (#2492)
* Added domain name property to Event related objects
* Added organization domain claiming event types
* Created migration script and updated related event scripts to include domanName
* Added EF Migrations
* Renamed postres script file extension
* Added DomainName property to response model
* Added abstraction to interface
* Added system name to enum
* dotnet formattinfg fix
* Added events to organization domain actions
* Added LastCheckedDate property to domain
* Migrations and stored procedure updates with new column
* Added new stored procedure to get domain by org id and domain name
* Log organization domain event abstract method
* Ef migrattion to add new LastCheckedDate column
* Added duplicate domain exception
* Modified create command to include domain verification and last checked date and renamed methods used
* removed variable
* changed service lifetime
* Renamed trigger
* Initialed property in constructor
* Ensured domain name is stored as lower case
* Fixed suggestions from review
* Fixed suggestions from review
* Return Conflict Status on Organization Domain APIs (#2498)
* Added conflict response to end point to help translate error message on the client better
* Added conflict response to end point to help translate error message on the client better
* Set message with exception message or generic message
* Added last check date to response model (#2499)
* Fix/Check to throw exception when domain is claimed by another organization (#2503)
* Added check to ensure domain claimed by another organization cannot be verified
* Made error message consistent
* [SG-660] Organization Domain Maintenance (#2502)
* Added email template
* Mail service abstraction and implementation
* Mail template model
* Initial delete job commit
* Added SPs to get all unverifed domains after 72 hours and another to delete unverified domains after 7 days
* Moved all organization domain scripts to single file
* Added new scripts implementation for sqlserver and EF core
* Renamed service
* Formatting fix
* Added background service to send warning email and delete expired domains
* Renamed variable
* Added implementation for email warning to organization admins and for deleting expired domains after 7 days
* Added formatting
* Modified read if expired script to limit result to 4 days
* Added send mail abstract method and implementation
* Model used in build mail body
* Completed maintenace service
* Added comment to make logic clear
* Fixed cron expression (#2505)
* Modified procedure and methods to handle flexible verification adn expiration period (#2517)
* Merged with master
* [SG-908] Unit Tests for Organization Domain Claiming Feature (#2522)
* added test controlleer class
* added unit test for create command
* Added query tests
* Added tests for delete and verify command
* Formated code and added some more unit tests
* Fixed lint
* Added log event assertion to create command tests
* Added log event assertion to delete command tests
* Added unit tests for organization domain controller
* Added unit tests for organization domain service
* Modified test after merge
* fixed comment
* fixed comment
* fixed lint
* Defect/SG-977 - Org domain event logs missing details (#2573)
* SG-977 - (1) Refactor EventSystemUser.SSO to be EventSystemUser.DomainVerification to better match SCIM property and for easier display and translation on web client (2) Add new DeviceType of Server to be used on SCIM and Domain Verification logs so event log will show Server as client.
* SG-977 - SCIM bugfix - Restoring / Revoking user access via Jumpcloud activation / suspension did not properly log the events as SCIM events so the client side showed Unknown for both Client and Member.
* Run autoformat to fix lint errors
* SG-977 - Fixed broken test due to new device type logic in event service
* SG-976 - Add admin log and clean up log verbiage for domain verification (#2574)
* SG-976 - Add admin log and clean up log verbiage for domain verification
* SG-976 - (1) Use logInformation extension without exception (2) Clarify verbiage of logs
* SG-955 - On domain verification error or failure, set last checked da… (#2541)
* SG-955 - On domain verification error or failure, set last checked date on the org domain.
* SG-955 - Refactoring VerifyOrganizationDomain event logging to avoid duplication and increase efficiency (based on Gbubemi's PR feedback)
* Org Domain Background Verification service - set last checked date (#2599)
* Refactored OrganizationDomain repository to work with latest changes on code base
* Fixed formatting
* [SG-957] Cannot Delete Organizations due to FK Constraint (#2602)
* Added stored procedure to fix FX contstraint issue when deleting an organization
* Update stored procedures related to organization delete with OrganizationDomain_OrganizationDelete SP
* Fixed formatting
* Updated SP
* SG-990 - Log expired domains that are going to be deleted.
* Fix lint errors with auto format
* /home/runner/work/server/server/src/Core/OrganizationFeatures/OrganizationServiceCollectionExtensions.cs(107,2): error FINALNEWLINE: Fix final newline. Insert '\n'.
* Added missing bracket to fix compile error.
* Added imports for Domain Claiming classes that were lost on merge.
* Fixing broken unit tests + adding proper behavior for newly added SCIM logic changing device type
* Fix lint errors again
* Included domain name set in constructor (#2618)
* [SG-1001] Error Thrown When Verifying Sub Domains (#2621)
* Renamed exception to a more generic name that receives error message from the dns client and also added updates to job count and next run date
* Improved error logs by adding dns client error message
* Fixed formatting
* [SG-1001] Added event logs when a domain is not verified due to thrown exception (#2623)
* Added eevent logs when a domain is not verified due to thrown exception
* Fixed formatting
* Org Domain Verification - Small refactor to improve method/model name… (#2641)
* Org Domain Verification - Small refactor to improve method/model names and method locations - required refactoring of controller routes (I confirmed all behavior still functional)
* Fixed organization test controller issue
* Fixed lint
* Autoformat org domain controller
* Removing whitespace for lint argh, why does Rider not do this.
---------
Co-authored-by: gbubemismith <gsmithwalter@gmail.com>
* Tweak name of Request model to match Response model for ClaimedOrgDomain call
* [SG-1009] Users with Custom Role and "Manage SSO" permission don't receive verification failed email (#2645)
* Modified condition to pick up unverified domains after said period
* Fix to get emails of custom users with manage sso rights
* Formatted code
* Removed return that made background job exit on successful validation (#2648)
* [SG-1014] Unit Tests for Get Organization Sso Details (#2655)
* Added unit tests for GetOrgDomainSsoDetails
* renamed variable
* Adjust OrganizationDomainSsoDetails_ReadByEmail to use outer join so … (#2657)
* Adjust OrganizationDomainSsoDetails_ReadByEmail to use outer join so that claimed domain results will come back if an org has not yet setup a policy
* Removed migration as not needed
* Updated OrganizationDomainSsoDetails_ReadByEmail from original creation migration to use outer join & handle null policy results (and still return results)
* Fixed lint formatting
---------
Co-authored-by: Jared Snider <116684653+JaredSnider-Bitwarden@users.noreply.github.com>
Co-authored-by: Jared Snider <jsnider@bitwarden.com>
Co-authored-by: Todd Martin <tmartin@bitwarden.com>
2023-02-15 14:26:41 -05:00
|
|
|
|
services.AddScoped<IOrganizationDomainService, OrganizationDomainService>();
|
2024-02-08 14:07:58 -08:00
|
|
|
|
services.AddVaultServices();
|
2024-11-11 11:18:10 -05:00
|
|
|
|
services.AddReportingServices();
|
2022-08-29 15:53:48 -04:00
|
|
|
|
}
|
2021-05-17 09:43:02 -05:00
|
|
|
|
|
2017-12-08 16:03:20 -05:00
|
|
|
|
public static void AddTokenizers(this IServiceCollection services)
|
|
|
|
|
|
{
|
2024-05-22 12:59:19 -04:00
|
|
|
|
services.AddSingleton<IDataProtectorTokenFactory<OrgDeleteTokenable>>(serviceProvider =>
|
|
|
|
|
|
new DataProtectorTokenFactory<OrgDeleteTokenable>(
|
|
|
|
|
|
OrgDeleteTokenable.ClearTextPrefix,
|
|
|
|
|
|
OrgDeleteTokenable.DataProtectorPurpose,
|
|
|
|
|
|
serviceProvider.GetDataProtectionProvider(),
|
|
|
|
|
|
serviceProvider.GetRequiredService<ILogger<DataProtectorTokenFactory<OrgDeleteTokenable>>>())
|
|
|
|
|
|
);
|
2017-12-08 16:03:20 -05:00
|
|
|
|
services.AddSingleton<IDataProtectorTokenFactory<EmergencyAccessInviteTokenable>>(serviceProvider =>
|
2022-01-10 10:58:16 -05:00
|
|
|
|
new DataProtectorTokenFactory<EmergencyAccessInviteTokenable>(
|
2017-12-08 16:03:20 -05:00
|
|
|
|
EmergencyAccessInviteTokenable.ClearTextPrefix,
|
2020-03-27 14:36:37 -04:00
|
|
|
|
EmergencyAccessInviteTokenable.DataProtectorPurpose,
|
2022-09-26 15:22:02 -04:00
|
|
|
|
serviceProvider.GetDataProtectionProvider(),
|
|
|
|
|
|
serviceProvider.GetRequiredService<ILogger<DataProtectorTokenFactory<EmergencyAccessInviteTokenable>>>())
|
2021-06-16 12:47:41 -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
|
|
|
|
|
2021-06-16 12:47:41 -04:00
|
|
|
|
services.AddSingleton<IDataProtectorTokenFactory<HCaptchaTokenable>>(serviceProvider =>
|
2022-01-10 10:58:16 -05:00
|
|
|
|
new DataProtectorTokenFactory<HCaptchaTokenable>(
|
|
|
|
|
|
HCaptchaTokenable.ClearTextPrefix,
|
2021-06-16 12:47:41 -04:00
|
|
|
|
HCaptchaTokenable.DataProtectorPurpose,
|
2022-09-26 15:22:02 -04:00
|
|
|
|
serviceProvider.GetDataProtectionProvider(),
|
|
|
|
|
|
serviceProvider.GetRequiredService<ILogger<DataProtectorTokenFactory<HCaptchaTokenable>>>())
|
2021-06-16 12:47:41 -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
|
|
|
|
|
2021-06-16 12:47:41 -04:00
|
|
|
|
services.AddSingleton<IDataProtectorTokenFactory<SsoTokenable>>(serviceProvider =>
|
|
|
|
|
|
new DataProtectorTokenFactory<SsoTokenable>(
|
2022-06-01 13:23:52 -04:00
|
|
|
|
SsoTokenable.ClearTextPrefix,
|
2021-06-16 12:47:41 -04:00
|
|
|
|
SsoTokenable.DataProtectorPurpose,
|
2022-09-26 15:22:02 -04:00
|
|
|
|
serviceProvider.GetDataProtectionProvider(),
|
|
|
|
|
|
serviceProvider.GetRequiredService<ILogger<DataProtectorTokenFactory<SsoTokenable>>>()));
|
2023-10-30 08:40:06 -05:00
|
|
|
|
services.AddSingleton<IDataProtectorTokenFactory<WebAuthnCredentialCreateOptionsTokenable>>(serviceProvider =>
|
|
|
|
|
|
new DataProtectorTokenFactory<WebAuthnCredentialCreateOptionsTokenable>(
|
|
|
|
|
|
WebAuthnCredentialCreateOptionsTokenable.ClearTextPrefix,
|
|
|
|
|
|
WebAuthnCredentialCreateOptionsTokenable.DataProtectorPurpose,
|
|
|
|
|
|
serviceProvider.GetDataProtectionProvider(),
|
|
|
|
|
|
serviceProvider.GetRequiredService<ILogger<DataProtectorTokenFactory<WebAuthnCredentialCreateOptionsTokenable>>>()));
|
2023-11-20 15:55:31 +01:00
|
|
|
|
services.AddSingleton<IDataProtectorTokenFactory<WebAuthnLoginAssertionOptionsTokenable>>(serviceProvider =>
|
|
|
|
|
|
new DataProtectorTokenFactory<WebAuthnLoginAssertionOptionsTokenable>(
|
|
|
|
|
|
WebAuthnLoginAssertionOptionsTokenable.ClearTextPrefix,
|
|
|
|
|
|
WebAuthnLoginAssertionOptionsTokenable.DataProtectorPurpose,
|
|
|
|
|
|
serviceProvider.GetDataProtectionProvider(),
|
|
|
|
|
|
serviceProvider.GetRequiredService<ILogger<DataProtectorTokenFactory<WebAuthnLoginAssertionOptionsTokenable>>>()));
|
2023-05-04 15:12:03 -04:00
|
|
|
|
services.AddSingleton<IDataProtectorTokenFactory<SsoEmail2faSessionTokenable>>(serviceProvider =>
|
|
|
|
|
|
new DataProtectorTokenFactory<SsoEmail2faSessionTokenable>(
|
|
|
|
|
|
SsoEmail2faSessionTokenable.ClearTextPrefix,
|
|
|
|
|
|
SsoEmail2faSessionTokenable.DataProtectorPurpose,
|
|
|
|
|
|
serviceProvider.GetDataProtectionProvider(),
|
|
|
|
|
|
serviceProvider.GetRequiredService<ILogger<DataProtectorTokenFactory<SsoEmail2faSessionTokenable>>>()));
|
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
|
|
|
|
|
|
|
|
|
|
services.AddSingleton<IOrgUserInviteTokenableFactory, OrgUserInviteTokenableFactory>();
|
|
|
|
|
|
services.AddSingleton<IDataProtectorTokenFactory<OrgUserInviteTokenable>>(serviceProvider =>
|
|
|
|
|
|
new DataProtectorTokenFactory<OrgUserInviteTokenable>(
|
|
|
|
|
|
OrgUserInviteTokenable.ClearTextPrefix,
|
|
|
|
|
|
OrgUserInviteTokenable.DataProtectorPurpose,
|
|
|
|
|
|
serviceProvider.GetDataProtectionProvider(),
|
|
|
|
|
|
serviceProvider.GetRequiredService<ILogger<DataProtectorTokenFactory<OrgUserInviteTokenable>>>()));
|
2024-02-14 18:00:46 -05:00
|
|
|
|
services.AddSingleton<IDataProtectorTokenFactory<DuoUserStateTokenable>>(serviceProvider =>
|
|
|
|
|
|
new DataProtectorTokenFactory<DuoUserStateTokenable>(
|
|
|
|
|
|
DuoUserStateTokenable.ClearTextPrefix,
|
|
|
|
|
|
DuoUserStateTokenable.DataProtectorPurpose,
|
|
|
|
|
|
serviceProvider.GetDataProtectionProvider(),
|
|
|
|
|
|
serviceProvider.GetRequiredService<ILogger<DataProtectorTokenFactory<DuoUserStateTokenable>>>()));
|
2024-04-17 10:09:53 +01:00
|
|
|
|
|
|
|
|
|
|
services.AddSingleton<IDataProtectorTokenFactory<ProviderDeleteTokenable>>(serviceProvider =>
|
|
|
|
|
|
new DataProtectorTokenFactory<ProviderDeleteTokenable>(
|
|
|
|
|
|
ProviderDeleteTokenable.ClearTextPrefix,
|
|
|
|
|
|
ProviderDeleteTokenable.DataProtectorPurpose,
|
|
|
|
|
|
serviceProvider.GetDataProtectionProvider(),
|
|
|
|
|
|
serviceProvider.GetRequiredService<ILogger<DataProtectorTokenFactory<ProviderDeleteTokenable>>>())
|
|
|
|
|
|
);
|
2024-06-19 13:54:20 -04:00
|
|
|
|
services.AddSingleton<IDataProtectorTokenFactory<RegistrationEmailVerificationTokenable>>(
|
|
|
|
|
|
serviceProvider => new DataProtectorTokenFactory<RegistrationEmailVerificationTokenable>(
|
|
|
|
|
|
RegistrationEmailVerificationTokenable.ClearTextPrefix,
|
|
|
|
|
|
RegistrationEmailVerificationTokenable.DataProtectorPurpose,
|
|
|
|
|
|
serviceProvider.GetDataProtectionProvider(),
|
|
|
|
|
|
serviceProvider.GetRequiredService<ILogger<DataProtectorTokenFactory<RegistrationEmailVerificationTokenable>>>()));
|
2024-07-25 07:51:23 -07:00
|
|
|
|
services.AddSingleton<IDataProtectorTokenFactory<TwoFactorAuthenticatorUserVerificationTokenable>>(
|
|
|
|
|
|
serviceProvider => new DataProtectorTokenFactory<TwoFactorAuthenticatorUserVerificationTokenable>(
|
|
|
|
|
|
TwoFactorAuthenticatorUserVerificationTokenable.ClearTextPrefix,
|
|
|
|
|
|
TwoFactorAuthenticatorUserVerificationTokenable.DataProtectorPurpose,
|
|
|
|
|
|
serviceProvider.GetDataProtectionProvider(),
|
|
|
|
|
|
serviceProvider.GetRequiredService<ILogger<DataProtectorTokenFactory<TwoFactorAuthenticatorUserVerificationTokenable>>>()));
|
2022-08-29 14:53:16 -04:00
|
|
|
|
}
|
2017-12-04 12:17:26 -05:00
|
|
|
|
|
2020-03-27 14:36:37 -04:00
|
|
|
|
public static void AddDefaultServices(this IServiceCollection services, GlobalSettings globalSettings)
|
2017-08-07 16:31:00 -04:00
|
|
|
|
{
|
|
|
|
|
|
// Required for UserService
|
|
|
|
|
|
services.AddWebAuthn(globalSettings);
|
2017-08-08 17:27:01 -04:00
|
|
|
|
// Required for HTTP calls
|
|
|
|
|
|
services.AddHttpClient();
|
2020-07-07 12:01:34 -04:00
|
|
|
|
|
2020-11-02 15:55:49 -05:00
|
|
|
|
services.AddSingleton<IStripeAdapter, StripeAdapter>();
|
|
|
|
|
|
services.AddSingleton<Braintree.IBraintreeGateway>((serviceProvider) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
return new Braintree.BraintreeGateway
|
|
|
|
|
|
{
|
2021-09-27 23:01:13 +02:00
|
|
|
|
Environment = globalSettings.Braintree.Production ?
|
2017-08-11 10:04:59 -04:00
|
|
|
|
Braintree.Environment.PRODUCTION : Braintree.Environment.SANDBOX,
|
2021-09-27 23:01:13 +02:00
|
|
|
|
MerchantId = globalSettings.Braintree.MerchantId,
|
|
|
|
|
|
PublicKey = globalSettings.Braintree.PublicKey,
|
2020-11-02 15:55:49 -05:00
|
|
|
|
PrivateKey = globalSettings.Braintree.PrivateKey
|
2022-08-29 16:06:55 -04:00
|
|
|
|
};
|
|
|
|
|
|
});
|
2024-02-01 13:21:17 -05:00
|
|
|
|
services.AddScoped<IPaymentService, StripePaymentService>();
|
2024-09-09 09:38:58 -04:00
|
|
|
|
services.AddScoped<IPaymentHistoryService, PaymentHistoryService>();
|
2020-11-02 15:55:49 -05:00
|
|
|
|
services.AddSingleton<IStripeSyncService, StripeSyncService>();
|
2017-08-11 10:04:59 -04:00
|
|
|
|
services.AddSingleton<IMailService, HandlebarsMailService>();
|
2024-12-05 09:31:14 -05:00
|
|
|
|
services.AddScoped<ILicensingService, LicensingService>();
|
2023-04-06 15:31:45 -04:00
|
|
|
|
services.AddSingleton<ILookupClient>(_ =>
|
|
|
|
|
|
{
|
2023-05-03 09:07:04 -04:00
|
|
|
|
var options = new LookupClientOptions { Timeout = TimeSpan.FromSeconds(15), UseTcpOnly = true };
|
2023-04-06 15:31:45 -04:00
|
|
|
|
return new LookupClient(options);
|
|
|
|
|
|
});
|
[SG-147] Organization Domain Claiming Feature (#2704)
* [SG-696] Organization Domain Claiming DB Objects and Migrations (#2394)
* model organization domain claiming
* Added migration scripts and db objects for mssql
* create and implement sql repository abstraction
* Added ef migrations for mysql and postgres. Removed time without timezone in previous migration
* made update on sql migration to use create or alter statement
* removed active column from OrganizationDomain table and decided to go with the hard delete approach
* Ran dotnet restore evaluate
* created DNS service verification using DNSClient (#2401)
* [SG-678] Api Endpoints for Domain Claiming (#2430)
* Added stored procedure to read claimed domains
* Updated Organization Domain Repository to include method to get claimed domains
* Updated domain entity and added request model
* Implemented organization domain respository and regsitered it in the various extensions
* Added create endpoint, request, responses and command
* Added endpoint to get domain by domain entry id
* Ran lint fix
* Added new stored procedure to get domains by organizattion id
* Moved migration scripts to init migration and added new procedure
* Renamed from domainId to Id
* Added and implemented GetDomainByOrganizationId
* Completed GetDomainByOrgId endpoint and started work on verify domain endpoint
* Updated the OrganizationDomain update procedure
* Added delete command and include other endpoints in the controller
* Remove test item from controller
* Remove test item from controller
* Changed access to allow admin, owners and manage sso roles
* changed logic for setting the initial value for the NextRunCount
* Renamed NextRunCount to JobRunCount
* Renamed NextRunCount to JobRunCount on mysql
* Renamed NextRunCount to JobRunCount on postgres
* Removed chaining pattern and added logic to get next run date
* Lint fix
* Added stored procedure to get organization sso details by email address
* Added endpoint to get sso details of an organization with email
* Added organizationDomainRepository to OrganizationController test
* merged with master and fixed conflicts
* [SG-661] Background Domain Verification Service (#2455)
* Added stored procedure to read claimed domains
* Updated Organization Domain Repository to include method to get claimed domains
* Updated domain entity and added request model
* Implemented organization domain respository and regsitered it in the various extensions
* Added create endpoint, request, responses and command
* Added endpoint to get domain by domain entry id
* Ran lint fix
* Added new stored procedure to get domains by organizattion id
* Moved migration scripts to init migration and added new procedure
* Renamed from domainId to Id
* Added and implemented GetDomainByOrganizationId
* Completed GetDomainByOrgId endpoint and started work on verify domain endpoint
* Updated the OrganizationDomain update procedure
* Added delete command and include other endpoints in the controller
* Remove test item from controller
* Remove test item from controller
* Changed access to allow admin, owners and manage sso roles
* Added stored procedure to get unverified domains by nextrundate
* Renamed stored procedure name
* Added domain verification service interface
* Added GetManyByNextRunDate to repository
* Added verification domain service implementation
* changed logic for setting the initial value for the NextRunCount
* This commit should be signed using my SSH key
* Renamed NextRunCount to JobRunCount
* Renamed NextRunCount to JobRunCount on mysql
* Renamed NextRunCount to JobRunCount on postgres
* Removed chaining pattern and added logic to get next run date
* Lint fix
* Implemented EF core version on the repository
* Created background job implementation and logic
* popped stash
* Updated stored procedure and EF script
* Lint fix
* Added logic to set next job count and the next run date when a verification is false
* Added logic to set next job count and the next run date when a verification is false
* Updated stored procedure name on repository
* Removed test trigger
* Lint fix
* Added trigger for job
* Added job count update after successful domain verification
* Lint fix
* Lint fix
* [SG-682] Add Event Log Entries to Organization Domain (#2492)
* Added domain name property to Event related objects
* Added organization domain claiming event types
* Created migration script and updated related event scripts to include domanName
* Added EF Migrations
* Renamed postres script file extension
* Added DomainName property to response model
* Added abstraction to interface
* Added system name to enum
* dotnet formattinfg fix
* Added events to organization domain actions
* Added LastCheckedDate property to domain
* Migrations and stored procedure updates with new column
* Added new stored procedure to get domain by org id and domain name
* Log organization domain event abstract method
* Ef migrattion to add new LastCheckedDate column
* Added duplicate domain exception
* Modified create command to include domain verification and last checked date and renamed methods used
* removed variable
* changed service lifetime
* Renamed trigger
* Initialed property in constructor
* Ensured domain name is stored as lower case
* Fixed suggestions from review
* Fixed suggestions from review
* Return Conflict Status on Organization Domain APIs (#2498)
* Added conflict response to end point to help translate error message on the client better
* Added conflict response to end point to help translate error message on the client better
* Set message with exception message or generic message
* Added last check date to response model (#2499)
* Fix/Check to throw exception when domain is claimed by another organization (#2503)
* Added check to ensure domain claimed by another organization cannot be verified
* Made error message consistent
* [SG-660] Organization Domain Maintenance (#2502)
* Added email template
* Mail service abstraction and implementation
* Mail template model
* Initial delete job commit
* Added SPs to get all unverifed domains after 72 hours and another to delete unverified domains after 7 days
* Moved all organization domain scripts to single file
* Added new scripts implementation for sqlserver and EF core
* Renamed service
* Formatting fix
* Added background service to send warning email and delete expired domains
* Renamed variable
* Added implementation for email warning to organization admins and for deleting expired domains after 7 days
* Added formatting
* Modified read if expired script to limit result to 4 days
* Added send mail abstract method and implementation
* Model used in build mail body
* Completed maintenace service
* Added comment to make logic clear
* Fixed cron expression (#2505)
* Modified procedure and methods to handle flexible verification adn expiration period (#2517)
* Merged with master
* [SG-908] Unit Tests for Organization Domain Claiming Feature (#2522)
* added test controlleer class
* added unit test for create command
* Added query tests
* Added tests for delete and verify command
* Formated code and added some more unit tests
* Fixed lint
* Added log event assertion to create command tests
* Added log event assertion to delete command tests
* Added unit tests for organization domain controller
* Added unit tests for organization domain service
* Modified test after merge
* fixed comment
* fixed comment
* fixed lint
* Defect/SG-977 - Org domain event logs missing details (#2573)
* SG-977 - (1) Refactor EventSystemUser.SSO to be EventSystemUser.DomainVerification to better match SCIM property and for easier display and translation on web client (2) Add new DeviceType of Server to be used on SCIM and Domain Verification logs so event log will show Server as client.
* SG-977 - SCIM bugfix - Restoring / Revoking user access via Jumpcloud activation / suspension did not properly log the events as SCIM events so the client side showed Unknown for both Client and Member.
* Run autoformat to fix lint errors
* SG-977 - Fixed broken test due to new device type logic in event service
* SG-976 - Add admin log and clean up log verbiage for domain verification (#2574)
* SG-976 - Add admin log and clean up log verbiage for domain verification
* SG-976 - (1) Use logInformation extension without exception (2) Clarify verbiage of logs
* SG-955 - On domain verification error or failure, set last checked da… (#2541)
* SG-955 - On domain verification error or failure, set last checked date on the org domain.
* SG-955 - Refactoring VerifyOrganizationDomain event logging to avoid duplication and increase efficiency (based on Gbubemi's PR feedback)
* Org Domain Background Verification service - set last checked date (#2599)
* Refactored OrganizationDomain repository to work with latest changes on code base
* Fixed formatting
* [SG-957] Cannot Delete Organizations due to FK Constraint (#2602)
* Added stored procedure to fix FX contstraint issue when deleting an organization
* Update stored procedures related to organization delete with OrganizationDomain_OrganizationDelete SP
* Fixed formatting
* Updated SP
* SG-990 - Log expired domains that are going to be deleted.
* Fix lint errors with auto format
* /home/runner/work/server/server/src/Core/OrganizationFeatures/OrganizationServiceCollectionExtensions.cs(107,2): error FINALNEWLINE: Fix final newline. Insert '\n'.
* Added missing bracket to fix compile error.
* Added imports for Domain Claiming classes that were lost on merge.
* Fixing broken unit tests + adding proper behavior for newly added SCIM logic changing device type
* Fix lint errors again
* Included domain name set in constructor (#2618)
* [SG-1001] Error Thrown When Verifying Sub Domains (#2621)
* Renamed exception to a more generic name that receives error message from the dns client and also added updates to job count and next run date
* Improved error logs by adding dns client error message
* Fixed formatting
* [SG-1001] Added event logs when a domain is not verified due to thrown exception (#2623)
* Added eevent logs when a domain is not verified due to thrown exception
* Fixed formatting
* Org Domain Verification - Small refactor to improve method/model name… (#2641)
* Org Domain Verification - Small refactor to improve method/model names and method locations - required refactoring of controller routes (I confirmed all behavior still functional)
* Fixed organization test controller issue
* Fixed lint
* Autoformat org domain controller
* Removing whitespace for lint argh, why does Rider not do this.
---------
Co-authored-by: gbubemismith <gsmithwalter@gmail.com>
* Tweak name of Request model to match Response model for ClaimedOrgDomain call
* [SG-1009] Users with Custom Role and "Manage SSO" permission don't receive verification failed email (#2645)
* Modified condition to pick up unverified domains after said period
* Fix to get emails of custom users with manage sso rights
* Formatted code
* Removed return that made background job exit on successful validation (#2648)
* [SG-1014] Unit Tests for Get Organization Sso Details (#2655)
* Added unit tests for GetOrgDomainSsoDetails
* renamed variable
* Adjust OrganizationDomainSsoDetails_ReadByEmail to use outer join so … (#2657)
* Adjust OrganizationDomainSsoDetails_ReadByEmail to use outer join so that claimed domain results will come back if an org has not yet setup a policy
* Removed migration as not needed
* Updated OrganizationDomainSsoDetails_ReadByEmail from original creation migration to use outer join & handle null policy results (and still return results)
* Fixed lint formatting
---------
Co-authored-by: Jared Snider <116684653+JaredSnider-Bitwarden@users.noreply.github.com>
Co-authored-by: Jared Snider <jsnider@bitwarden.com>
Co-authored-by: Todd Martin <tmartin@bitwarden.com>
2023-02-15 14:26:41 -05:00
|
|
|
|
services.AddSingleton<IDnsResolverService, DnsResolverService>();
|
2024-01-18 09:47:34 -05:00
|
|
|
|
services.AddOptionality();
|
2022-01-10 10:58:16 -05:00
|
|
|
|
services.AddTokenizers();
|
2022-08-29 16:06:55 -04:00
|
|
|
|
|
2020-03-27 14:36:37 -04:00
|
|
|
|
if (CoreHelpers.SettingHasValue(globalSettings.ServiceBus.ConnectionString) &&
|
2020-11-02 15:55:49 -05:00
|
|
|
|
CoreHelpers.SettingHasValue(globalSettings.ServiceBus.ApplicationCacheTopicName))
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2017-05-05 20:57:33 -04:00
|
|
|
|
services.AddSingleton<IApplicationCacheService, InMemoryServiceBusApplicationCacheService>();
|
2020-11-02 15:55:49 -05:00
|
|
|
|
}
|
2022-08-29 16:06:55 -04:00
|
|
|
|
else
|
|
|
|
|
|
{
|
2017-05-05 20:57:33 -04:00
|
|
|
|
services.AddSingleton<IApplicationCacheService, InMemoryApplicationCacheService>();
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2020-11-02 15:55:49 -05:00
|
|
|
|
|
2020-07-07 12:01:34 -04:00
|
|
|
|
var awsConfigured = CoreHelpers.SettingHasValue(globalSettings.Amazon?.AccessKeySecret);
|
|
|
|
|
|
if (awsConfigured && CoreHelpers.SettingHasValue(globalSettings.Mail?.SendGridApiKey))
|
|
|
|
|
|
{
|
|
|
|
|
|
services.AddSingleton<IMailDeliveryService, MultiServiceMailDeliveryService>();
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2020-07-07 12:01:34 -04:00
|
|
|
|
else if (awsConfigured)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2020-07-07 12:01:34 -04:00
|
|
|
|
services.AddSingleton<IMailDeliveryService, AmazonSesMailDeliveryService>();
|
2022-08-29 14:53:16 -04:00
|
|
|
|
}
|
2020-07-07 12:01:34 -04:00
|
|
|
|
else if (CoreHelpers.SettingHasValue(globalSettings.Mail?.Smtp?.Host))
|
2022-08-29 14:53:16 -04:00
|
|
|
|
{
|
2017-05-05 20:57:33 -04:00
|
|
|
|
services.AddSingleton<IMailDeliveryService, MailKitSmtpMailDeliveryService>();
|
2022-08-29 14:53:16 -04:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2020-07-07 12:01:34 -04:00
|
|
|
|
services.AddSingleton<IMailDeliveryService, NoopMailDeliveryService>();
|
|
|
|
|
|
}
|
2021-06-16 12:47:41 -04:00
|
|
|
|
|
2021-07-21 13:42:06 -05:00
|
|
|
|
services.AddSingleton<IPushNotificationService, MultiServicePushNotificationService>();
|
2024-10-22 09:20:57 -07:00
|
|
|
|
if (globalSettings.SelfHosted)
|
2021-06-16 12:47:41 -04:00
|
|
|
|
{
|
2024-10-22 09:20:57 -07:00
|
|
|
|
if (CoreHelpers.SettingHasValue(globalSettings.PushRelayBaseUri) &&
|
|
|
|
|
|
globalSettings.Installation?.Id != null &&
|
|
|
|
|
|
CoreHelpers.SettingHasValue(globalSettings.Installation?.Key))
|
|
|
|
|
|
{
|
|
|
|
|
|
services.AddKeyedSingleton<IPushNotificationService, RelayPushNotificationService>("implementation");
|
|
|
|
|
|
services.AddSingleton<IPushRegistrationService, RelayPushRegistrationService>();
|
|
|
|
|
|
}
|
2024-10-24 12:45:13 -07:00
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
services.AddSingleton<IPushRegistrationService, NoopPushRegistrationService>();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-22 09:20:57 -07:00
|
|
|
|
if (CoreHelpers.SettingHasValue(globalSettings.InternalIdentityKey) &&
|
|
|
|
|
|
CoreHelpers.SettingHasValue(globalSettings.BaseServiceUri.InternalNotifications))
|
|
|
|
|
|
{
|
|
|
|
|
|
services.AddKeyedSingleton<IPushNotificationService, NotificationsApiPushNotificationService>("implementation");
|
|
|
|
|
|
}
|
2022-08-29 15:53:48 -04:00
|
|
|
|
}
|
2021-06-16 12:47:41 -04:00
|
|
|
|
else if (!globalSettings.SelfHosted)
|
2022-08-29 15:53:48 -04:00
|
|
|
|
{
|
2024-10-22 09:20:57 -07:00
|
|
|
|
services.AddSingleton<INotificationHubPool, NotificationHubPool>();
|
2018-04-03 14:31:33 -04:00
|
|
|
|
services.AddSingleton<IPushRegistrationService, NotificationHubPushRegistrationService>();
|
2024-10-22 09:20:57 -07:00
|
|
|
|
services.AddKeyedSingleton<IPushNotificationService, NotificationHubPushNotificationService>("implementation");
|
|
|
|
|
|
if (CoreHelpers.SettingHasValue(globalSettings.Notifications?.ConnectionString))
|
|
|
|
|
|
{
|
|
|
|
|
|
services.AddKeyedSingleton<IPushNotificationService, AzureQueuePushNotificationService>("implementation");
|
|
|
|
|
|
}
|
2021-06-16 12:47:41 -04:00
|
|
|
|
}
|
2017-05-05 20:57:33 -04:00
|
|
|
|
|
|
|
|
|
|
if (!globalSettings.SelfHosted && CoreHelpers.SettingHasValue(globalSettings.Mail.ConnectionString))
|
2022-08-29 14:53:16 -04:00
|
|
|
|
{
|
2017-05-05 20:57:33 -04:00
|
|
|
|
services.AddSingleton<IMailEnqueuingService, AzureQueueMailService>();
|
2022-08-29 14:53:16 -04:00
|
|
|
|
}
|
|
|
|
|
|
else
|
2017-05-05 20:57:33 -04:00
|
|
|
|
{
|
2017-06-15 15:34:12 -04:00
|
|
|
|
services.AddSingleton<IMailEnqueuingService, BlockingMailEnqueuingService>();
|
2017-05-05 20:57:33 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!globalSettings.SelfHosted && CoreHelpers.SettingHasValue(globalSettings.Events.ConnectionString))
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2017-05-05 20:57:33 -04:00
|
|
|
|
services.AddSingleton<IEventWriteService, AzureQueueEventWriteService>();
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2020-11-02 15:55:49 -05:00
|
|
|
|
else if (globalSettings.SelfHosted)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2017-05-05 20:57:33 -04:00
|
|
|
|
services.AddSingleton<IEventWriteService, RepositoryEventWriteService>();
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
|
|
|
|
|
else
|
2017-05-05 20:57:33 -04:00
|
|
|
|
{
|
2017-06-23 10:08:29 -04:00
|
|
|
|
services.AddSingleton<IEventWriteService, NoopEventWriteService>();
|
|
|
|
|
|
}
|
2018-09-12 10:35:05 -04:00
|
|
|
|
|
2018-09-12 00:15:59 -04:00
|
|
|
|
if (CoreHelpers.SettingHasValue(globalSettings.Attachment.ConnectionString))
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2018-09-12 00:15:59 -04:00
|
|
|
|
services.AddSingleton<IAttachmentStorageService, AzureAttachmentStorageService>();
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2018-09-12 00:15:59 -04:00
|
|
|
|
else if (CoreHelpers.SettingHasValue(globalSettings.Attachment.BaseDirectory))
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2018-09-12 00:15:59 -04:00
|
|
|
|
services.AddSingleton<IAttachmentStorageService, LocalAttachmentStorageService>();
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
|
|
|
|
|
else
|
2022-08-29 14:53:16 -04:00
|
|
|
|
{
|
2018-09-12 00:15:59 -04:00
|
|
|
|
services.AddSingleton<IAttachmentStorageService, NoopAttachmentStorageService>();
|
2022-08-29 14:53:16 -04:00
|
|
|
|
}
|
2018-03-21 14:26:49 -04:00
|
|
|
|
|
|
|
|
|
|
if (CoreHelpers.SettingHasValue(globalSettings.Send.ConnectionString))
|
2022-08-29 14:53:16 -04:00
|
|
|
|
{
|
2018-03-21 14:26:49 -04:00
|
|
|
|
services.AddSingleton<ISendFileStorageService, AzureSendFileStorageService>();
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2018-03-21 14:26:49 -04:00
|
|
|
|
else if (CoreHelpers.SettingHasValue(globalSettings.Send.BaseDirectory))
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2018-03-21 14:26:49 -04:00
|
|
|
|
services.AddSingleton<ISendFileStorageService, LocalSendStorageService>();
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2018-03-21 14:26:49 -04:00
|
|
|
|
else
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2018-03-21 14:26:49 -04:00
|
|
|
|
services.AddSingleton<ISendFileStorageService, NoopSendFileStorageService>();
|
2022-08-29 15:53:48 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-03-21 14:26:49 -04:00
|
|
|
|
if (globalSettings.SelfHosted)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2018-03-21 14:26:49 -04:00
|
|
|
|
services.AddSingleton<IReferenceEventService, NoopReferenceEventService>();
|
2022-08-29 15:53:48 -04:00
|
|
|
|
}
|
2018-03-21 14:26:49 -04:00
|
|
|
|
else
|
2022-08-29 15:53:48 -04:00
|
|
|
|
{
|
2018-03-21 14:26:49 -04:00
|
|
|
|
services.AddSingleton<IReferenceEventService, AzureQueueReferenceEventService>();
|
2022-08-29 15:53:48 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-03-21 14:26:49 -04:00
|
|
|
|
if (CoreHelpers.SettingHasValue(globalSettings.Captcha?.HCaptchaSecretKey) &&
|
2020-01-13 12:03:10 -05:00
|
|
|
|
CoreHelpers.SettingHasValue(globalSettings.Captcha?.HCaptchaSiteKey))
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2020-01-13 12:03:10 -05:00
|
|
|
|
services.AddSingleton<ICaptchaValidationService, HCaptchaValidationService>();
|
2022-08-29 15:53:48 -04:00
|
|
|
|
}
|
2018-09-12 10:35:05 -04:00
|
|
|
|
else
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2018-09-12 10:35:05 -04:00
|
|
|
|
services.AddSingleton<ICaptchaValidationService, NoopCaptchaValidationService>();
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2021-03-22 23:21:43 +01:00
|
|
|
|
}
|
2018-03-21 14:26:49 -04:00
|
|
|
|
|
2018-09-12 10:35:05 -04:00
|
|
|
|
public static void AddOosServices(this IServiceCollection services)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2018-09-12 10:35:05 -04:00
|
|
|
|
services.AddScoped<IProviderService, NoopProviderService>();
|
2023-07-24 23:05:05 +01:00
|
|
|
|
services.AddScoped<IServiceAccountRepository, NoopServiceAccountRepository>();
|
2023-08-05 07:51:12 +10:00
|
|
|
|
services.AddScoped<ISecretRepository, NoopSecretRepository>();
|
|
|
|
|
|
services.AddScoped<IProjectRepository, NoopProjectRepository>();
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2022-08-29 14:53:16 -04:00
|
|
|
|
|
2018-09-12 10:35:05 -04:00
|
|
|
|
public static void AddNoopServices(this IServiceCollection services)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2018-09-12 00:15:59 -04:00
|
|
|
|
services.AddSingleton<IMailService, NoopMailService>();
|
2018-09-12 10:35:05 -04:00
|
|
|
|
services.AddSingleton<IMailDeliveryService, NoopMailDeliveryService>();
|
2018-09-12 00:15:59 -04:00
|
|
|
|
services.AddSingleton<IPushNotificationService, NoopPushNotificationService>();
|
2018-09-12 10:35:05 -04:00
|
|
|
|
services.AddSingleton<IPushRegistrationService, NoopPushRegistrationService>();
|
|
|
|
|
|
services.AddSingleton<IAttachmentStorageService, NoopAttachmentStorageService>();
|
2018-09-12 00:15:59 -04:00
|
|
|
|
services.AddSingleton<ILicensingService, NoopLicensingService>();
|
2018-09-12 10:35:05 -04:00
|
|
|
|
services.AddSingleton<IEventWriteService, NoopEventWriteService>();
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2018-03-21 14:26:49 -04:00
|
|
|
|
|
2018-08-15 09:26:19 -04:00
|
|
|
|
public static IdentityBuilder AddCustomIdentityServices(
|
|
|
|
|
|
this IServiceCollection services, GlobalSettings globalSettings)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2024-11-18 15:58:05 -08:00
|
|
|
|
services.AddScoped<IOrganizationDuoUniversalTokenProvider, OrganizationDuoUniversalTokenProvider>();
|
2018-08-15 09:26:19 -04:00
|
|
|
|
services.Configure<PasswordHasherOptions>(options => options.IterationCount = 100000);
|
|
|
|
|
|
services.Configure<TwoFactorRememberTokenProviderOptions>(options =>
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2018-08-15 09:26:19 -04:00
|
|
|
|
options.TokenLifespan = TimeSpan.FromDays(30);
|
2022-08-29 16:06:55 -04:00
|
|
|
|
});
|
2022-08-29 15:53:48 -04:00
|
|
|
|
|
2018-08-15 09:26:19 -04:00
|
|
|
|
var identityBuilder = services.AddIdentityWithoutCookieAuth<User, Role>(options =>
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2018-08-15 09:26:19 -04:00
|
|
|
|
options.User = new UserOptions
|
2022-08-29 15:53:48 -04:00
|
|
|
|
{
|
2017-05-05 20:57:33 -04:00
|
|
|
|
RequireUniqueEmail = true,
|
2018-08-15 09:26:19 -04:00
|
|
|
|
AllowedUserNameCharacters = null // all
|
|
|
|
|
|
};
|
|
|
|
|
|
options.Password = new PasswordOptions
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2018-08-15 09:26:19 -04:00
|
|
|
|
RequireDigit = false,
|
|
|
|
|
|
RequireLowercase = false,
|
2023-02-16 13:15:45 -05:00
|
|
|
|
RequiredLength = 12,
|
2018-08-15 09:26:19 -04:00
|
|
|
|
RequireNonAlphanumeric = false,
|
2017-05-05 20:57:33 -04:00
|
|
|
|
RequireUppercase = false
|
2018-08-15 09:26:19 -04:00
|
|
|
|
};
|
|
|
|
|
|
options.ClaimsIdentity = new ClaimsIdentityOptions
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2023-01-13 15:02:53 +01:00
|
|
|
|
SecurityStampClaimType = Claims.SecurityStamp,
|
2018-08-15 09:26:19 -04:00
|
|
|
|
UserNameClaimType = JwtClaimTypes.Email,
|
2023-01-13 15:02:53 +01:00
|
|
|
|
UserIdClaimType = JwtClaimTypes.Subject,
|
2022-08-29 16:06:55 -04:00
|
|
|
|
};
|
2018-08-15 09:26:19 -04:00
|
|
|
|
options.Tokens.ChangeEmailTokenProvider = TokenOptions.DefaultEmailProvider;
|
|
|
|
|
|
});
|
2022-08-29 16:06:55 -04:00
|
|
|
|
|
2018-08-15 09:26:19 -04:00
|
|
|
|
identityBuilder
|
2018-09-12 10:35:05 -04:00
|
|
|
|
.AddUserStore<UserStore>()
|
2018-08-15 09:26:19 -04:00
|
|
|
|
.AddRoleStore<RoleStore>()
|
|
|
|
|
|
.AddTokenProvider<DataProtectorTokenProvider<User>>(TokenOptions.DefaultProvider)
|
2018-12-19 22:27:45 -05:00
|
|
|
|
.AddTokenProvider<AuthenticatorTokenProvider>(
|
2018-08-15 09:26:19 -04:00
|
|
|
|
CoreHelpers.CustomProviderName(TwoFactorProviderType.Authenticator))
|
2024-07-11 14:39:27 -04:00
|
|
|
|
.AddTokenProvider<EmailTwoFactorTokenProvider>(
|
2018-08-15 09:26:19 -04:00
|
|
|
|
CoreHelpers.CustomProviderName(TwoFactorProviderType.Email))
|
|
|
|
|
|
.AddTokenProvider<YubicoOtpTokenProvider>(
|
|
|
|
|
|
CoreHelpers.CustomProviderName(TwoFactorProviderType.YubiKey))
|
2024-11-18 15:58:05 -08:00
|
|
|
|
.AddTokenProvider<DuoUniversalTokenProvider>(
|
2018-12-19 22:27:45 -05:00
|
|
|
|
CoreHelpers.CustomProviderName(TwoFactorProviderType.Duo))
|
|
|
|
|
|
.AddTokenProvider<TwoFactorRememberTokenProvider>(
|
2018-08-15 09:26:19 -04:00
|
|
|
|
CoreHelpers.CustomProviderName(TwoFactorProviderType.Remember))
|
2024-07-11 14:39:27 -04:00
|
|
|
|
.AddTokenProvider<EmailTokenProvider>(TokenOptions.DefaultEmailProvider)
|
2021-03-22 23:21:43 +01:00
|
|
|
|
.AddTokenProvider<WebAuthnTokenProvider>(
|
|
|
|
|
|
CoreHelpers.CustomProviderName(TwoFactorProviderType.WebAuthn));
|
2022-08-29 16:06:55 -04:00
|
|
|
|
|
2018-08-15 09:26:19 -04:00
|
|
|
|
return identityBuilder;
|
2020-01-10 08:33:13 -05:00
|
|
|
|
}
|
2022-08-29 14:53:16 -04:00
|
|
|
|
|
2021-05-06 10:17:12 +02:00
|
|
|
|
public static void AddIdentityAuthenticationServices(
|
2020-03-27 14:36:37 -04:00
|
|
|
|
this IServiceCollection services, GlobalSettings globalSettings, IWebHostEnvironment environment,
|
|
|
|
|
|
Action<AuthorizationOptions> addAuthorization)
|
2018-08-15 09:26:19 -04:00
|
|
|
|
{
|
2023-11-20 16:32:23 -05:00
|
|
|
|
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
|
|
|
|
|
.AddJwtBearer(options =>
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2023-11-20 16:32:23 -05:00
|
|
|
|
options.MapInboundClaims = false;
|
2018-08-15 18:43:26 -04:00
|
|
|
|
options.Authority = globalSettings.BaseServiceUri.InternalIdentity;
|
|
|
|
|
|
options.RequireHttpsMetadata = !environment.IsDevelopment() &&
|
2018-08-15 09:26:19 -04:00
|
|
|
|
globalSettings.BaseServiceUri.InternalIdentity.StartsWith("https");
|
2023-11-20 16:32:23 -05:00
|
|
|
|
options.TokenValidationParameters.ValidateAudience = false;
|
|
|
|
|
|
options.TokenValidationParameters.ValidTypes = new[] { "at+jwt" };
|
|
|
|
|
|
options.TokenValidationParameters.NameClaimType = ClaimTypes.Email;
|
|
|
|
|
|
options.Events = new JwtBearerEvents
|
|
|
|
|
|
{
|
|
|
|
|
|
OnMessageReceived = (context) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
context.Token = TokenRetrieval.FromAuthorizationHeaderOrQueryString()(context.Request);
|
|
|
|
|
|
return Task.CompletedTask;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2018-08-15 18:43:26 -04:00
|
|
|
|
});
|
2019-02-26 17:01:06 -05:00
|
|
|
|
|
2020-03-27 14:36:37 -04:00
|
|
|
|
if (addAuthorization != null)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2020-03-27 14:36:37 -04:00
|
|
|
|
services.AddAuthorization(config =>
|
2019-02-26 17:01:06 -05:00
|
|
|
|
{
|
|
|
|
|
|
addAuthorization.Invoke(config);
|
|
|
|
|
|
});
|
2018-08-15 09:26:19 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-01-10 08:33:13 -05:00
|
|
|
|
if (environment.IsDevelopment())
|
2017-05-05 20:57:33 -04:00
|
|
|
|
{
|
2021-12-22 19:47:35 +01:00
|
|
|
|
Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2020-07-16 08:01:39 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static void AddCustomDataProtectionServices(
|
|
|
|
|
|
this IServiceCollection services, IWebHostEnvironment env, GlobalSettings globalSettings)
|
|
|
|
|
|
{
|
2023-01-18 13:16:57 -05:00
|
|
|
|
var builder = services.AddDataProtection().SetApplicationName("Bitwarden");
|
2020-07-16 08:01:39 -04:00
|
|
|
|
if (env.IsDevelopment())
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2020-07-16 08:01:39 -04:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (globalSettings.SelfHosted && CoreHelpers.SettingHasValue(globalSettings.DataProtection.Directory))
|
2022-08-29 15:53:48 -04:00
|
|
|
|
{
|
2021-12-22 19:47:35 +01:00
|
|
|
|
builder.PersistKeysToFileSystem(new DirectoryInfo(globalSettings.DataProtection.Directory));
|
2020-07-16 08:01:39 -04:00
|
|
|
|
}
|
2017-05-05 20:57:33 -04:00
|
|
|
|
|
2020-07-16 08:01:39 -04:00
|
|
|
|
if (!globalSettings.SelfHosted && CoreHelpers.SettingHasValue(globalSettings.Storage?.ConnectionString))
|
|
|
|
|
|
{
|
2020-08-25 13:15:59 -04:00
|
|
|
|
X509Certificate2 dataProtectionCert = null;
|
|
|
|
|
|
if (CoreHelpers.SettingHasValue(globalSettings.DataProtection.CertificateThumbprint))
|
2017-05-05 20:57:33 -04:00
|
|
|
|
{
|
2020-08-25 13:15:59 -04:00
|
|
|
|
dataProtectionCert = CoreHelpers.GetCertificate(
|
|
|
|
|
|
globalSettings.DataProtection.CertificateThumbprint);
|
2019-07-10 20:05:07 -04:00
|
|
|
|
}
|
2020-08-21 11:58:22 -04:00
|
|
|
|
else if (CoreHelpers.SettingHasValue(globalSettings.DataProtection.CertificatePassword))
|
|
|
|
|
|
{
|
|
|
|
|
|
dataProtectionCert = CoreHelpers.GetBlobCertificateAsync(globalSettings.Storage.ConnectionString, "certificates",
|
|
|
|
|
|
"dataprotection.pfx", globalSettings.DataProtection.CertificatePassword)
|
|
|
|
|
|
.GetAwaiter().GetResult();
|
|
|
|
|
|
}
|
2017-08-07 16:31:00 -04:00
|
|
|
|
builder
|
|
|
|
|
|
.PersistKeysToAzureBlobStorage(globalSettings.Storage.ConnectionString, "aspnet-dataprotection", "keys.xml")
|
|
|
|
|
|
.ProtectKeysWithCertificate(dataProtectionCert);
|
2017-05-05 20:57:33 -04:00
|
|
|
|
}
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2017-05-05 20:57:33 -04:00
|
|
|
|
|
|
|
|
|
|
public static IIdentityServerBuilder AddIdentityServerCertificate(
|
|
|
|
|
|
this IIdentityServerBuilder identityServerBuilder, IWebHostEnvironment env, GlobalSettings globalSettings)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2017-05-05 20:57:33 -04:00
|
|
|
|
var certificate = CoreHelpers.GetIdentityServerCertificate(globalSettings);
|
|
|
|
|
|
if (certificate != null)
|
|
|
|
|
|
{
|
2017-10-19 00:08:09 -04:00
|
|
|
|
identityServerBuilder.AddSigningCredential(certificate);
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2023-12-08 15:14:49 -05:00
|
|
|
|
else if (env.IsDevelopment() && !string.IsNullOrEmpty(globalSettings.DevelopmentDirectory))
|
|
|
|
|
|
{
|
|
|
|
|
|
var developerSigningKeyPath = Path.Combine(globalSettings.DevelopmentDirectory, "signingkey.jwk");
|
|
|
|
|
|
identityServerBuilder.AddDeveloperSigningCredential(true, developerSigningKeyPath);
|
|
|
|
|
|
}
|
2017-10-19 00:08:09 -04:00
|
|
|
|
else if (env.IsDevelopment())
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2017-10-19 00:08:09 -04:00
|
|
|
|
identityServerBuilder.AddDeveloperSigningCredential(false);
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2017-10-19 00:08:09 -04:00
|
|
|
|
throw new Exception("No identity certificate to use.");
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2017-10-19 00:08:09 -04:00
|
|
|
|
return identityServerBuilder;
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2022-03-21 18:13:00 -04:00
|
|
|
|
|
|
|
|
|
|
public static GlobalSettings AddGlobalSettingsServices(this IServiceCollection services,
|
2023-03-30 15:37:19 +02:00
|
|
|
|
IConfiguration configuration, IHostEnvironment environment)
|
2022-03-21 18:13:00 -04:00
|
|
|
|
{
|
|
|
|
|
|
var globalSettings = new GlobalSettings();
|
|
|
|
|
|
ConfigurationBinder.Bind(configuration.GetSection("GlobalSettings"), globalSettings);
|
|
|
|
|
|
|
2017-05-05 20:57:33 -04:00
|
|
|
|
if (environment.IsDevelopment() && configuration.GetValue<bool>("developSelfHosted"))
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2017-05-05 20:57:33 -04:00
|
|
|
|
// Override settings with selfHostedOverride settings
|
2021-02-25 07:00:28 -06:00
|
|
|
|
ConfigurationBinder.Bind(configuration.GetSection("Dev:SelfHostOverride:GlobalSettings"), globalSettings);
|
2017-05-05 20:57:33 -04:00
|
|
|
|
}
|
2017-07-21 12:53:26 -04:00
|
|
|
|
|
2021-05-06 10:17:12 +02:00
|
|
|
|
services.AddSingleton(s => globalSettings);
|
|
|
|
|
|
services.AddSingleton<IGlobalSettings, GlobalSettings>(s => globalSettings);
|
2021-02-25 07:00:28 -06:00
|
|
|
|
return globalSettings;
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-09-03 14:44:22 -04:00
|
|
|
|
public static void UseDefaultMiddleware(this IApplicationBuilder app,
|
2020-01-10 08:33:13 -05:00
|
|
|
|
IWebHostEnvironment env, GlobalSettings globalSettings)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2024-10-03 08:30:02 -04:00
|
|
|
|
app.UseMiddleware<RequestLoggingMiddleware>();
|
2017-07-21 12:53:26 -04:00
|
|
|
|
}
|
2019-04-26 09:52:54 -04:00
|
|
|
|
|
2023-06-08 08:41:36 -05:00
|
|
|
|
public static void UseForwardedHeaders(this IApplicationBuilder app, IGlobalSettings globalSettings)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2019-04-26 09:52:54 -04:00
|
|
|
|
var options = new ForwardedHeadersOptions
|
2022-08-29 14:53:16 -04:00
|
|
|
|
{
|
2019-04-26 09:52:54 -04:00
|
|
|
|
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
|
|
|
|
|
|
};
|
2023-06-08 08:41:36 -05:00
|
|
|
|
|
|
|
|
|
|
if (!globalSettings.UnifiedDeployment)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Trust the X-Forwarded-Host header of the nginx docker container
|
2023-06-14 09:33:26 -05:00
|
|
|
|
try
|
2023-06-08 08:41:36 -05:00
|
|
|
|
{
|
2023-06-14 09:33:26 -05:00
|
|
|
|
var nginxIp = Dns.GetHostEntry("nginx")?.AddressList.FirstOrDefault();
|
|
|
|
|
|
if (nginxIp != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
options.KnownProxies.Add(nginxIp);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
// Ignore DNS errors
|
2023-06-08 08:41:36 -05:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-04-26 09:52:54 -04:00
|
|
|
|
if (!string.IsNullOrWhiteSpace(globalSettings.KnownProxies))
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2020-03-27 14:36:37 -04:00
|
|
|
|
var proxies = globalSettings.KnownProxies.Split(',');
|
|
|
|
|
|
foreach (var proxy in proxies)
|
2019-04-26 09:52:54 -04:00
|
|
|
|
{
|
2023-06-08 08:41:36 -05:00
|
|
|
|
if (IPAddress.TryParse(proxy.Trim(), out var ip))
|
2019-04-26 09:52:54 -04:00
|
|
|
|
{
|
|
|
|
|
|
options.KnownProxies.Add(ip);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-08-28 12:14:23 -04:00
|
|
|
|
if (options.KnownProxies.Count > 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
options.ForwardLimit = null;
|
|
|
|
|
|
}
|
2019-04-26 09:52:54 -04:00
|
|
|
|
app.UseForwardedHeaders(options);
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2020-08-28 12:14:23 -04:00
|
|
|
|
|
|
|
|
|
|
public static void AddCoreLocalizationServices(this IServiceCollection services)
|
|
|
|
|
|
{
|
|
|
|
|
|
services.AddTransient<II18nService, I18nService>();
|
2021-12-22 19:47:35 +01:00
|
|
|
|
services.AddLocalization(options => options.ResourcesPath = "Resources");
|
2020-08-28 12:14:23 -04:00
|
|
|
|
}
|
2021-01-11 11:03:46 -05:00
|
|
|
|
|
2020-08-28 12:14:23 -04:00
|
|
|
|
public static IApplicationBuilder UseCoreLocalization(this IApplicationBuilder app)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2020-08-28 12:14:23 -04:00
|
|
|
|
var supportedCultures = new[] { "en" };
|
2021-12-22 19:47:35 +01:00
|
|
|
|
return app.UseRequestLocalization(options => options
|
2020-08-28 12:14:23 -04:00
|
|
|
|
.SetDefaultCulture(supportedCultures[0])
|
|
|
|
|
|
.AddSupportedCultures(supportedCultures)
|
|
|
|
|
|
.AddSupportedUICultures(supportedCultures));
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-01-11 11:03:46 -05:00
|
|
|
|
public static IMvcBuilder AddViewAndDataAnnotationLocalization(this IMvcBuilder mvc)
|
2022-08-29 14:53:16 -04:00
|
|
|
|
{
|
2021-01-11 11:03:46 -05:00
|
|
|
|
mvc.Services.AddTransient<IViewLocalizer, I18nViewLocalizer>();
|
|
|
|
|
|
return mvc.AddViewLocalization(options => options.ResourcesPath = "Resources")
|
|
|
|
|
|
.AddDataAnnotationsLocalization(options =>
|
|
|
|
|
|
options.DataAnnotationLocalizerProvider = (type, factory) =>
|
2022-08-29 15:53:48 -04:00
|
|
|
|
{
|
2021-01-11 11:03:46 -05:00
|
|
|
|
var assemblyName = new AssemblyName(typeof(SharedResources).GetTypeInfo().Assembly.FullName);
|
|
|
|
|
|
return factory.Create("SharedResources", assemblyName.Name);
|
2022-08-29 15:53:48 -04:00
|
|
|
|
});
|
2022-08-29 14:53:16 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-02-09 07:43:28 -05:00
|
|
|
|
public static IServiceCollection AddDistributedIdentityServices(this IServiceCollection services)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2021-01-11 11:03:46 -05:00
|
|
|
|
services.AddOidcStateDataFormatterCache();
|
|
|
|
|
|
services.AddSession();
|
|
|
|
|
|
services.ConfigureApplicationCookie(configure => configure.CookieManager = new DistributedCacheCookieManager());
|
|
|
|
|
|
services.ConfigureExternalCookie(configure => configure.CookieManager = new DistributedCacheCookieManager());
|
2024-02-09 07:43:28 -05:00
|
|
|
|
services.AddSingleton<IPostConfigureOptions<CookieAuthenticationOptions>, ConfigureOpenIdConnectDistributedOptions>();
|
2022-08-29 16:06:55 -04:00
|
|
|
|
|
2021-01-11 11:03:46 -05:00
|
|
|
|
return services;
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-05-06 10:17:12 +02:00
|
|
|
|
public static void AddWebAuthn(this IServiceCollection services, GlobalSettings globalSettings)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2022-06-24 10:39:34 -04:00
|
|
|
|
services.AddFido2(options =>
|
2021-01-11 11:03:46 -05:00
|
|
|
|
{
|
|
|
|
|
|
options.ServerDomain = new Uri(globalSettings.BaseServiceUri.Vault).Host;
|
|
|
|
|
|
options.ServerName = "Bitwarden";
|
|
|
|
|
|
options.Origins = new HashSet<string> { globalSettings.BaseServiceUri.Vault, };
|
|
|
|
|
|
options.TimestampDriftTolerance = 300000;
|
|
|
|
|
|
});
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2021-01-11 11:03:46 -05:00
|
|
|
|
|
2022-07-19 11:58:32 -07:00
|
|
|
|
/// <summary>
|
2021-01-11 11:03:46 -05:00
|
|
|
|
/// Adds either an in-memory or distributed IP rate limiter depending if a Redis connection string is available.
|
2022-07-19 11:58:32 -07:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="services"></param>
|
|
|
|
|
|
/// <param name="globalSettings"></param>
|
|
|
|
|
|
public static void AddIpRateLimiting(this IServiceCollection services,
|
|
|
|
|
|
GlobalSettings globalSettings)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2021-01-11 11:03:46 -05:00
|
|
|
|
services.AddHostedService<IpRateLimitSeedStartupService>();
|
|
|
|
|
|
services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
|
2021-05-06 10:17:12 +02:00
|
|
|
|
|
2024-02-07 17:38:18 -05:00
|
|
|
|
if (!globalSettings.DistributedIpRateLimiting.Enabled ||
|
|
|
|
|
|
string.IsNullOrEmpty(globalSettings.DistributedIpRateLimiting.RedisConnectionString))
|
2021-05-06 10:17:12 +02:00
|
|
|
|
{
|
2022-06-24 10:39:34 -04:00
|
|
|
|
services.AddInMemoryRateLimiting();
|
2021-05-06 10:17:12 +02:00
|
|
|
|
}
|
2022-07-19 11:58:32 -07:00
|
|
|
|
else
|
|
|
|
|
|
{
|
2022-08-31 14:17:29 -07:00
|
|
|
|
// Use memory stores for Ip and Client Policy stores as we don't currently use them
|
|
|
|
|
|
// and they add unnecessary Redis network delays checking for policies that don't exist
|
|
|
|
|
|
services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();
|
|
|
|
|
|
services.AddSingleton<IClientPolicyStore, MemoryCacheClientPolicyStore>();
|
|
|
|
|
|
|
|
|
|
|
|
// Use a custom Redis processing strategy that skips Ip limiting if Redis is down
|
2024-02-07 17:38:18 -05:00
|
|
|
|
services.AddKeyedSingleton<IConnectionMultiplexer>("rate-limiter", (_, provider) =>
|
|
|
|
|
|
ConnectionMultiplexer.Connect(globalSettings.DistributedIpRateLimiting.RedisConnectionString));
|
2022-08-31 14:17:29 -07:00
|
|
|
|
services.AddSingleton<IProcessingStrategy, CustomRedisProcessingStrategy>();
|
2022-07-19 11:58:32 -07:00
|
|
|
|
}
|
2022-08-29 16:06:55 -04:00
|
|
|
|
}
|
2022-07-19 11:58:32 -07:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Adds an implementation of <see cref="IDistributedCache"/> to the service collection. Uses a memory
|
|
|
|
|
|
/// cache if self hosted or no Redis connection string is available in GlobalSettings.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void AddDistributedCache(
|
|
|
|
|
|
this IServiceCollection services,
|
|
|
|
|
|
GlobalSettings globalSettings)
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2024-02-08 14:34:53 -05:00
|
|
|
|
if (!string.IsNullOrEmpty(globalSettings.DistributedCache?.Redis?.ConnectionString))
|
|
|
|
|
|
{
|
|
|
|
|
|
services.AddStackExchangeRedisCache(options =>
|
|
|
|
|
|
{
|
|
|
|
|
|
options.Configuration = globalSettings.DistributedCache.Redis.ConnectionString;
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
2022-07-19 11:58:32 -07:00
|
|
|
|
{
|
2024-07-03 12:48:23 -04:00
|
|
|
|
var (databaseProvider, databaseConnectionString) = GetDatabaseProvider(globalSettings);
|
|
|
|
|
|
if (databaseProvider == SupportedDatabaseProviders.SqlServer)
|
|
|
|
|
|
{
|
|
|
|
|
|
services.AddDistributedSqlServerCache(o =>
|
|
|
|
|
|
{
|
|
|
|
|
|
o.ConnectionString = databaseConnectionString;
|
|
|
|
|
|
o.SchemaName = "dbo";
|
|
|
|
|
|
o.TableName = "Cache";
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
services.AddSingleton<IDistributedCache, EntityFrameworkCache>();
|
|
|
|
|
|
}
|
2022-07-19 11:58:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-02-08 14:34:53 -05:00
|
|
|
|
if (!string.IsNullOrEmpty(globalSettings.DistributedCache?.Cosmos?.ConnectionString))
|
2022-08-29 16:06:55 -04:00
|
|
|
|
{
|
2024-02-08 14:34:53 -05:00
|
|
|
|
services.AddKeyedSingleton<IDistributedCache>("persistent", (s, _) =>
|
|
|
|
|
|
new CosmosCache(new CosmosCacheOptions
|
|
|
|
|
|
{
|
|
|
|
|
|
DatabaseName = "cache",
|
|
|
|
|
|
ContainerName = "default",
|
|
|
|
|
|
CreateIfNotExists = false,
|
|
|
|
|
|
ClientBuilder = new CosmosClientBuilder(globalSettings.DistributedCache?.Cosmos?.ConnectionString)
|
|
|
|
|
|
}));
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2024-07-03 12:48:23 -04:00
|
|
|
|
services.AddKeyedSingleton("persistent", (s, _) => s.GetRequiredService<IDistributedCache>());
|
2024-02-08 14:34:53 -05:00
|
|
|
|
}
|
2017-05-05 20:57:33 -04:00
|
|
|
|
}
|
2024-01-18 09:47:34 -05:00
|
|
|
|
|
|
|
|
|
|
public static IServiceCollection AddOptionality(this IServiceCollection services)
|
|
|
|
|
|
{
|
|
|
|
|
|
services.AddSingleton<ILdClient>(s =>
|
|
|
|
|
|
{
|
|
|
|
|
|
return new LdClient(LaunchDarklyFeatureService.GetConfiguredClient(
|
|
|
|
|
|
s.GetRequiredService<GlobalSettings>()));
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
services.AddScoped<IFeatureService, LaunchDarklyFeatureService>();
|
|
|
|
|
|
|
|
|
|
|
|
return services;
|
|
|
|
|
|
}
|
2024-07-03 12:48:23 -04:00
|
|
|
|
|
|
|
|
|
|
private static (SupportedDatabaseProviders provider, string connectionString)
|
|
|
|
|
|
GetDatabaseProvider(GlobalSettings globalSettings)
|
|
|
|
|
|
{
|
|
|
|
|
|
var selectedDatabaseProvider = globalSettings.DatabaseProvider;
|
|
|
|
|
|
var provider = SupportedDatabaseProviders.SqlServer;
|
|
|
|
|
|
var connectionString = string.Empty;
|
|
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(selectedDatabaseProvider))
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (selectedDatabaseProvider.ToLowerInvariant())
|
|
|
|
|
|
{
|
|
|
|
|
|
case "postgres":
|
|
|
|
|
|
case "postgresql":
|
|
|
|
|
|
provider = SupportedDatabaseProviders.Postgres;
|
|
|
|
|
|
connectionString = globalSettings.PostgreSql.ConnectionString;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case "mysql":
|
|
|
|
|
|
case "mariadb":
|
|
|
|
|
|
provider = SupportedDatabaseProviders.MySql;
|
|
|
|
|
|
connectionString = globalSettings.MySql.ConnectionString;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case "sqlite":
|
|
|
|
|
|
provider = SupportedDatabaseProviders.Sqlite;
|
|
|
|
|
|
connectionString = globalSettings.Sqlite.ConnectionString;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case "sqlserver":
|
|
|
|
|
|
connectionString = globalSettings.SqlServer.ConnectionString;
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// Default to attempting to use SqlServer connection string if globalSettings.DatabaseProvider has no value.
|
|
|
|
|
|
connectionString = globalSettings.SqlServer.ConnectionString;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return (provider, connectionString);
|
|
|
|
|
|
}
|
2017-05-05 20:57:33 -04:00
|
|
|
|
}
|