public HttpResponseMessage Send(SendConfirmationEmailRequest request) { Guid activityId = Guid.NewGuid(); var response = new ConfirmApiResponse { ActivityId = activityId }; this.ValidateSendInput(request, activityId, response); EntityType entityType; if (!this.TryConvertEntityType(request.ConfirmationType, out entityType)) { Log.Verbose(activityId, "Bad Request: unknown confirmation type: {0}", request.ConfirmationType); throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.BadRequest, response)); } try { Log.Info(activityId, "Start Processing link account request. uh={0}; confirmation type={1}", request.UserIdHash, entityType); var confirmationEntity = this.userDal.GetConfirmationEntity(request.UserIdHash, entityType); User user = null; if (confirmationEntity != null) { user = this.userDal.GetUserByUserId(confirmationEntity.UserId); } if (confirmationEntity == null || user == null) { response.Code = SendConfirmationResultCode.Invalid.ToString(); Log.Info(activityId, "confirmation entity or user not found to the given user hash and entity type. uh={0}; confirmation type={1}", request.UserIdHash, entityType); throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.BadRequest, response)); } this.ValidateResendJobsInTimeWindow(user.Id, entityType, activityId, response); ConfirmationEmailCargo job = null; if (entityType == EntityType.AccountLink) { job = this.CreateSendLinkAccountEmailJob(user, entityType, activityId, response); } else if (entityType == EntityType.UnAuthenticatedEmailAddress) { job = this.CreateSendConfirmEmailAddressEmailJob(user, confirmationEntity, entityType, activityId, response); } this.userDal.LogUserConfirmEmailResend(user.Id, entityType); this.confirmationJobsQueue.Enqueue(job); response.Code = SendConfirmationResultCode.EmailSent.ToString(); return(Request.CreateResponse(HttpStatusCode.Accepted, response)); } catch (HttpResponseException) { throw; } catch (Exception e) { Log.Error(activityId, e, "Unexpected error in send confirmation email call. user id hash: {0}; entity type: {1}", request.UserIdHash, entityType); response.Code = SendConfirmationResultCode.UnknownError.ToString(); return(Request.CreateResponse(HttpStatusCode.InternalServerError, response)); } }
public HttpResponseMessage SendToUsers(Guid?correlationId, SendEmailByUserIdRequest request) { // TODO - add application authentication string requestIdentifier = string.Format("Correletion Id={0}", correlationId); Log.Verbose("Start processing email send to users request. {0}", requestIdentifier); if (request == null || request.UserIds == null || request.UserIds.Count < 1 || request.Content == null || string.IsNullOrEmpty(request.Content.From)) { Log.Verbose("Email Send Request, Bad Request. {0}", requestIdentifier); HttpResponseMessage httpResponse = this.ControllerContext.Request.CreateResponse(HttpStatusCode.BadRequest); return(httpResponse); } try { var emails = new Dictionary <Guid, string>(); foreach (Guid userId in request.UserIds) { DataModel.User user = this.usersDal.GetUserByUserId(userId); if (user != null && !string.IsNullOrEmpty(user.Email) && !user.IsSuppressed) { emails.Add(userId, user.Email); } } if (emails.Count > 0) { this.emailClient.Send(this.ConvertRequest(request.Content, emails.Values.ToList(), request.IsTest), correlationId); IList <Guid> usersWithEmailAddress = emails.Keys.ToList(); HttpResponseMessage response = this.ControllerContext.Request.CreateResponse(HttpStatusCode.Accepted, usersWithEmailAddress); Log.Verbose("Email Send Request Completed Succefully. {0}", requestIdentifier); return(response); } HttpResponseMessage httpResponse = this.ControllerContext.Request.CreateResponse(HttpStatusCode.NotFound); return(httpResponse); } catch (Exception e) { Log.Error(e, "Couldn't send emails by users. Request Corelletion={0}", correlationId); HttpResponseMessage httpResponse = this.ControllerContext.Request.CreateResponse(HttpStatusCode.InternalServerError); return(httpResponse); } }
/// <summary> The create send link account email job. </summary> /// <param name="user"> The user. </param> /// <param name="entityType"> The entity type. </param> /// <param name="activityId"> The activity id. </param> /// <param name="response"> The response. </param> /// <returns> The <see cref="ConfirmationEmailCargo"/>. </returns> /// <exception cref="HttpResponseException">the account is already linked </exception> private ConfirmationEmailCargo CreateSendLinkAccountEmailJob(User user, EntityType entityType, Guid activityId, ConfirmApiResponse response) { if (!string.IsNullOrEmpty(user.MsId)) { response.Code = SendConfirmationResultCode.AlreadyLinked.ToString(); Log.Info(activityId, "Account is already linked to ms-id/ fb-id, won't resend confirm email. user id={0}; ", user.Id); throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.BadRequest, response)); } Tuple <string, int> confirmationCode = this.userDal.CreateConfirmationCode(user.Id.ToString(), entityType, user.Id); return(new ConfirmationEmailCargo { Id = Guid.NewGuid(), EntityType = EntityType.AccountLink, EmailAddress = user.Email, UserIdHash = confirmationCode.Item1, ConfirmationCode = confirmationCode.Item2, }); }
/// <summary> The create send confirm email address email job. </summary> /// <param name="user"> The user. </param> /// <param name="confirmEntity"> The confirm entity. </param> /// <param name="entityType"> The entity type. </param> /// <param name="activityId"> The activity id. </param> /// <param name="response"> The response. </param> /// <returns> The <see cref="ConfirmationEmailCargo"/>. the created job to queue</returns> /// <exception cref="HttpResponseException">the email address is already confirmed </exception> private ConfirmationEmailCargo CreateSendConfirmEmailAddressEmailJob(User user, ConfirmEntity confirmEntity, EntityType entityType, Guid activityId, ConfirmApiResponse response) { string emailToConfirm = confirmEntity.Name; if (user.Email == emailToConfirm && user.IsEmailConfirmed) { response.Code = SendConfirmationResultCode.AlreadyConfirmed.ToString(); Log.Info(activityId, "Email Address already confirmed, won't resend confirm email. user id={0}; ", user.Id); throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.BadRequest, response)); } Tuple <string, int> confirmationCode = this.userDal.CreateConfirmationCode(emailToConfirm, entityType, user.Id); return(new ConfirmationEmailCargo { Id = Guid.NewGuid(), EntityType = EntityType.UnAuthenticatedEmailAddress, EmailAddress = user.Email, UserIdHash = confirmationCode.Item1, ConfirmationCode = confirmationCode.Item2 }); }
/// <summary> /// Send email and sms /// </summary> /// <param name="userId"> /// User Id to send notification to /// </param> /// <param name="environment"> /// Environment for which notification needs to be sent /// </param> internal void Send(Guid userId, string environment) { try { Users.Dal.DataModel.User user = RetrieveUser(userId); //By default, enable both email and phone notification TransactionNotificationPreference transactionNotificationPreference = TransactionNotificationPreference.Email | TransactionNotificationPreference.Phone; if (user.Info != null && user.Info.Preferences != null) { transactionNotificationPreference = user.Info.Preferences.TransactionNotificationMedium; } if (transactionNotificationPreference == TransactionNotificationPreference.None) { Context.Log.Verbose("User has turned off both SMS & Email auth notification"); return; } INotificationContentCreator creator = NotificationContentCreatorFactory.NotificationContentCreator(Context); RedeemedDealInfo redeemedDealInfo = (RedeemedDealInfo)Context[Key.RedeemedDealInfo]; Context.Log.Verbose("Credit Amount : {0}", redeemedDealInfo.DiscountText); Context.Log.Verbose("DiscountSummary : {0}", redeemedDealInfo.DiscountSummary); Context.Log.Verbose("LastFourDigits : {0}", redeemedDealInfo.LastFourDigits); Context.Log.Verbose("MerchantName : {0}", redeemedDealInfo.MerchantName); Context.Log.Verbose("UserName : {0}", SalutationName); Context.Log.Verbose("ReimbursementTender : {0}", redeemedDealInfo.ReimbursementTenderId); AuthEmailNotificationData authEmailNotificationData = new AuthEmailNotificationData() { CreditAmount = redeemedDealInfo.DiscountText, DiscountSummary = redeemedDealInfo.DiscountSummary, LastFourDigits = redeemedDealInfo.LastFourDigits, MerchantName = redeemedDealInfo.MerchantName, UserName = SalutationName, UserId = userId.ToString(), DealId = redeemedDealInfo.ParentDealId.ToString(), DiscountId = redeemedDealInfo.GlobalId.ToString(), TransactionDate = redeemedDealInfo.TransactionDate.ToLongDateString(), TransactionId = redeemedDealInfo.TransactionId, PartnerId = redeemedDealInfo.PartnerId.ToString(CultureInfo.InvariantCulture), PartnerMerchantId = redeemedDealInfo.PartnerMerchantId, Percent = (float)Math.Round(redeemedDealInfo.Percent, 2) }; NotificationContent content; if ((transactionNotificationPreference & TransactionNotificationPreference.Email) == TransactionNotificationPreference.Email) { EnvironmentType environmentType; if (Enum.TryParse(environment, true, out environmentType)) { authEmailNotificationData.PopulateAuthStatusAndEmailLink(user, UsersDal, environmentType); } bool isEarn = true; if (redeemedDealInfo.ReimbursementTenderId == (int)ReimbursementTender.MicrosoftEarn) { content = creator.CreateAuthEmailContentAsync(authEmailNotificationData, authEmailSubjectEarn, authEmailTemplatePathEarn).Result; } else if (redeemedDealInfo.ReimbursementTenderId == (int)ReimbursementTender.MicrosoftBurn) { content = creator.CreateAuthEmailContentAsync(authEmailNotificationData, authEmailSubjectBurn, authEmailTemplatePathBurn).Result; } else { isEarn = false; content = creator.CreateAuthEmailContentAsync(authEmailNotificationData, authEmailSubjectClo).Result; } Context.Log.Verbose("About to send Email Auth notification"); SendEmailNotification(user.Email, content, isEarn); Context.Log.Verbose("Email notification sent"); } else { Context.Log.Verbose("User has turned off Email Auth notification"); } if ((transactionNotificationPreference & TransactionNotificationPreference.Phone) == TransactionNotificationPreference.Phone) { AuthSmsNotificationData authSmsNotificationData = new AuthSmsNotificationData() { DiscountSummary = redeemedDealInfo.DiscountSummary, MerchantName = redeemedDealInfo.MerchantName, Percent = (float)Math.Round(redeemedDealInfo.Percent, 2), CreditAmount = redeemedDealInfo.DiscountText }; if (redeemedDealInfo.ReimbursementTenderId == (int)ReimbursementTender.MicrosoftEarn) { content = creator.CreateAuthSmsContentAsync(authSmsNotificationData, authSmsTemplatePathEarn).Result; } else if (redeemedDealInfo.ReimbursementTenderId == (int)ReimbursementTender.MicrosoftBurn) { content = creator.CreateAuthSmsContentAsync(authSmsNotificationData, authSmsTemplatePathBurn).Result; } else { content = creator.CreateAuthSmsContentAsync(authSmsNotificationData).Result; } Context.Log.Verbose("About to send SMS Auth notification"); SendSmsNotification(userId, content.TextBody); Context.Log.Verbose("SMS Notification sent"); } else { Context.Log.Verbose("User has turned off SMS Auth notification"); } } catch (Exception exception) { // catch all exception, log them as warning. // but continue sending other notifications if needed Context.Log.Warning("Sending notification resulted in error. User Id : {0}", exception, userId); } }
public HttpResponseMessage Link(LinkAccountRequest request) { if (request == null) { throw new HttpResponseException(HttpStatusCode.BadRequest); } string uh = request.UserIdHash; int code = request.Code; Guid activityId = Guid.NewGuid(); var linkAccountResponse = new ConfirmApiResponse { ActivityId = activityId }; Log.Info(activityId, "Start Processing link account request. uh={0}", uh); var identity = Thread.CurrentPrincipal.Identity as CustomIdentity; if (identity == null) { Log.Error(activityId, "call passed authentication however identity context is empty. uh: {0}", uh); linkAccountResponse.Code = LinkAccountResultCode.UnknownError.ToString(); return(Request.CreateResponse(HttpStatusCode.InternalServerError, linkAccountResponse)); } try { var result = this.userDal.ConfirmEntity(uh, EntityType.AccountLink, code); // couldn't confirm code if (result == null || result.Status != ConfirmStatus.CodeConfirmed) { Log.Error(activityId, "Couldn't link account for user: {0}. Response from confirm code call: {1}", uh, result != null ? (ConfirmStatus?)result.Status : null); linkAccountResponse.Code = LinkAccountResultCode.Invalid.ToString(); return(Request.CreateResponse(HttpStatusCode.BadRequest, linkAccountResponse)); } // code confirmed Guid userId = result.UserId.Value; User user = this.userDal.GetUserByUserId(userId); if (user == null) { Log.Error(activityId, "Link account error. User is confirmed however the user couldn't be found in DB. user id: {0}", userId); linkAccountResponse.Code = LinkAccountResultCode.UnknownError.ToString(); return(Request.CreateResponse(HttpStatusCode.InternalServerError, linkAccountResponse)); } User authenticateUser = this.userDal.GetUserByExternalId(identity.ExternalUserId, UserExternalIdType.MsId); // there is a user in the db with the given external id if (authenticateUser != null) { // the users are actualy the same user if (authenticateUser.Id == userId) { Log.Verbose(activityId, "Link account succeeded. User already linked to this external id. user id: {0}", userId); linkAccountResponse.Code = LinkAccountResultCode.Linked.ToString(); return(Request.CreateResponse(HttpStatusCode.Accepted, linkAccountResponse)); } // this external identity already in use. Log.Warn(activityId, "Can't link account to external identity. this identity is in use by other user. user id:{0}, other user id:{1}", userId, authenticateUser.Id); linkAccountResponse.Code = LinkAccountResultCode.ExternalIdentityInUse.ToString(); return(Request.CreateResponse(HttpStatusCode.Forbidden, linkAccountResponse)); } if (user.MsId != null) { // user already linked to different msid Log.Warn(activityId, "User linked to other external id. user id: {0}", userId); linkAccountResponse.Code = LinkAccountResultCode.AlreadyLinked.ToString(); return(Request.CreateResponse(HttpStatusCode.Conflict, linkAccountResponse)); } // Link exterenal id to the account this.userDal.CreateOrGetUserByMsId(identity.ExternalUserId, null, null, userId); Log.Verbose(activityId, "Account linking succeeded. user id: {0}", userId); linkAccountResponse.Code = LinkAccountResultCode.Linked.ToString(); return(Request.CreateResponse(HttpStatusCode.Accepted, linkAccountResponse)); } catch (Exception e) { Log.Error(activityId, e, "Unexpected error in link accounts call. user id hash: {0}", uh); linkAccountResponse.Code = LinkAccountResultCode.UnknownError.ToString(); return(Request.CreateResponse(HttpStatusCode.InternalServerError, linkAccountResponse)); } }