namespace MyOffice.Services.Users; using Domain; using Core; using Data.Models.Users; using Data.Repositories.Users; public class UserService { private readonly IUserRepository _userRepository; private readonly IUserExternalRepository _userExternalRepository; public UserService( IUserRepository userRepository, IUserExternalRepository userExternalRepository ) { _userRepository = userRepository; _userExternalRepository = userExternalRepository; } public async Task Get(Guid id) { return await _userRepository.GetUserAsync(id); } public async Task> GetUserExternals(Guid userId) { return await _userExternalRepository.GetUserExternalsByUserIdAsync(userId); } public async Task GetUserExternal(Guid userId, string provider) { return await _userExternalRepository.GetByUserIdAsync(userId, provider); } public async Task> RemoveUserExternal(Guid userId, string provider) { var result = new Exec(); var userExternal = await _userExternalRepository.GetByUserIdAsync(userId, provider); if (userExternal == null) return result.Set(GeneralExecStatus.not_found); _userExternalRepository.RemoveUserExternal(userExternal); return result.Set(userExternal); } private readonly object _lock = new(); public Exec AddUserExternal( Guid userId, string provider, string externalId, string email ) { var result = new Exec(AddUserExternalStatusEnum.success); var externalLogin = _userExternalRepository.GetByUserId(userId, provider); if (externalLogin != null) return result.Set(externalLogin); lock (_lock) { externalLogin = _userExternalRepository.GetByUserId(userId, provider); // externalLogin exists if (externalLogin != null) return result.Set(externalLogin); externalLogin = _userExternalRepository.GetByExternalId(externalId, provider); // externalId connected to another user if (externalLogin != null) return result.Set(AddUserExternalStatusEnum.externalid_used); var user = _userRepository.GetByUserUserName(email); // there are another user with that email if (user?.Id != userId) return result.Set(AddUserExternalStatusEnum.user_not_valid); externalLogin = new UserExternal { UserId = userId, CreatedOn = DateTime.UtcNow, Provider = provider.ToLower(), ExternalId = externalId, Email = email }; _userExternalRepository.AddUserExternal(externalLogin); } return result; } }