Ejemplo n.º 1
0
        public async Task <RegistrationResultModel> RegisterAsync(RegistrationRequestDto model)
        {
            var adminId = Guid.NewGuid().ToString();

            model.Email = model.Email.ToLower();

            CredentialsCreateResponse adminCredentialsCreationResult;

            try
            {
                adminCredentialsCreationResult = await _credentialsClient.Admins.CreateAsync(
                    new AdminCredentialsCreateRequest { Login = model.Email, AdminId = adminId, Password = model.Password });
            }
            catch (ClientApiException exception) when(exception.HttpStatusCode == HttpStatusCode.BadRequest)
            {
                return(new RegistrationResultModel {
                    Error = ServicesError.InvalidEmailOrPasswordFormat
                });
            }

            if (adminCredentialsCreationResult.Error == CredentialsError.LoginAlreadyExists)
            {
                return new RegistrationResultModel {
                           Error = ServicesError.AlreadyRegistered
                }
            }
            ;

            var emailHash = GetHash(model.Email);

            if (adminCredentialsCreationResult.Error != CredentialsError.None)
            {
                const string errorMessage = "An error occurred while creating admin credentials.";

                _log.Error(errorMessage, context:
                           $"adminUserId: {adminId}; email: {emailHash}; error: {adminCredentialsCreationResult.Error}");

                throw new InvalidOperationException(errorMessage);
            }

            var registrationDateTime = DateTime.UtcNow;

            var result = await _adminUsersRepository.TryCreateAsync(
                new AdminUserEncrypted
            {
                AdminUserId           = adminId,
                EmailHash             = emailHash,
                RegisteredAt          = registrationDateTime,
                IsActive              = true,
                UseDefaultPermissions = false
            });

            if (result)
            {
                _log.Info("Admin user created for an account.", context: $"adminUserId: {adminId}; email: {emailHash}");
            }
            else
            {
                _log.Warning("Trying to create a duplicate admin user.", context: $"email: {emailHash}");

                return(new RegistrationResultModel {
                    Error = ServicesError.AlreadyRegistered
                });
            }

            var adminProfileCreationResult = await _customerProfileClient.AdminProfiles.AddAsync(
                _mapper.Map <RegistrationRequestDto, AdminProfileRequest>(model,
                                                                          opt => opt.AfterMap((src, dest) => { dest.AdminId = Guid.Parse(adminId); }))
                );

            await _permissionsService.CreateOrUpdatePermissionsAsync(adminId, model.Permissions);

            await _permissionsCache.SetAsync(adminId, model.Permissions.ToList());

            if (adminProfileCreationResult.ErrorCode != AdminProfileErrorCodes.None)
            {
                _log.Error(message: "An error occurred while creating admin profile.",
                           context: $"adminUserId: {adminId}; error: {adminProfileCreationResult.ErrorCode}");
            }

            #region email verification code

            var emailVerificationCode = Guid.NewGuid().ToString();

            var emailVerificationCodeEntity = await _emailVerificationCodeRepository.CreateOrUpdateAsync(
                adminId,
                emailVerificationCode);

            #endregion

            await _notificationsService.NotifyAdminCreatedAsync(new AdminCreatedEmailDto
            {
                AdminUserId           = adminId,
                Email                 = model.Email,
                EmailVerificationCode = emailVerificationCode.ToBase64(),
                Password              = model.Password,
                Name         = $"{model.FirstName} {model.LastName}",
                Localization = model.Localization
            });

            _log.Info(message: "Successfully generated AdminCreatedEmail", context: adminId);

            var adminUser = _mapper.Map <AdminUser>(adminProfileCreationResult.Data);
            adminUser.AdminUserId           = adminId;
            adminUser.Permissions           = model.Permissions.ToList();
            adminUser.RegisteredAt          = registrationDateTime;
            adminUser.UseDefaultPermissions = false;
            adminUser.IsActive = true;

            return(new RegistrationResultModel {
                Admin = adminUser
            });
        }
Ejemplo n.º 2
0
        /// <inheritdoc />
        public async Task <VerificationCodeResult> RequestVerificationAsync(string customerId)
        {
            if (string.IsNullOrEmpty(customerId))
            {
                throw new ArgumentNullException(nameof(customerId));
            }

            if (!await _callRateLimiterService.IsAllowedToCallEmailVerificationAsync(customerId))
            {
                _log.Info($"Customer with Id: {customerId} made too many email verification request and was blocked");
                return(VerificationCodeResult.Failed(VerificationCodeError.ReachedMaximumRequestForPeriod));
            }

            await _callRateLimiterService.RecordEmailVerificationCallAsync(customerId);

            var customer =
                await _customerProfileClient.CustomerProfiles.GetByCustomerIdAsync(customerId,
                                                                                   includeNotVerified : true);

            if (customer?.Profile == null)
            {
                return(VerificationCodeResult.Failed(VerificationCodeError.CustomerDoesNotExist));
            }

            if (customer.Profile.IsEmailVerified)
            {
                return(VerificationCodeResult.Failed(VerificationCodeError.AlreadyVerified));
            }

            var existingCode = await _emailVerificationCodeRepository.GetByCustomerAsync(customerId);

            if (existingCode?.IsVerified ?? false)
            {
                return(VerificationCodeResult.Failed(VerificationCodeError.AlreadyVerified));
            }

            var verificationCodeValue = Guid.NewGuid().ToString("D");

            var verificationCodeEntity = await _emailVerificationCodeRepository.CreateOrUpdateAsync(
                customerId,
                verificationCodeValue);

            await _emailEventPublisher.PublishAsync(new EmailMessageEvent
            {
                CustomerId         = customerId,
                MessageTemplateId  = _verificationEmailTemplateId,
                SubjectTemplateId  = _verificationEmailSubjectTemplateId,
                TemplateParameters = new Dictionary <string, string>
                {
                    {
                        "EmailVerificationLink",
                        string.Format(
                            _verificationEmailVerificationLink,
                            verificationCodeEntity.VerificationCode.ToBase64())
                    }
                },
                Source = $"{AppEnvironment.Name} - {AppEnvironment.Version}"
            });

            _log.Info(message: "Successfully generated Verification Email for customer", context: customerId);

            return(VerificationCodeResult.Succeeded(verificationCodeEntity.ExpireDate));
        }