public HttpResponseMessage RoadZenResetPassword(LoginRequest passwordRequest)
        {
            Services.Log.Info("RoadZen Password Reset Request from Phone# [" + passwordRequest.Phone + "]");

            stranddContext context     = new stranddContext();
            Account        useraccount = context.Accounts.Where(a => a.Phone == passwordRequest.Phone).SingleOrDefault();

            if (useraccount != null)
            {
                if (useraccount.ProviderUserID.Substring(0, 7) != "RoadZen")
                {
                    string responseText = "Phone# Registered with Google";
                    Services.Log.Warn(responseText);
                    return(this.Request.CreateResponse(HttpStatusCode.BadRequest, WebConfigurationManager.AppSettings["RZ_MobileClientUserWarningPrefix"] + responseText));
                }
                else
                {
                    //Generate random characters from GUID
                    string newPassword = Guid.NewGuid().ToString().Replace("-", string.Empty).Substring(0, 8);

                    //Encrypt new Password
                    byte[] salt = RoadZenSecurityUtils.generateSalt();
                    useraccount.Salt = salt;

                    useraccount.SaltedAndHashedPassword = RoadZenSecurityUtils.hash(newPassword, salt);
                    Services.Log.Info("Password for Phone# [" + passwordRequest.Phone + "] Reset & Saved");

                    //Save Encrypted Password
                    context.SaveChanges();

                    //Prepare SendGrid Mail
                    SendGridMessage resetEmail = new SendGridMessage();

                    resetEmail.From = SendGridHelper.GetAppFrom();
                    resetEmail.AddTo(useraccount.Email);
                    resetEmail.Subject = "StrandD Password Reset";
                    resetEmail.Html    = "<h3>New Password</h3><p>" + newPassword + "</p>";
                    resetEmail.Text    = "New Password: "******"New Password Email Sent to [" + useraccount.Email + "]";
                    Services.Log.Info(responseText);
                    return(this.Request.CreateResponse(HttpStatusCode.OK, responseText));
                }
            }
            else
            {
                string responseText = "Phone Number Not Registered";
                Services.Log.Warn(responseText);
                return(this.Request.CreateResponse(HttpStatusCode.BadRequest, WebConfigurationManager.AppSettings["RZ_MobileClientUserWarningPrefix"] + responseText));
            }
        }
        public HttpResponseMessage RoadZenAccountProviderRegistration(ProviderRegistrationRequest registrationRequest)
        {
            Services.Log.Info("New Account Provider Registration Request [API]");

            // Phone Number SS Validation
            if (!Regex.IsMatch(registrationRequest.Phone, "^[0-9]{10}$"))
            {
                Services.Log.Warn("Invalid phone number (must be 10 numeric digits");
                return(this.Request.CreateResponse(HttpStatusCode.BadRequest, "Invalid phone number (must be 10 numeric digits"));
            }
            if (!RegexUtilities.IsValidEmail(registrationRequest.Email))
            {
                Services.Log.Warn("Invalid e-mail address");
                return(this.Request.CreateResponse(HttpStatusCode.BadRequest, "Invalid e-mail address"));
            }

            // Get the logged-in user.
            var currentUser = this.User as ServiceUser;

            stranddContext context = new stranddContext();

            Account account = context.Accounts.Where(a => a.Phone == registrationRequest.Phone).SingleOrDefault();

            if (account != null)
            {
                string responseText = "Phone Number Already Registered";
                Services.Log.Warn(responseText);
                return(this.Request.CreateResponse(HttpStatusCode.BadRequest, WebConfigurationManager.AppSettings["RZ_MobileClientUserWarningPrefix"] + responseText));
            }

            //Password SS Validation
            if (registrationRequest.Password.Length < 6)
            {
                Services.Log.Warn("Invalid password (at least 6 chars required)");
                return(this.Request.CreateResponse(HttpStatusCode.BadRequest, "Invalid password (at least 6 chars required)"));
            }

            byte[] salt = RoadZenSecurityUtils.generateSalt();

            Guid guid = Guid.NewGuid();

            Account newUserAccount = new Account
            {
                Id                      = guid.ToString(),
                Name                    = registrationRequest.Name,
                Phone                   = registrationRequest.Phone,
                Email                   = registrationRequest.Email,
                ProviderUserID          = "RoadZen:" + guid.ToString("N").ToUpper(),
                Salt                    = salt,
                SaltedAndHashedPassword = RoadZenSecurityUtils.hash(registrationRequest.Password, salt)
            };

            context.Accounts.Add(newUserAccount);
            context.SaveChanges();

            Services.Log.Info("Account for [" + newUserAccount.ProviderUserID + "] has been created");
            return(this.Request.CreateResponse(HttpStatusCode.Created, "Account for [" + newUserAccount.ProviderUserID + "] has been created"));
        }
        public HttpResponseMessage RoadZenLogin(LoginRequest loginRequest)
        {
            Services.Log.Info("RoadZen Login Request from Phone# [" + loginRequest.Phone + "]");

            stranddContext context     = new stranddContext();
            Account        useraccount = context.Accounts.Where(a => a.Phone == loginRequest.Phone).SingleOrDefault();

            if (useraccount != null)
            {
                // Check if Registered Phone Number is through Google-Provider Account
                if (useraccount.ProviderUserID.Substring(0, 6) == "Google")
                {
                    string responseText = "Phone Number Registered with Google";
                    Services.Log.Warn(responseText);
                    return(this.Request.CreateResponse(HttpStatusCode.Unauthorized, WebConfigurationManager.AppSettings["RZ_MobileClientUserWarningPrefix"] + responseText));
                }

                byte[] incoming = RoadZenSecurityUtils.hash(loginRequest.Password, useraccount.Salt);

                if (RoadZenSecurityUtils.slowEquals(incoming, useraccount.SaltedAndHashedPassword))
                {
                    ClaimsIdentity claimsIdentity = new ClaimsIdentity();
                    claimsIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, loginRequest.Phone));
                    claimsIdentity.AddClaim(new Claim("AccountGUID", useraccount.Id));

                    LoginResult loginResult = new RoadZenLoginProvider(handler).CreateLoginResult(claimsIdentity, Services.Settings.MasterKey);

                    Services.Log.Info("Account [" + useraccount.ProviderUserID + "] has logged-in");
                    return(this.Request.CreateResponse(HttpStatusCode.OK, loginResult));
                }
                else
                {
                    string responseText = "Incorrect Password";
                    Services.Log.Warn(responseText);
                    return(this.Request.CreateResponse(HttpStatusCode.Unauthorized, WebConfigurationManager.AppSettings["RZ_MobileClientUserWarningPrefix"] + responseText));
                }
            }
            else
            {
                string responseText = "Unregistered Phone Number";
                Services.Log.Warn(responseText);
                return(this.Request.CreateResponse(HttpStatusCode.Unauthorized, WebConfigurationManager.AppSettings["RZ_MobileClientUserWarningPrefix"] + responseText));
            }
        }