public async Task <ServiceProviderResponse> StartOtpAsync( [FromHeader(Constant.OperationTrackingIdHeader)] string requestId, [FromHeader] string account, [FromBody] OtpPushDescription description) { Validator.ArgumentNotNull(account, nameof(account)); Validator.ArgumentNotNull(description, nameof(description)); Validator.ArgumentNotNullOrEmpty(description.TemplateName, nameof(description.TemplateName)); Validator.ArgumentNotNullOrEmpty(description.PhoneNumber, nameof(description.PhoneNumber)); if (description.ExpireTime == null) { description.ExpireTime = DefaultExpireTime; } if (description.CodeLength == null) { description.CodeLength = DefaultCodeLength; } if (description.Channel == null) { description.Channel = DefaultChannel; } if (description.ExpireTime < 60 || description.ExpireTime > 3600) { throw new ArgumentException($"ExpireTime should be a value between 60 and 3600."); } if (description.CodeLength < 4 || description.CodeLength > 10) { throw new ArgumentException($"CodeLength should be a value between 4 and 10."); } var result = await this.engine.OtpPushAsync(account, description, this.otpRequest, requestId, CancellationToken.None); return(result); }
public async Task <ServiceProviderResponse> OtpPushAsync(string account, OtpPushDescription description, ServiceProviderRequest request, string requestId, CancellationToken cancellationToken) { var channel = OtpChannelHelper.Format(description.Channel); var smsProvider = ProviderManager.GetSmsServiceProvider(); // Check if templete type is 2 var smsGetRequest = new ServiceProviderRequest { HttpMethod = "GET", Path = "templates/" + description.TemplateName, Content = string.Empty, Headers = request.Headers, QueryNameValuePairs = request.QueryNameValuePairs, }; var subscriptionId = await RequestHelper.GetSubscriptionId(account); try { var result = await smsProvider.OnRequestAsync(smsGetRequest); var projson = JObject.Parse(result.Content); JToken tpltype; if (projson.TryGetValue("tplType", out tpltype) && ((int)tpltype != 2)) { throw new ArgumentException($"Invalid template type."); } // generate otpCode var code = GetOtpCode((int)description.CodeLength); // prepare messageSendRequest for sending request to sms provider MessageSendRequest messageSendRequest = new MessageSendRequest() { Targets = new List <string>() { description.PhoneNumber }, MessageBody = new MessageTemplateBody() { TemplateName = description.TemplateName, TemplateParameters = new PropertyCollection <string>() } }; messageSendRequest.MessageBody.TemplateParameters.Add("otpcode", code); var content = JsonConvert.SerializeObject(messageSendRequest); // create request for sms provider var smsRequest = new ServiceProviderRequest { HttpMethod = "POST", Path = "messages", Content = content, Headers = request.Headers, QueryNameValuePairs = request.QueryNameValuePairs }; // send push request to sms provider result = await smsProvider.OnRequestAsync(smsRequest); if (result.StatusCode != HttpStatusCode.OK) { return(result); } // Create otp record in db var otpcode = await this.otpStore.CreateorUpdateOtpCodeAsync(account, description.PhoneNumber, code, (int)description.ExpireTime); // Create otp check history in otp storage table await this.otpStorage.CreateOtpCodeHistoryRecord(account, description.PhoneNumber, ActionType.Start.ToString(), DateTime.UtcNow); this.metricManager.LogOtpSendSuccess(1, account, subscriptionId, description.Channel); OtpProviderEventSource.Current.Info(requestId, this, nameof(this.OtpPushAsync), OperationStates.Succeeded, $"account: {account}, channel: {channel}, phoneNumber: {description.PhoneNumber}"); return(new ServiceProviderResponse { StatusCode = HttpStatusCode.OK, JsonContent = new OtpStartOperationResult { ExpireTime = (int)description.ExpireTime } }); } catch (Exception ex) { this.metricManager.LogOtpSendFailed(1, account, subscriptionId, description.Channel); while (ex is AggregateException) { ex = ex.InnerException; } OtpProviderEventSource.Current.ErrorException(requestId, this, nameof(this.OtpPushAsync), OperationStates.Failed, $"Failed to send OTP code for account: {account}, channel: {channel}, phoneNumber: {description.PhoneNumber}", ex); if ((ex is ArgumentException) || (ex is QuotaExceededException)) { throw ex; } throw new Exception(string.Format($"Failed to send OTP code for account: {account}, channel: {channel}, phoneNumber: {description.PhoneNumber}")); } }