// POST api/CustomLogin public HttpResponseMessage Post(LoginRequest loginRequest) { // TODO: Comment out for Azure Table storage. MobileServiceContext context = new MobileServiceContext(); Account account = context.Accounts .Where(a => a.Username == loginRequest.username).SingleOrDefault(); //// TODO: Uncomment to use Azure Table storage. //// Create a query for a specific username. //TableQuery<Account> query = new TableQuery<Account>().Where( // TableQuery.GenerateFilterCondition("Username", QueryComparisons.Equal, // loginRequest.username)); //// Execute the query to retrieve the account. //Account account = accountTable.ExecuteQuery(query).SingleOrDefault(); if (account != null) { if (!account.IsConfirmed) { return this.Request.CreateResponse(HttpStatusCode.BadRequest, "You must first confim your account registration."); } byte[] incoming = CustomLoginProviderUtils .hash(loginRequest.password, account.Salt); if (CustomLoginProviderUtils.slowEquals(incoming, account.SaltedAndHashedPassword)) { ClaimsIdentity claimsIdentity = new ClaimsIdentity(); claimsIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, loginRequest.username)); LoginResult loginResult = new CustomLoginProvider(handler) .CreateLoginResult(claimsIdentity, Services.Settings.MasterKey); var customLoginResult = new CustomLoginResult() { UserId = loginResult.User.UserId, MobileServiceAuthenticationToken = loginResult.AuthenticationToken }; return this.Request.CreateResponse(HttpStatusCode.OK, customLoginResult); } } return this.Request.CreateResponse(HttpStatusCode.Unauthorized, "Invalid username or password"); }
// POST api/CustomRegistration public HttpResponseMessage Post(RegistrationRequest registrationRequest) { if (!Regex.IsMatch(registrationRequest.username, "^[a-zA-Z0-9]{4,}$")) { return this.Request.CreateResponse(HttpStatusCode.BadRequest, "Invalid username (at least 4 chars, alphanumeric only)"); } else if (registrationRequest.password.Length < 8) { return this.Request.CreateResponse(HttpStatusCode.BadRequest, "Invalid password (at least 8 chars required)"); } else if (!registrationRequest.email.Contains("@")) { return this.Request.CreateResponse(HttpStatusCode.BadRequest, "Please supply a valid email address"); } // TODO: Comment out for Azure Table storage. // SQL Database version using Entity Framework for data access. MobileServiceContext context = new MobileServiceContext(); Account account = context.Accounts.Where(a => a.Username == registrationRequest.username).SingleOrDefault(); //// TODO: Azure Table storage version. //// Create a query for a specific username. //TableQuery<Account> query = new TableQuery<Account>().Where( // TableQuery.GenerateFilterCondition("Username", QueryComparisons.Equal, // registrationRequest.username)); //// Execute the query to retrieve the account. //Account account = accountTable.ExecuteQuery(query).FirstOrDefault(); // If there's already a confirmed account, return an error response. if (account != null) { return this.Request.CreateResponse(HttpStatusCode.BadRequest, "That username already exists."); } else { byte[] salt = CustomLoginProviderUtils.generateSalt(); Account newAccount = new Account { //// TODO: Uncomment the below for Azure Table storage. //PartitionKey = "partition", //RowKey = Guid.NewGuid().ToString(), //// TODO: Comment-out for Azure Table storage. Id = Guid.NewGuid().ToString(), Username = registrationRequest.username, Salt = salt, SaltedAndHashedPassword = CustomLoginProviderUtils.hash(registrationRequest.password, salt), IsConfirmed = true, // this should be false until confirmed. Email = registrationRequest.email, FriendlyName = registrationRequest.friendlyName }; // TODO: Comment out for Azure Table storage. context.Accounts.Add(newAccount); context.SaveChanges(); //// TODO: Azure Table storage version. //// Insert the new account into the table. //accountTable.Execute(TableOperation.Insert(newAccount)); // This is where you would kick-off the independent verification process, // such as sending an email using SendGrid integration (http://aka.ms/busjrt). // https://github.com/sendgrid/sendgrid-csharp // Return the success response. return this.Request.CreateResponse(HttpStatusCode.Created); } }