mirror of
https://github.com/bitwarden/server.git
synced 2024-11-24 12:35:25 +01:00
Move identity endpoints to Identity service (#1807)
This commit is contained in:
parent
56ee3bd290
commit
0def1830af
@ -81,8 +81,11 @@ EndProject
|
|||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharedWeb", "src\SharedWeb\SharedWeb.csproj", "{713D44C0-1BC1-4024-96A3-A98A49F33908}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharedWeb", "src\SharedWeb\SharedWeb.csproj", "{713D44C0-1BC1-4024-96A3-A98A49F33908}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Infrastructure.EntityFramework", "src\Infrastructure.EntityFramework\Infrastructure.EntityFramework.csproj", "{ED880735-0250-43C7-9662-FDC7C7416E7F}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Infrastructure.EntityFramework", "src\Infrastructure.EntityFramework\Infrastructure.EntityFramework.csproj", "{ED880735-0250-43C7-9662-FDC7C7416E7F}"
|
||||||
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Billing.Test", "test\Billing.Test\Billing.Test.csproj", "{B8639B10-2157-44BC-8CE1-D9EB4B50971F}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Billing.Test", "test\Billing.Test\Billing.Test.csproj", "{B8639B10-2157-44BC-8CE1-D9EB4B50971F}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Identity.Test", "test\Identity.Test\Identity.Test.csproj", "{310A1D8E-2D3F-4FA0-84D4-FFE31FCE193E}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -195,6 +198,10 @@ Global
|
|||||||
{B8639B10-2157-44BC-8CE1-D9EB4B50971F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{B8639B10-2157-44BC-8CE1-D9EB4B50971F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{B8639B10-2157-44BC-8CE1-D9EB4B50971F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{B8639B10-2157-44BC-8CE1-D9EB4B50971F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{B8639B10-2157-44BC-8CE1-D9EB4B50971F}.Release|Any CPU.Build.0 = Release|Any CPU
|
{B8639B10-2157-44BC-8CE1-D9EB4B50971F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{310A1D8E-2D3F-4FA0-84D4-FFE31FCE193E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{310A1D8E-2D3F-4FA0-84D4-FFE31FCE193E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{310A1D8E-2D3F-4FA0-84D4-FFE31FCE193E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{310A1D8E-2D3F-4FA0-84D4-FFE31FCE193E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@ -226,6 +233,7 @@ Global
|
|||||||
{713D44C0-1BC1-4024-96A3-A98A49F33908} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
{713D44C0-1BC1-4024-96A3-A98A49F33908} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
||||||
{ED880735-0250-43C7-9662-FDC7C7416E7F} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
{ED880735-0250-43C7-9662-FDC7C7416E7F} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D}
|
||||||
{B8639B10-2157-44BC-8CE1-D9EB4B50971F} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84F}
|
{B8639B10-2157-44BC-8CE1-D9EB4B50971F} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84F}
|
||||||
|
{310A1D8E-2D3F-4FA0-84D4-FFE31FCE193E} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84F}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {E01CBF68-2E20-425F-9EDB-E0A6510CA92F}
|
SolutionGuid = {E01CBF68-2E20-425F-9EDB-E0A6510CA92F}
|
||||||
|
@ -11,6 +11,8 @@ using Bit.Core.Entities;
|
|||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Enums.Provider;
|
using Bit.Core.Enums.Provider;
|
||||||
using Bit.Core.Exceptions;
|
using Bit.Core.Exceptions;
|
||||||
|
using Bit.Core.Models.Api.Request.Accounts;
|
||||||
|
using Bit.Core.Models.Api.Response.Accounts;
|
||||||
using Bit.Core.Models.Business;
|
using Bit.Core.Models.Business;
|
||||||
using Bit.Core.Models.Data;
|
using Bit.Core.Models.Data;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
@ -64,6 +66,9 @@ namespace Bit.Api.Controllers
|
|||||||
_sendService = sendService;
|
_sendService = sendService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region DEPRECATED (Moved to Identity Service)
|
||||||
|
|
||||||
|
[Obsolete("2022-01-12 Moved to Identity, left for backwards compatability with older clients")]
|
||||||
[HttpPost("prelogin")]
|
[HttpPost("prelogin")]
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
public async Task<PreloginResponseModel> PostPrelogin([FromBody] PreloginRequestModel model)
|
public async Task<PreloginResponseModel> PostPrelogin([FromBody] PreloginRequestModel model)
|
||||||
@ -74,12 +79,13 @@ namespace Bit.Api.Controllers
|
|||||||
kdfInformation = new UserKdfInformation
|
kdfInformation = new UserKdfInformation
|
||||||
{
|
{
|
||||||
Kdf = KdfType.PBKDF2_SHA256,
|
Kdf = KdfType.PBKDF2_SHA256,
|
||||||
KdfIterations = 100000
|
KdfIterations = 100000,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return new PreloginResponseModel(kdfInformation);
|
return new PreloginResponseModel(kdfInformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Obsolete("2022-01-12 Moved to Identity, left for backwards compatability with older clients")]
|
||||||
[HttpPost("register")]
|
[HttpPost("register")]
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
[CaptchaProtected]
|
[CaptchaProtected]
|
||||||
@ -101,6 +107,8 @@ namespace Bit.Api.Controllers
|
|||||||
throw new BadRequestException(ModelState);
|
throw new BadRequestException(ModelState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
[HttpPost("password-hint")]
|
[HttpPost("password-hint")]
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
public async Task PostPasswordHint([FromBody] PasswordHintRequestModel model)
|
public async Task PostPasswordHint([FromBody] PasswordHintRequestModel model)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
|
using Bit.Core.Models.Api.Request.Accounts;
|
||||||
|
|
||||||
namespace Bit.Api.Models.Request.Accounts
|
namespace Bit.Api.Models.Request.Accounts
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
|
using Bit.Core.Models.Api.Request.Accounts;
|
||||||
|
|
||||||
namespace Bit.Api.Models.Request.Accounts
|
namespace Bit.Api.Models.Request.Accounts
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
|
|
||||||
namespace Bit.Api.Models.Request.Accounts
|
namespace Bit.Core.Models.Api.Request.Accounts
|
||||||
{
|
{
|
||||||
public class KeysRequestModel
|
public class KeysRequestModel
|
||||||
{
|
{
|
@ -1,6 +1,6 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace Bit.Api.Models.Request.Accounts
|
namespace Bit.Core.Models.Api.Request.Accounts
|
||||||
{
|
{
|
||||||
public class PreloginRequestModel
|
public class PreloginRequestModel
|
||||||
{
|
{
|
@ -3,11 +3,10 @@ using System.Collections.Generic;
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Models.Api;
|
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Bit.Api.Models.Request.Accounts
|
namespace Bit.Core.Models.Api.Request.Accounts
|
||||||
{
|
{
|
||||||
public class RegisterRequestModel : IValidatableObject, ICaptchaProtectedModel
|
public class RegisterRequestModel : IValidatableObject, ICaptchaProtectedModel
|
||||||
{
|
{
|
@ -1,7 +1,7 @@
|
|||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Models.Data;
|
using Bit.Core.Models.Data;
|
||||||
|
|
||||||
namespace Bit.Api.Models.Response
|
namespace Bit.Core.Models.Api.Response.Accounts
|
||||||
{
|
{
|
||||||
public class PreloginResponseModel
|
public class PreloginResponseModel
|
||||||
{
|
{
|
70
src/Identity/Controllers/AccountsController.cs
Normal file
70
src/Identity/Controllers/AccountsController.cs
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Bit.Core.Enums;
|
||||||
|
using Bit.Core.Exceptions;
|
||||||
|
using Bit.Core.Models.Api.Request.Accounts;
|
||||||
|
using Bit.Core.Models.Api.Response.Accounts;
|
||||||
|
using Bit.Core.Models.Data;
|
||||||
|
using Bit.Core.Repositories;
|
||||||
|
using Bit.Core.Services;
|
||||||
|
using Bit.Core.Utilities;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace Bit.Identity.Controllers
|
||||||
|
{
|
||||||
|
[Route("accounts")]
|
||||||
|
public class AccountsController : Controller
|
||||||
|
{
|
||||||
|
private readonly ILogger<AccountsController> _logger;
|
||||||
|
private readonly IUserRepository _userRepository;
|
||||||
|
private readonly IUserService _userService;
|
||||||
|
|
||||||
|
public AccountsController(
|
||||||
|
ILogger<AccountsController> logger,
|
||||||
|
IUserRepository userRepository,
|
||||||
|
IUserService userService)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_userRepository = userRepository;
|
||||||
|
_userService = userService;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Moved from API, If you modify this endpoint, please update Identity as well.
|
||||||
|
[HttpPost("register")]
|
||||||
|
[CaptchaProtected]
|
||||||
|
public async Task PostRegister([FromBody] RegisterRequestModel model)
|
||||||
|
{
|
||||||
|
var result = await _userService.RegisterUserAsync(model.ToUser(), model.MasterPasswordHash,
|
||||||
|
model.Token, model.OrganizationUserId);
|
||||||
|
if (result.Succeeded)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var error in result.Errors.Where(e => e.Code != "DuplicateUserName"))
|
||||||
|
{
|
||||||
|
ModelState.AddModelError(string.Empty, error.Description);
|
||||||
|
}
|
||||||
|
|
||||||
|
await Task.Delay(2000);
|
||||||
|
throw new BadRequestException(ModelState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Moved from API, If you modify this endpoint, please update Identity as well.
|
||||||
|
[HttpPost("prelogin")]
|
||||||
|
public async Task<PreloginResponseModel> PostPrelogin([FromBody] PreloginRequestModel model)
|
||||||
|
{
|
||||||
|
var kdfInformation = await _userRepository.GetKdfInformationByEmailAsync(model.Email);
|
||||||
|
if (kdfInformation == null)
|
||||||
|
{
|
||||||
|
kdfInformation = new UserKdfInformation
|
||||||
|
{
|
||||||
|
Kdf = KdfType.PBKDF2_SHA256,
|
||||||
|
KdfIterations = 100000,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return new PreloginResponseModel(kdfInformation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -11,7 +11,6 @@ using Bit.Identity.Models;
|
|||||||
using IdentityModel;
|
using IdentityModel;
|
||||||
using IdentityServer4;
|
using IdentityServer4;
|
||||||
using IdentityServer4.Services;
|
using IdentityServer4.Services;
|
||||||
using IdentityServer4.Stores;
|
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Localization;
|
using Microsoft.AspNetCore.Localization;
|
||||||
@ -20,31 +19,28 @@ using Microsoft.Extensions.Logging;
|
|||||||
|
|
||||||
namespace Bit.Identity.Controllers
|
namespace Bit.Identity.Controllers
|
||||||
{
|
{
|
||||||
public class AccountController : Controller
|
// TODO: 2022-01-12, Remove account alias
|
||||||
|
[Route("account/[action]")]
|
||||||
|
[Route("sso/[action]")]
|
||||||
|
public class SsoController : Controller
|
||||||
{
|
{
|
||||||
private readonly IClientStore _clientStore;
|
|
||||||
private readonly IIdentityServerInteractionService _interaction;
|
private readonly IIdentityServerInteractionService _interaction;
|
||||||
private readonly ILogger<AccountController> _logger;
|
private readonly ILogger<SsoController> _logger;
|
||||||
private readonly ISsoConfigRepository _ssoConfigRepository;
|
private readonly ISsoConfigRepository _ssoConfigRepository;
|
||||||
private readonly IUserRepository _userRepository;
|
private readonly IUserRepository _userRepository;
|
||||||
private readonly IOrganizationRepository _organizationRepository;
|
|
||||||
private readonly IHttpClientFactory _clientFactory;
|
private readonly IHttpClientFactory _clientFactory;
|
||||||
|
|
||||||
public AccountController(
|
public SsoController(
|
||||||
IClientStore clientStore,
|
|
||||||
IIdentityServerInteractionService interaction,
|
IIdentityServerInteractionService interaction,
|
||||||
ILogger<AccountController> logger,
|
ILogger<SsoController> logger,
|
||||||
ISsoConfigRepository ssoConfigRepository,
|
ISsoConfigRepository ssoConfigRepository,
|
||||||
IUserRepository userRepository,
|
IUserRepository userRepository,
|
||||||
IOrganizationRepository organizationRepository,
|
|
||||||
IHttpClientFactory clientFactory)
|
IHttpClientFactory clientFactory)
|
||||||
{
|
{
|
||||||
_clientStore = clientStore;
|
|
||||||
_interaction = interaction;
|
_interaction = interaction;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_ssoConfigRepository = ssoConfigRepository;
|
_ssoConfigRepository = ssoConfigRepository;
|
||||||
_userRepository = userRepository;
|
_userRepository = userRepository;
|
||||||
_organizationRepository = organizationRepository;
|
|
||||||
_clientFactory = clientFactory;
|
_clientFactory = clientFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,7 +268,7 @@ namespace Bit.Identity.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsNativeClient(IdentityServer4.Models.AuthorizationRequest context)
|
private bool IsNativeClient(IdentityServer4.Models.AuthorizationRequest context)
|
||||||
{
|
{
|
||||||
return !context.RedirectUri.StartsWith("https", StringComparison.Ordinal)
|
return !context.RedirectUri.StartsWith("https", StringComparison.Ordinal)
|
||||||
&& !context.RedirectUri.StartsWith("http", StringComparison.Ordinal);
|
&& !context.RedirectUri.StartsWith("http", StringComparison.Ordinal);
|
@ -3,10 +3,10 @@ using System.Security.Claims;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Api.Controllers;
|
using Bit.Api.Controllers;
|
||||||
using Bit.Api.Models.Request.Accounts;
|
using Bit.Api.Models.Request.Accounts;
|
||||||
using Bit.Core;
|
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Exceptions;
|
using Bit.Core.Exceptions;
|
||||||
|
using Bit.Core.Models.Api.Request.Accounts;
|
||||||
using Bit.Core.Models.Data;
|
using Bit.Core.Models.Data;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Services;
|
using Bit.Core.Services;
|
||||||
@ -27,7 +27,6 @@ namespace Bit.Api.Test.Controllers
|
|||||||
private readonly IOrganizationService _organizationService;
|
private readonly IOrganizationService _organizationService;
|
||||||
private readonly IOrganizationUserRepository _organizationUserRepository;
|
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||||
private readonly IPaymentService _paymentService;
|
private readonly IPaymentService _paymentService;
|
||||||
private readonly ISsoUserRepository _ssoUserRepository;
|
|
||||||
private readonly IUserRepository _userRepository;
|
private readonly IUserRepository _userRepository;
|
||||||
private readonly IUserService _userService;
|
private readonly IUserService _userService;
|
||||||
private readonly ISendRepository _sendRepository;
|
private readonly ISendRepository _sendRepository;
|
||||||
|
115
test/Identity.Test/Controllers/AccountsControllerTests.cs
Normal file
115
test/Identity.Test/Controllers/AccountsControllerTests.cs
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Bit.Core.Entities;
|
||||||
|
using Bit.Core.Enums;
|
||||||
|
using Bit.Core.Exceptions;
|
||||||
|
using Bit.Core.Models.Api.Request.Accounts;
|
||||||
|
using Bit.Core.Models.Data;
|
||||||
|
using Bit.Core.Repositories;
|
||||||
|
using Bit.Core.Services;
|
||||||
|
using Bit.Identity.Controllers;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using NSubstitute;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Bit.Identity.Test.Controllers
|
||||||
|
{
|
||||||
|
public class AccountsControllerTests : IDisposable
|
||||||
|
{
|
||||||
|
|
||||||
|
private readonly AccountsController _sut;
|
||||||
|
private readonly ILogger<AccountsController> _logger;
|
||||||
|
private readonly IUserRepository _userRepository;
|
||||||
|
private readonly IUserService _userService;
|
||||||
|
|
||||||
|
public AccountsControllerTests()
|
||||||
|
{
|
||||||
|
_logger = Substitute.For<ILogger<AccountsController>>();
|
||||||
|
_userRepository = Substitute.For<IUserRepository>();
|
||||||
|
_userService = Substitute.For<IUserService>();
|
||||||
|
_sut = new AccountsController(
|
||||||
|
_logger,
|
||||||
|
_userRepository,
|
||||||
|
_userService
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_sut?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task PostPrelogin_WhenUserExists_ShouldReturnUserKdfInfo()
|
||||||
|
{
|
||||||
|
var userKdfInfo = new UserKdfInformation
|
||||||
|
{
|
||||||
|
Kdf = KdfType.PBKDF2_SHA256,
|
||||||
|
KdfIterations = 5000
|
||||||
|
};
|
||||||
|
_userRepository.GetKdfInformationByEmailAsync(Arg.Any<string>()).Returns(Task.FromResult(userKdfInfo));
|
||||||
|
|
||||||
|
var response = await _sut.PostPrelogin(new PreloginRequestModel { Email = "user@example.com" });
|
||||||
|
|
||||||
|
Assert.Equal(userKdfInfo.Kdf, response.Kdf);
|
||||||
|
Assert.Equal(userKdfInfo.KdfIterations, response.KdfIterations);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task PostPrelogin_WhenUserDoesNotExist_ShouldDefaultToSha256And100000Iterations()
|
||||||
|
{
|
||||||
|
_userRepository.GetKdfInformationByEmailAsync(Arg.Any<string>()).Returns(Task.FromResult((UserKdfInformation)null));
|
||||||
|
|
||||||
|
var response = await _sut.PostPrelogin(new PreloginRequestModel { Email = "user@example.com" });
|
||||||
|
|
||||||
|
Assert.Equal(KdfType.PBKDF2_SHA256, response.Kdf);
|
||||||
|
Assert.Equal(100000, response.KdfIterations);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task PostRegister_ShouldRegisterUser()
|
||||||
|
{
|
||||||
|
var passwordHash = "abcdef";
|
||||||
|
var token = "123456";
|
||||||
|
var userGuid = new Guid();
|
||||||
|
_userService.RegisterUserAsync(Arg.Any<User>(), passwordHash, token, userGuid)
|
||||||
|
.Returns(Task.FromResult(IdentityResult.Success));
|
||||||
|
var request = new RegisterRequestModel
|
||||||
|
{
|
||||||
|
Name = "Example User",
|
||||||
|
Email = "user@example.com",
|
||||||
|
MasterPasswordHash = passwordHash,
|
||||||
|
MasterPasswordHint = "example",
|
||||||
|
Token = token,
|
||||||
|
OrganizationUserId = userGuid
|
||||||
|
};
|
||||||
|
|
||||||
|
await _sut.PostRegister(request);
|
||||||
|
|
||||||
|
await _userService.Received(1).RegisterUserAsync(Arg.Any<User>(), passwordHash, token, userGuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task PostRegister_WhenUserServiceFails_ShouldThrowBadRequestException()
|
||||||
|
{
|
||||||
|
var passwordHash = "abcdef";
|
||||||
|
var token = "123456";
|
||||||
|
var userGuid = new Guid();
|
||||||
|
_userService.RegisterUserAsync(Arg.Any<User>(), passwordHash, token, userGuid)
|
||||||
|
.Returns(Task.FromResult(IdentityResult.Failed()));
|
||||||
|
var request = new RegisterRequestModel
|
||||||
|
{
|
||||||
|
Name = "Example User",
|
||||||
|
Email = "user@example.com",
|
||||||
|
MasterPasswordHash = passwordHash,
|
||||||
|
MasterPasswordHint = "example",
|
||||||
|
Token = token,
|
||||||
|
OrganizationUserId = userGuid
|
||||||
|
};
|
||||||
|
|
||||||
|
await Assert.ThrowsAsync<BadRequestException>(() => _sut.PostRegister(request));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
29
test/Identity.Test/Identity.Test.csproj
Normal file
29
test/Identity.Test/Identity.Test.csproj
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="coverlet.collector" Version="3.0.3">
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
|
||||||
|
<PackageReference Include="NSubstitute" Version="4.2.2" />
|
||||||
|
<PackageReference Include="xunit" Version="2.4.1" />
|
||||||
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.2">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="AutoFixture.Xunit2" Version="4.14.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\Core\Core.csproj" />
|
||||||
|
<ProjectReference Include="..\..\src\Identity\Identity.csproj" />
|
||||||
|
<ProjectReference Include="..\common\Common.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
Loading…
Reference in New Issue
Block a user