Beispiel #1
0
        public async Task <IActionResult> UpdatePhoneNumber([FromBody] UpdateUserPhoneNumberRequest request)
        {
            var user = await _userManager.GetUserAsync(User);

            if (user == null)
            {
                return(NotFound());
            }
            var currentPhoneNumber = user.PhoneNumber ?? string.Empty;

            if (currentPhoneNumber.Equals(request.PhoneNumber, StringComparison.OrdinalIgnoreCase) && await _userManager.IsPhoneNumberConfirmedAsync(user))
            {
                ModelState.AddModelError(nameof(request.PhoneNumber).ToLower(), _userManager.MessageDescriber.UserAlreadyHasPhoneNumber(request.PhoneNumber));
                return(BadRequest(new ValidationProblemDetails(ModelState)));
            }
            var result = await _userManager.SetPhoneNumberAsync(user, request.PhoneNumber);

            if (!result.Succeeded)
            {
                return(BadRequest(result.Errors.ToValidationProblemDetails()));
            }
            if (!_identityServerApiEndpointsOptions.PhoneNumber.SendOtpOnUpdate)
            {
                return(NoContent());
            }
            var smsService = _smsServiceFactory.Create(request.DeliveryChannel);

            if (smsService == null)
            {
                throw new Exception($"No concrete implementation of {nameof(ISmsService)} is registered.");
            }
            var token = await _userManager.GenerateChangePhoneNumberTokenAsync(user, request.PhoneNumber);

            await smsService.SendAsync(request.PhoneNumber, string.Empty, _userManager.MessageDescriber.PhoneNumberVerificationMessage(token));

            return(NoContent());
        }
Beispiel #2
0
        /// <inheritdoc />
        public async Task <TotpResult> Send(ClaimsPrincipal principal, string message, TotpDeliveryChannel channel = TotpDeliveryChannel.Sms, string purpose = null, string securityToken = null, string phoneNumberOrEmail = null)
        {
            var totpResult = ValidateParameters(principal, securityToken, phoneNumberOrEmail);

            if (!totpResult.Success)
            {
                return(totpResult);
            }
            User user         = null;
            var  hasPrincipal = principal != null;

            if (hasPrincipal)
            {
                user = await _userManager.GetUserAsync(principal);

                if (user?.PhoneNumberConfirmed == false || string.IsNullOrEmpty(user?.PhoneNumber))
                {
                    return(TotpResult.ErrorResult(_localizer["Cannot send SMS. User's phone number is not verified."]));
                }
            }
            purpose ??= TotpConstants.TokenGenerationPurpose.StrongCustomerAuthentication;
            var token            = string.Empty;
            var hasSecurityToken = !string.IsNullOrEmpty(securityToken);

            if (hasSecurityToken)
            {
                var modifier     = GetModifier(purpose, phoneNumberOrEmail);
                var encodedToken = Encoding.Unicode.GetBytes(securityToken);
                token = _rfc6238AuthenticationService.GenerateCode(encodedToken, modifier).ToString("D6", CultureInfo.InvariantCulture);
            }
            if (hasPrincipal)
            {
                token = await _userManager.GenerateUserTokenAsync(user, TokenOptions.DefaultPhoneProvider, purpose);
            }
            var userName = user?.UserName ?? "Anonymous";
            var cacheKey = $"totp{(hasPrincipal ? $":{user.Id}" : string.Empty)}:{channel}:{token}:{purpose}";

            if (await CacheKeyExists(cacheKey))
            {
                _logger.LogInformation($"User: '******' - Last token has not expired yet. Throttling.");
                return(TotpResult.ErrorResult(_localizer["Last token has not expired yet. Please wait a few seconds and try again."]));
            }
            _logger.LogInformation($"User: '******' - Token generated successfully.");
            switch (channel)
            {
            case TotpDeliveryChannel.Sms:
            case TotpDeliveryChannel.Viber:
                var smsService = _smsServiceFactory.Create(channel.ToString());
                await smsService.SendAsync(user?.PhoneNumber ?? phoneNumberOrEmail, _localizer["OTP"], _localizer[message, token]);

                break;

            case TotpDeliveryChannel.Email:
            case TotpDeliveryChannel.Telephone:
            case TotpDeliveryChannel.EToken:
                throw new NotSupportedException($"EToken delivery channel {channel} is not implemented.");

            case TotpDeliveryChannel.PushNotification:
                if (_pushNotificationService == null)
                {
                    throw new ArgumentNullException(nameof(_pushNotificationService), $"Cannot send push notification since there is no implementation of {nameof(IPushNotificationService)}.");
                }
                await _pushNotificationService.SendAsync(_localizer[message, token], token, user.Id);

                break;

            default:
                break;
            }
            await AddCacheKey(cacheKey);

            return(TotpResult.SuccessResult);
        }