public async Task <UserStatusModel> AutoSignIn(UserAutoSignInModel model)
        {
            var provider = await _repositoryProvider.GetFirst(x => x.Slug == model.ProviderSlug && x.State == MREntityState.Active);

            if (provider == null)
            {
                _eNotFound("Provider not found");
            }

            return(new UserStatusModel
            {
                CallbackToken = ProviderTokenGenerator.Generate(provider.Id, _userId),
                CallbackUrl = string.IsNullOrWhiteSpace(model.RedirectUrl) ? provider.Options.CallbackUrl : model.RedirectUrl
            });
        }
        public async Task <UserPorviderProofResponseModel> LoginProof(string providerToken, string userToken)
        {
            var provider = await _repositoryProvider.GetByToken(providerToken);

            if (provider == null)
            {
                throw new MRException <object>(-1, "Wrong provider token");
            }

            (var providerId, var userId) = ProviderTokenGenerator.DecryptToken(userToken);

            if (!provider.Id.Equals(providerId))
            {
                throw new MRException <object>(-1, "Wrong provider token");
            }

            var user = await _repositoryUser.GetFirst(x => x.Id == userId && x.State == MREntityState.Active);

            if (user == null)
            {
                throw new MRException <object>(-1, "User not found");
            }

            var providerLogin = new ProviderClientLogin
            {
                ProviderToken = providerToken,
                ClientToken   = userToken,
                Time          = DateTime.UtcNow
            };

            if (provider.Clients == null)
            {
                provider.Clients = new List <ProviderClient>();
                await _repositoryProvider.Replace(provider);
            }

            var providerClient = provider.Clients.FirstOrDefault(x => x.UserId == user.Id);

            if (providerClient == null)
            {
                providerClient = new ProviderClient
                {
                    UserId = user.Id,
                    Email  = user.Email,
                    Roles  = provider.Options.DefaultRoles,
                    Logins = new List <ProviderClientLogin> {
                        providerLogin
                    }
                };

                provider.Clients.Add(providerClient);

                await _repositoryProvider.AddClient(provider.Id, providerClient);
            }
            else
            {
                await _repositoryProvider.AddClientLogin(provider.Id, providerClient.UserId, providerLogin);
            }

            var model = _mapper.Map <UserPorviderProofResponseModel>(user);

            model.Roles            = providerClient.Roles;
            model.IsEmailConfirmed = await _managerUser.IsEmailConfirmedAsync(user);

            model.IsEmailOnChange = await _repositoryEmailChangeUnit.Any(x => x.UserId == user.Id && x.Status == Infrastructure.Entity.Enum.EmailChangeResult.NEW);

            return(model);
        }
        public async Task <UserStatusModel> SignUp(UserSignupModel model)
        {
            var exists = await _managerUser.FindByEmailAsync(model.Email);

            if (exists != null)
            {
                throw new MRException <UserStatusModel>((int)ExceptionCode.SYSTEM_EXCEPTION, "User with this email already exists");
            }

            var user       = _mapper.Map <User>(model);
            var saveResult = await _managerUser.CreateAsync(user);

            if (!saveResult.Succeeded)
            {
                throw new MRException <UserStatusModel>((int)ExceptionCode.SYSTEM_EXCEPTION, "Can not create user");
            }

            await _managerUser.AddPasswordAsync(user, model.Password);

            await _managerUser.AddToRoleAsync(user, AppRoles.USER.ToString());

            string providerToken = null;

            if (!string.IsNullOrWhiteSpace(model.ProviderSlug))
            {
                var provider = await _repositoryProvider.GetFirst(x => x.Slug == model.ProviderSlug && x.State == MREntityState.Active);

                if (provider != null)
                {
                    if (!provider.Options.IsRegistrationAvaliable)
                    {
                        throw new MRException <object>(-1, "Provider registration disabled");
                    }

                    providerToken = ProviderTokenGenerator.Generate(provider.Id, user.Id);
                }
            }

            var token = _serviceToken.GenerateToken(user.Id, user.Email, new List <string> {
                AppRoles.USER.ToString()
            });

            var response = new UserStatusModel
            {
                FirstName   = user.FirstName,
                LastName    = user.LastName,
                Email       = user.Email,
                AccessToken = token,
                Roles       = new List <string> {
                    AppRoles.USER.ToString()
                },
                LanguageCode     = user.LanguageCode,
                Sex              = user.Sex,
                CallbackUrl      = model.CallbackUrl,
                CallbackToken    = providerToken,
                IsEmailConfirmed = false,
                IsEmailOnChange  = false
            };

            return(response);
        }
        public async Task <UserStatusModel> SignIn(UserSignInModel model)
        {
            var user = await _managerUser.FindByEmailAsync(model.Email);

            if (user == null || !await _managerUser.CheckPasswordAsync(user, model.Password))
            {
                _eNotFound <UserStatusModel>("User not found");
            }

            var userRoles = await _managerUser.GetRolesAsync(user);

            var token = _serviceToken.GenerateToken(user.Id, user.Email, userRoles);

            UserLoginInfo li            = null;
            string        callbackToken = null;

            if (!string.IsNullOrWhiteSpace(model.ProviderSlug))
            {
                var provider = await _repositoryProvider.GetFirst(x => x.Slug == model.ProviderSlug && x.State == MREntityState.Active);

                if (provider != null && provider.Options.IsEnabled)
                {
                    li = new UserLoginInfo(provider.Id, token, provider.Slug);

                    _serviceToken.GenerateToken("SOME_SECRET_KEY", "MR_IDENTITY", "SOME_PROVIDER", 60, new List <Tuple <string, string> >
                    {
                        new Tuple <string, string>("provider.id", provider.Id),
                        new Tuple <string, string>("user.id", user.Id)
                    }, "name", "password");

                    callbackToken = ProviderTokenGenerator.Generate(provider.Id, user.Id);
                }
            }

            if (li == null)
            {
                li = new UserLoginInfo(_tokenOptions.Issuer, token, _tokenOptions.Issuer);
            }

            if (await _managerUser.FindByLoginAsync(li.LoginProvider, li.ProviderKey) != null)
            {
                await _managerUser.RemoveLoginAsync(user, li.LoginProvider, li.ProviderKey);
            }

            await _managerUser.AddLoginAsync(user, li);

            var isEmailOnChange = await _repositoryEmailChangeUnit.Any(x => x.State == MREntityState.Active && x.UserId == user.Id && x.Status == Infrastructure.Entity.Enum.EmailChangeResult.NEW);

            _logger.LogInformation($"User login");

            return(new UserStatusModel
            {
                FirstName = user.FirstName,
                LastName = user.LastName,
                Roles = userRoles.ToList(),
                AccessToken = token,
                LanguageCode = user.LanguageCode,
                Email = user.Email,
                Sex = user.Sex,
                IsEmailConfirmed = user.IsEmailConfirmed,
                IsEmailOnChange = isEmailOnChange,
                CallbackUrl = model.CallbackUrl,
                CallbackToken = callbackToken
            });
        }