using System.Net.Http.Json; using System.Text.Json; using Bit.Core.Auth.Models.Api.Request.Accounts; using Bit.Core.Enums; using Bit.Core.Utilities; using Bit.Identity; using Bit.Identity.Models.Request.Accounts; using Bit.Test.Common.Helpers; using HandlebarsDotNet; using Microsoft.AspNetCore.Http; namespace Bit.IntegrationTestCommon.Factories; public class IdentityApplicationFactory : WebApplicationFactoryBase { public const string DefaultDeviceIdentifier = "92b9d953-b9b6-4eaf-9d3e-11d57144dfeb"; public async Task RegisterAsync(RegisterRequestModel model) { return await Server.PostAsync("/accounts/register", JsonContent.Create(model)); } public async Task PostRegisterSendEmailVerificationAsync(RegisterSendVerificationEmailRequestModel model) { return await Server.PostAsync("/accounts/register/send-verification-email", JsonContent.Create(model)); } public async Task PostRegisterFinishAsync(RegisterFinishRequestModel model) { return await Server.PostAsync("/accounts/register/finish", JsonContent.Create(model)); } public async Task PostRegisterVerificationEmailClicked(RegisterVerificationEmailClickedRequestModel model) { return await Server.PostAsync("/accounts/register/verification-email-clicked", JsonContent.Create(model)); } public async Task<(string Token, string RefreshToken)> TokenFromPasswordAsync( string username, string password, string deviceIdentifier = DefaultDeviceIdentifier, string clientId = "web", DeviceType deviceType = DeviceType.FirefoxBrowser, string deviceName = "firefox") { var context = await ContextFromPasswordAsync( username, password, deviceIdentifier, clientId, deviceType, deviceName); using var body = await AssertHelper.AssertResponseTypeIs(context); var root = body.RootElement; return (root.GetProperty("access_token").GetString(), root.GetProperty("refresh_token").GetString()); } public async Task ContextFromPasswordAsync( string username, string password, string deviceIdentifier = DefaultDeviceIdentifier, string clientId = "web", DeviceType deviceType = DeviceType.FirefoxBrowser, string deviceName = "firefox") { var context = await Server.PostAsync("/connect/token", new FormUrlEncodedContent(new Dictionary { { "scope", "api offline_access" }, { "client_id", clientId }, { "deviceType", ((int)deviceType).ToString() }, { "deviceIdentifier", deviceIdentifier }, { "deviceName", deviceName }, { "grant_type", "password" }, { "username", username }, { "password", password }, }), context => context.Request.Headers.Append("Auth-Email", CoreHelpers.Base64UrlEncodeString(username))); return context; } public async Task ContextFromPasswordWithTwoFactorAsync( string username, string password, string deviceIdentifier = DefaultDeviceIdentifier, string clientId = "web", DeviceType deviceType = DeviceType.FirefoxBrowser, string deviceName = "firefox", string twoFactorProviderType = "Email", string twoFactorToken = "two-factor-token") { var context = await Server.PostAsync("/connect/token", new FormUrlEncodedContent(new Dictionary { { "scope", "api offline_access" }, { "client_id", clientId }, { "deviceType", ((int)deviceType).ToString() }, { "deviceIdentifier", deviceIdentifier }, { "deviceName", deviceName }, { "grant_type", "password" }, { "username", username }, { "password", password }, { "TwoFactorToken", twoFactorToken }, { "TwoFactorProvider", twoFactorProviderType }, { "TwoFactorRemember", "1" }, }), context => context.Request.Headers.Append("Auth-Email", CoreHelpers.Base64UrlEncodeString(username))); return context; } public async Task TokenFromAccessTokenAsync(Guid clientId, string clientSecret, DeviceType deviceType = DeviceType.SDK) { var context = await ContextFromAccessTokenAsync(clientId, clientSecret, deviceType); using var body = await AssertHelper.AssertResponseTypeIs(context); var root = body.RootElement; return root.GetProperty("access_token").GetString(); } public async Task ContextFromAccessTokenAsync(Guid clientId, string clientSecret, DeviceType deviceType = DeviceType.SDK) { var context = await Server.PostAsync("/connect/token", new FormUrlEncodedContent(new Dictionary { { "scope", "api.secrets" }, { "client_id", clientId.ToString() }, { "client_secret", clientSecret }, { "grant_type", "client_credentials" }, { "deviceType", ((int)deviceType).ToString() } })); return context; } public async Task TokenFromOrganizationApiKeyAsync(string clientId, string clientSecret, DeviceType deviceType = DeviceType.FirefoxBrowser) { var context = await ContextFromOrganizationApiKeyAsync(clientId, clientSecret, deviceType); using var body = await AssertHelper.AssertResponseTypeIs(context); var root = body.RootElement; return root.GetProperty("access_token").GetString(); } public async Task ContextFromOrganizationApiKeyAsync(string clientId, string clientSecret, DeviceType deviceType = DeviceType.FirefoxBrowser) { var context = await Server.PostAsync("/connect/token", new FormUrlEncodedContent(new Dictionary { { "scope", "api.organization" }, { "client_id", clientId }, { "client_secret", clientSecret }, { "grant_type", "client_credentials" }, { "deviceType", ((int)deviceType).ToString() } })); return context; } }