示例#1
0
        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));
            }
        }
示例#2
0
        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);
            }
        }
示例#3
0
        /// <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,
            });
        }
示例#4
0
        /// <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
            });
        }
示例#5
0
        /// <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);
            }
        }
示例#6
0
        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));
            }
        }