Add user
This commit is contained in:
parent
f406854dae
commit
fe9edd891b
@ -1,4 +1,4 @@
|
||||
namespace Nocr.Users.Api.Contracts.Users;
|
||||
namespace Nocr.Users.Api.Contracts.Users.Dto;
|
||||
|
||||
public sealed class CreateUserRequest
|
||||
{
|
||||
@ -7,4 +7,6 @@ public sealed class CreateUserRequest
|
||||
public string? Email { get; set; }
|
||||
|
||||
public long? TelegramId { get; set; }
|
||||
|
||||
public string? TelegramUsername { get; set; }
|
||||
}
|
||||
@ -1,3 +1,4 @@
|
||||
using Nocr.Users.Api.Contracts.Users.Dto;
|
||||
using RestEase;
|
||||
|
||||
namespace Nocr.Users.Api.Contracts.Users;
|
||||
@ -7,4 +8,7 @@ public interface IUsersController
|
||||
{
|
||||
[Post]
|
||||
Task<long> Create([Body] CreateUserRequest request, CancellationToken cancellationToken = default);
|
||||
|
||||
[Get(WebRoutes.Users.ById)]
|
||||
Task<UserData?> GetById([Path] long id, CancellationToken cancellationToken = default);
|
||||
}
|
||||
8
src/Nocr.Users.Api.Contracts/Users/UserData.cs
Normal file
8
src/Nocr.Users.Api.Contracts/Users/UserData.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Nocr.Users.Api.Contracts.Users;
|
||||
|
||||
public sealed class UserData
|
||||
{
|
||||
public long Id { get; set; }
|
||||
|
||||
public string Username { get; set; }
|
||||
}
|
||||
@ -7,5 +7,7 @@ public static class WebRoutes
|
||||
public static class Users
|
||||
{
|
||||
public const string Path = BasePath + "/" + "users";
|
||||
|
||||
public const string ById = "{id}";
|
||||
}
|
||||
}
|
||||
@ -9,6 +9,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Nocr.Users.Api.Contracts\Nocr.Users.Api.Contracts.csproj" />
|
||||
<ProjectReference Include="..\Nocr.Users.Core\Nocr.Users.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Nocr.Users.AppServices.Users;
|
||||
|
||||
namespace Nocr.Users.AppServices;
|
||||
|
||||
@ -10,7 +11,9 @@ public static class ServiceCollectionExtensions
|
||||
throw new ArgumentNullException(nameof(services));
|
||||
|
||||
// Add registrations here
|
||||
|
||||
services.AddScoped<IUsersRepository, InMemoryUsersRepository>();
|
||||
services.AddScoped<IUsersService, UsersService>();
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
8
src/Nocr.Users.AppServices/Users/IUsersRepository.cs
Normal file
8
src/Nocr.Users.AppServices/Users/IUsersRepository.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Nocr.Users.AppServices.Users;
|
||||
|
||||
public interface IUsersRepository
|
||||
{
|
||||
Task<long> Create(User user, CancellationToken cancellationToken = default);
|
||||
|
||||
Task<User?> GetUserById(long id, CancellationToken cancellationToken = default);
|
||||
}
|
||||
11
src/Nocr.Users.AppServices/Users/IUsersService.cs
Normal file
11
src/Nocr.Users.AppServices/Users/IUsersService.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using Nocr.Users.Api.Contracts.Users;
|
||||
|
||||
namespace Nocr.Users.AppServices.Users;
|
||||
|
||||
public interface IUsersService
|
||||
{
|
||||
Task<long> Create(string username, string? telegramUsername, string? email, long? telegramId,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
Task<UserData?> GetUserById(long id, CancellationToken cancellationToken = default);
|
||||
}
|
||||
29
src/Nocr.Users.AppServices/Users/InMemoryUsersRepository.cs
Normal file
29
src/Nocr.Users.AppServices/Users/InMemoryUsersRepository.cs
Normal file
@ -0,0 +1,29 @@
|
||||
namespace Nocr.Users.AppServices.Users;
|
||||
|
||||
public sealed class InMemoryUsersRepository : IUsersRepository
|
||||
{
|
||||
private long _id = 0;
|
||||
|
||||
private long _userIdentityId = 0;
|
||||
|
||||
private readonly List<User> _users = new();
|
||||
|
||||
public Task<long> Create(User user, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var id = Interlocked.Increment(ref _id);
|
||||
user.Id = id;
|
||||
_users.Add(user);
|
||||
|
||||
foreach (var identity in user.Identities)
|
||||
{
|
||||
identity.Id = Interlocked.Increment(ref _userIdentityId);
|
||||
}
|
||||
|
||||
return Task.FromResult(id);
|
||||
}
|
||||
|
||||
public Task<User?> GetUserById(long id, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(_users.FirstOrDefault(x => x.Id == id));
|
||||
}
|
||||
}
|
||||
@ -6,18 +6,30 @@ public sealed class User
|
||||
|
||||
public string Username { get; private set; }
|
||||
|
||||
private User(string username)
|
||||
private List<UserIdentity> _identities = new List<UserIdentity>();
|
||||
|
||||
public IReadOnlyCollection<UserIdentity> Identities => _identities;
|
||||
|
||||
private User(string username, params UserIdentity[] identities)
|
||||
{
|
||||
Username = username;
|
||||
|
||||
// TODO: Check that there is no repeating identity types
|
||||
_identities.AddRange(identities);
|
||||
}
|
||||
|
||||
public static User Initialize(string username)
|
||||
public static User Initialize(string username, params UserIdentity[] identities)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(username))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(username));
|
||||
}
|
||||
|
||||
return new User(username);
|
||||
|
||||
if (username.Length is < 5 or > 32)
|
||||
{
|
||||
throw new ArgumentException("Username length should be between 5 and 32 symbols", username);
|
||||
}
|
||||
|
||||
return new User(username, identities);
|
||||
}
|
||||
}
|
||||
34
src/Nocr.Users.AppServices/Users/UserIdentity.cs
Normal file
34
src/Nocr.Users.AppServices/Users/UserIdentity.cs
Normal file
@ -0,0 +1,34 @@
|
||||
namespace Nocr.Users.AppServices.Users;
|
||||
|
||||
public sealed class UserIdentity
|
||||
{
|
||||
public long Id { get; set; }
|
||||
|
||||
public string Identity { get; private set; }
|
||||
|
||||
public UserIdentityType IdentityType { get; private set; }
|
||||
|
||||
private UserIdentity(string identity, UserIdentityType identityType)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(identity))
|
||||
throw new ArgumentNullException(nameof(identity));
|
||||
|
||||
Identity = identity;
|
||||
IdentityType = identityType;
|
||||
}
|
||||
|
||||
public static UserIdentity TelegramId(string identity)
|
||||
{
|
||||
return new UserIdentity(identity, UserIdentityType.TelegramId);
|
||||
}
|
||||
|
||||
public static UserIdentity TelegramUsername(string identity)
|
||||
{
|
||||
return new UserIdentity(identity, UserIdentityType.TelegramUsername);
|
||||
}
|
||||
|
||||
public static UserIdentity Email(string identity)
|
||||
{
|
||||
return new UserIdentity(identity, UserIdentityType.TelegramUsername);
|
||||
}
|
||||
}
|
||||
8
src/Nocr.Users.AppServices/Users/UserIdentityType.cs
Normal file
8
src/Nocr.Users.AppServices/Users/UserIdentityType.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Nocr.Users.AppServices.Users;
|
||||
|
||||
public enum UserIdentityType
|
||||
{
|
||||
Email = 1,
|
||||
TelegramId = 2,
|
||||
TelegramUsername = 3,
|
||||
}
|
||||
46
src/Nocr.Users.AppServices/Users/UsersService.cs
Normal file
46
src/Nocr.Users.AppServices/Users/UsersService.cs
Normal file
@ -0,0 +1,46 @@
|
||||
using Nocr.Users.Api.Contracts.Users;
|
||||
|
||||
namespace Nocr.Users.AppServices.Users;
|
||||
|
||||
public sealed class UsersService : IUsersService
|
||||
{
|
||||
private readonly IUsersRepository _repository;
|
||||
|
||||
public UsersService(IUsersRepository repository)
|
||||
{
|
||||
_repository = repository ?? throw new ArgumentNullException(nameof(repository));
|
||||
}
|
||||
|
||||
public async Task<long> Create(string username, string? telegramUsername, string? email, long? telegramId,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var identities = new List<UserIdentity>();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(email))
|
||||
identities.Add(UserIdentity.Email(email));
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(telegramUsername))
|
||||
identities.Add(UserIdentity.TelegramUsername(telegramUsername));
|
||||
|
||||
if (telegramId.HasValue)
|
||||
identities.Add(UserIdentity.TelegramId(telegramId.Value.ToString()));
|
||||
|
||||
// TODO: ToArray = грубо
|
||||
var user = User.Initialize(username, identities.ToArray());
|
||||
|
||||
return await _repository.Create(user, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<UserData?> GetUserById(long id, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var user = await _repository.GetUserById(id, cancellationToken);
|
||||
if (user == null)
|
||||
return null;
|
||||
|
||||
return new UserData
|
||||
{
|
||||
Id = user.Id,
|
||||
Username = user.Username,
|
||||
};
|
||||
}
|
||||
}
|
||||
30
src/Nocr.Users.Host/Controllers/UsersController.cs
Normal file
30
src/Nocr.Users.Host/Controllers/UsersController.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Nocr.Users.Api.Contracts;
|
||||
using Nocr.Users.Api.Contracts.Users;
|
||||
using Nocr.Users.Api.Contracts.Users.Dto;
|
||||
using Nocr.Users.AppServices.Users;
|
||||
|
||||
namespace Nocr.Users.Host;
|
||||
|
||||
[ApiController]
|
||||
[Route(WebRoutes.Users.Path)]
|
||||
public class UsersController : ControllerBase
|
||||
{
|
||||
private readonly IUsersService _usersService;
|
||||
|
||||
public UsersController(IUsersService usersService)
|
||||
{
|
||||
_usersService = usersService ?? throw new ArgumentNullException(nameof(usersService));
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public Task<long> Create([FromBody] CreateUserRequest request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return _usersService.Create(request.Username, request.TelegramUsername, request.Email, request.TelegramId, cancellationToken);
|
||||
}
|
||||
[HttpGet("{id}")]
|
||||
public Task<UserData?> GetById([FromRoute] long id, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return _usersService.GetUserById(id, cancellationToken);
|
||||
}
|
||||
}
|
||||
@ -12,7 +12,8 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Nocr.Users.AppServices\Nocr.Users.AppServices.csproj"/>
|
||||
<ProjectReference Include="..\Nocr.Users.Api.Contracts\Nocr.Users.Api.Contracts.csproj" />
|
||||
<ProjectReference Include="..\Nocr.Users.AppServices\Nocr.Users.AppServices.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user