public async Task <ActionResult> Generate() { string input = null; // If not data came in, then return if (this.Request.Body == null) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Request content is null", HttpStatusCode.Conflict))); } // Read the input claims from the request body using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8)) { input = await reader.ReadToEndAsync(); } // Check input content value if (string.IsNullOrEmpty(input)) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Request content is empty", HttpStatusCode.Conflict))); } // Convert the input string into InputClaimsModel object InputClaimsModel inputClaims = InputClaimsModel.Parse(input); if (inputClaims == null) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Can not deserialize input claims", HttpStatusCode.Conflict))); } try { // Define the URL for the QR code. When user scan this URL, it opens one of the // authentication apps running on the mobile device byte[] secretKey = KeyGeneration.GenerateRandomKey(20); string TOTPUrl = KeyUrl.GetTotpUrl(secretKey, $"{AppSettings.TOTPAccountPrefix}:{inputClaims.userName}", AppSettings.TOTPTimestep); TOTPUrl = $"{TOTPUrl}&issuer={AppSettings.TOTPIssuer.Replace(" ", "%20")}"; // Generate QR code for the above URL var qrCodeGenerator = new QRCodeGenerator(); QRCodeData qrCodeData = qrCodeGenerator.CreateQrCode(TOTPUrl, QRCodeGenerator.ECCLevel.L); BitmapByteQRCode qrCode = new BitmapByteQRCode(qrCodeData); byte[] qrCodeBitmap = qrCode.GetGraphic(4); B2CResponseModel output = new B2CResponseModel(string.Empty, HttpStatusCode.OK) { qrCodeBitmap = Convert.ToBase64String(qrCodeBitmap), secretKey = this.EncryptAndBase64(Convert.ToBase64String(secretKey)) }; return(Ok(output)); } catch (Exception ex) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel($"General error (REST API): {ex.Message}", HttpStatusCode.Conflict))); } }
public IHttpActionResult Validate() { // Check the certificate if (IsValidClientCertificate() == false) { return(Content(HttpStatusCode.Conflict, new B2CResponseModel("Your client certificate is not valid", HttpStatusCode.Conflict))); } // If not data came in, then returen if (this.Request.Content == null) { throw new Exception(); } // Read the input claims from the request body string input = Request.Content.ReadAsStringAsync().Result; // Check input content value if (string.IsNullOrEmpty(input)) { return(Content(HttpStatusCode.Conflict, new B2CResponseModel("Request content is empty", HttpStatusCode.Conflict))); } // Convert the input string into InputClaimsModel object InputClaimsModel inputClaims = JsonConvert.DeserializeObject(input, typeof(InputClaimsModel)) as InputClaimsModel; if (inputClaims == null) { return(Content(HttpStatusCode.Conflict, new B2CResponseModel("Can not deserialize input claims", HttpStatusCode.Conflict))); } //Check if the language parameter is presented if (string.IsNullOrEmpty(inputClaims.language)) { return(Content(HttpStatusCode.Conflict, new B2CResponseModel("Language code is null or empty", HttpStatusCode.Conflict))); } //Check if the email parameter is presented if (string.IsNullOrEmpty(inputClaims.email)) { return(Content(HttpStatusCode.Conflict, new B2CResponseModel("Email is null or empty", HttpStatusCode.Conflict))); } // Validate the email address if (inputClaims.email.ToLower().StartsWith("test")) { return(Content(HttpStatusCode.Conflict, new B2CResponseModel("Your email address can't start with 'test'", HttpStatusCode.Conflict))); } // Create output claims object and set the loyalty number with random value B2CResponseModel outputClaims = new B2CResponseModel(string.Empty, HttpStatusCode.OK); outputClaims.loyaltyNumber = inputClaims.language + "-" + rnd.Next(1000, 9999).ToString(); outputClaims.email = inputClaims.email.ToLower(); // Return the output claim(s) return(Ok(outputClaims)); }
public async Task <IActionResult> GenerateAsync( [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "totp/generate")] HttpRequest request, ILogger log) { log.LogInformation("Start QrCode Generate Function."); if (request.Body is null) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Request content is null", HttpStatusCode.Conflict))); } var input = await new StreamReader(request.Body, Encoding.UTF8).ReadToEndAsync(); if (string.IsNullOrEmpty(input)) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Request content is empty", HttpStatusCode.Conflict))); } var inputClaims = InputClaimsModel.Parse(input); if (inputClaims == null) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Can not deserialize input claims", HttpStatusCode.Conflict))); } try { var secretKey = KeyGeneration.GenerateRandomKey(20); var TOTPUrl = GetTotpUrl(secretKey , inputClaims.UserName , _options.TOTPIssuer , _options.TOTPTimestep , _options.TOTPAccountPrefix); // Generate QR code for the above URL var qrCodeGenerator = new QRCodeGenerator(); var qrCodeData = qrCodeGenerator.CreateQrCode(TOTPUrl, QRCodeGenerator.ECCLevel.L); var qrCode = new BitmapByteQRCode(qrCodeData); var qrCodeBitmap = qrCode.GetGraphic(4); var output = new B2CResponseModel(string.Empty, HttpStatusCode.OK) { QrCodeBitmap = Convert.ToBase64String(qrCodeBitmap), SecretKey = EncryptAndBase64(Convert.ToBase64String(secretKey)) }; return(Ok(output)); } catch (Exception e) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel($"General error (REST API): {e.Message}", HttpStatusCode.Conflict))); } }
public IHttpActionResult Loyalty() { // If not data came in, then returen if (this.Request.Content == null) { throw new Exception(); } // Read the input claims from the request body string input = Request.Content.ReadAsStringAsync().Result; // Check input content value if (string.IsNullOrEmpty(input)) { return(Content(HttpStatusCode.Conflict, new B2CResponseModel("Request content is empty", HttpStatusCode.Conflict))); } // Convert the input string into InputClaimsModel object InputClaimsModel inputClaims = JsonConvert.DeserializeObject(input, typeof(InputClaimsModel)) as InputClaimsModel; if (inputClaims == null) { return(Content(HttpStatusCode.Conflict, new B2CResponseModel("Can not deserialize input claims", HttpStatusCode.Conflict))); } //Check if the language parameter is presented if (string.IsNullOrEmpty(inputClaims.language)) { return(Content(HttpStatusCode.Conflict, new B2CResponseModel("Language code is null or empty", HttpStatusCode.Conflict))); } //Check if the objectId parameter is presented if (string.IsNullOrEmpty(inputClaims.objectId)) { return(Content(HttpStatusCode.Conflict, new B2CResponseModel("User object Id is null or empty", HttpStatusCode.Conflict))); } // Create output claims object and set the loyalty number with random value B2CResponseModel outputClaims = new B2CResponseModel(string.Empty, HttpStatusCode.OK); outputClaims.loyaltyNumber = inputClaims.language + "-" + rnd.Next(1000, 9999).ToString(); // Return the output claim(s) return(Ok(outputClaims)); }
public async Task <ActionResult> LoginCallbackJSON() { string input = null; if (this.Request.Body == null) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Request content is null", HttpStatusCode.Conflict))); } // Read the input claims from the request body using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8)) { input = await reader.ReadToEndAsync(); } // Check input content value if (string.IsNullOrEmpty(input)) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Request content is empty", HttpStatusCode.Conflict))); } // Convert the input string into InputClaimsModel object CallbackClaimsModel inputClaims = CallbackClaimsModel.Parse(input); if (inputClaims == null) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Can not deserialize input claims", HttpStatusCode.Conflict))); } byte[] data = Convert.FromBase64String(inputClaims.callback); string decodedString = Encoding.UTF8.GetString(data); CredentialsModel cm = JsonConvert.DeserializeObject <CredentialsModel>(decodedString); B2CResponseModel b2crm = LoginCallbackAPI(cm); return(Ok(b2crm)); }
public async Task <IActionResult> VerifyAsync( [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "totp/verify")] HttpRequest request, ILogger log) { log.LogInformation("Start code Verify Function."); if (request.Body is null) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Request content is null", HttpStatusCode.Conflict))); } var input = await new StreamReader(request.Body, Encoding.UTF8).ReadToEndAsync(); if (string.IsNullOrEmpty(input)) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Request content is empty", HttpStatusCode.Conflict))); } var inputClaims = InputClaimsModel.Parse(input); if (inputClaims == null) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Can not deserialize input claims", HttpStatusCode.Conflict))); } try { var secretKey = Convert.FromBase64String(DecryptAndBase64(inputClaims.SecretKey)); var totp = new Totp(secretKey); // Verify the TOTP code provided by the users var verificationResult = totp.VerifyTotp( inputClaims.TotpCode, out var timeStepMatched, VerificationWindow.RfcSpecifiedNetworkDelay); if (!verificationResult) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("The verification code is invalid.", HttpStatusCode.Conflict))); } // Using the input claim 'timeStepMatched', we check whether the verification code has already been used. // For sign-up, the 'timeStepMatched' input claim is null and should not be evaluated // For sign-in, the 'timeStepMatched' input claim contains the last time a code matched (from the user profile), and if equal to // the last time matched from the verify totp step, we know this code has already been used and can reject if (!string.IsNullOrEmpty(inputClaims.TimeStepMatched) && (inputClaims.TimeStepMatched).Equals(timeStepMatched.ToString())) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("The verification code has already been used.", HttpStatusCode.Conflict))); } var output = new B2CResponseModel(string.Empty, HttpStatusCode.OK) { TimeStepMatched = timeStepMatched.ToString() }; return(Ok(output)); } catch (Exception e) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel($"General error (REST API): {e.Message}", HttpStatusCode.Conflict))); } }
public async Task <ActionResult> Verify() { string input = null; // If not data came in, then return if (this.Request.Body == null) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Request content is null", HttpStatusCode.Conflict))); } // Read the input claims from the request body using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8)) { input = await reader.ReadToEndAsync(); } // Check input content value if (string.IsNullOrEmpty(input)) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Request content is empty", HttpStatusCode.Conflict))); } // Convert the input string into InputClaimsModel object InputClaimsModel inputClaims = InputClaimsModel.Parse(input); if (inputClaims == null) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Can not deserialize input claims", HttpStatusCode.Conflict))); } try { byte[] secretKey = Convert.FromBase64String(this.DecryptAndBase64(inputClaims.secretKey)); Totp totp = new Totp(secretKey); long timeStepMatched; // Verify the TOTP code provided by the users bool verificationResult = totp.VerifyTotp( inputClaims.totpCode, out timeStepMatched, VerificationWindow.RfcSpecifiedNetworkDelay); if (!verificationResult) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("The verification code is invalid.", HttpStatusCode.Conflict))); } // Using the input claim 'timeStepMatched', we check whether the verification code has already been used. // For sign-up, the 'timeStepMatched' input claim is null and should not be evaluated // For sign-in, the 'timeStepMatched' input claim contains the last time last matched (from the user profile), and evaluated with // the value of the result of the TOTP out 'timeStepMatched' variable if ((string.IsNullOrEmpty(inputClaims.timeStepMatched) == false) && !(inputClaims.timeStepMatched).Equals(timeStepMatched.ToString())) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("The verification code has already been used.", HttpStatusCode.Conflict))); } B2CResponseModel output = new B2CResponseModel(string.Empty, HttpStatusCode.OK) { timeStepMatched = timeStepMatched.ToString() }; return(Ok(output)); } catch (Exception ex) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel($"General error (REST API): {ex.Message}", HttpStatusCode.Conflict))); } }
public async Task <ActionResult> Send() { string input = null; // If not data came in, then return if (this.Request.Body == null) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Request content is null", HttpStatusCode.Conflict))); } // Read the input claims from the request body using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8)) { input = await reader.ReadToEndAsync(); } // Check input content value if (string.IsNullOrEmpty(input)) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Request content is empty", HttpStatusCode.Conflict))); } // Convert the input string into InputClaimsModel object InputClaimsModel inputClaims = InputClaimsModel.Parse(input); if (inputClaims == null) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Can not deserialize input claims", HttpStatusCode.Conflict))); } // Check input email address. If phone number is empty, the user not found in the directory. So, return a random value if (string.IsNullOrEmpty(inputClaims.phoneNumber)) { B2CResponseModel b2CResponseModel = new B2CResponseModel("Ok", HttpStatusCode.OK); b2CResponseModel.verificationCode = Guid.NewGuid().ToString(); return(Ok(b2CResponseModel)); } try { int code = random.Next(1593, 9937); TwilioClient.Init(this.AppSettings.SMSUsername, this.AppSettings.SMSPassword); var message = MessageResource.Create( from: new Twilio.Types.PhoneNumber(this.AppSettings.SMSFromPhoneNumber), body: $"{this.AppSettings.SMSMessage}\r\n{code}", to: new Twilio.Types.PhoneNumber(inputClaims.phoneNumber) ); //Output claims B2CResponseModel b2CResponseModel = new B2CResponseModel("Ok", HttpStatusCode.OK); b2CResponseModel.verificationCode = code.ToString(); return(Ok(b2CResponseModel)); } catch (Exception ex) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("An unexpected error occurred. " + ex.Message, HttpStatusCode.Conflict))); } }
public IHttpActionResult Migrate() { string input = Request.Content.ReadAsStringAsync().Result; // If not data came in, then return if (this.Request.Content == null) { return(Content(HttpStatusCode.Conflict, new B2CResponseModel("Request content is null", HttpStatusCode.Conflict))); } //// Read the input claims from the request body //using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8)) //{ // input = await reader.ReadToEndAsync(); //} // Check input content value if (string.IsNullOrEmpty(input)) { return(Content(HttpStatusCode.Conflict, new B2CResponseModel("Request content is empty", HttpStatusCode.Conflict))); } // Convert the input string into InputClaimsModel object InputClaimsModel inputClaims = InputClaimsModel.Parse(input); if (inputClaims == null) { return(Content(HttpStatusCode.Conflict, new B2CResponseModel("Can not deserialize input claims", HttpStatusCode.Conflict))); } if (string.IsNullOrEmpty(inputClaims.signInName)) { return(Content(HttpStatusCode.Conflict, new B2CResponseModel("User 'signInName' is null or empty", HttpStatusCode.Conflict))); } //if (string.IsNullOrEmpty(inputClaims.password)) //{ // return Content(HttpStatusCode.Conflict, new B2CResponseModel("Password is null or empty", HttpStatusCode.Conflict)); //} AzureADGraphClient azureADGraphClient = new AzureADGraphClient(ConfigurationManager.AppSettings["Tenant"], ConfigurationManager.AppSettings["ClientId"], ConfigurationManager.AppSettings["ClientSecret"]); GraphAccountModel account = azureADGraphClient.SearcUserBySignInNames(inputClaims.signInName).Result; // User already exists, no need to migrate. if (account != null) { return(Ok()); } B2CResponseModel outputClaimsCol = new B2CResponseModel("", HttpStatusCode.OK); Ldap.Controllers.ValuesController tmp = new Ldap.Controllers.ValuesController(); outputClaimsCol.isMigrated = false; outputClaimsCol.email = inputClaims.signInName; //Only migrate account that is not migrated already, and verified successfully within the local LDAP store. if (account == null && tmp.VerifyCredentials(inputClaims.signInName, inputClaims.password)) { inputClaims.sn = "EID"; inputClaims.givenName = inputClaims.signInName; inputClaims.email = string.Format("{0}@noreply.com", inputClaims.signInName); bool result = MigrateUser(azureADGraphClient, inputClaims); if (result) { outputClaimsCol.displayName = inputClaims.sn; outputClaimsCol.givenName = inputClaims.givenName; outputClaimsCol.surName = inputClaims.email; outputClaimsCol.password = inputClaims.password; outputClaimsCol.isMigrated = true; } } return(Ok(outputClaimsCol)); //// Initiate the output claim object //B2CResponseModel outputClaims = new B2CResponseModel("", HttpStatusCode.OK); //outputClaims.newPassword = inputClaims.password; //outputClaims.email = inputClaims.signInName; //outputClaims.needToMigrate = "null"; //Ldap.Controllers.ValuesController tmp = new Ldap.Controllers.ValuesController(); //if (tmp.VerifyCredentials(inputClaims.signInName, inputClaims.password)) //{ // outputClaims.givenName = "Test " + DateTime.UtcNow.ToLongTimeString(); // outputClaims.surName = "User " + DateTime.UtcNow.ToLongDateString(); // outputClaims.needToMigrate = "local"; //} //outputClaims.displayName = userMigrationEntity.DisplayName; //outputClaims.surName = userMigrationEntity.LastName; //outputClaims.givenName = userMigrationEntity.FirstName; // Create a retrieve operation that takes a customer entity. // Note: Azure Blob Table query is case sensitive, always set the input email to lower case //var retrieveOperation = TableOperation.Retrieve<UserTableEntity>(Consts.MigrationTablePartition, inputClaims.signInName.ToLower()); //CloudTable table = await GetSignUpTable(this.AppSettings.BlobStorageConnectionString); // Execute the retrieve operation. //TableResult tableEntity = await table.ExecuteAsync(retrieveOperation); //TableResult tableEntity = null; //if (tableEntity != null && tableEntity.Result != null) //{ // UserTableEntity userMigrationEntity = ((UserTableEntity)tableEntity.Result); // try // { // outputClaims.needToMigrate = "local"; // // Compare the password entered by the user and the one in the migration table. // // Don't compare in password reset flow (useInputPassword is true) // if (inputClaims.useInputPassword || (inputClaims.password == userMigrationEntity.Password)) // { // outputClaims.newPassword = inputClaims.password; // outputClaims.email = inputClaims.signInName; // outputClaims.displayName = userMigrationEntity.DisplayName; // outputClaims.surName = userMigrationEntity.LastName; // outputClaims.givenName = userMigrationEntity.FirstName; // // Remove the user entity from migration table // TableOperation deleteOperation = TableOperation.Delete((UserTableEntity)tableEntity.Result); // //await table.ExecuteAsync(deleteOperation); // } // else // { // return Content(HttpStatusCode.Conflict, new B2CResponseModel("Your password is incorrect (migration API)", HttpStatusCode.Conflict)); // } // } // catch (Exception ex) // { // return Content(HttpStatusCode.Conflict, new B2CResponseModel($"User migration error: {ex.Message}", HttpStatusCode.Conflict)); // } //} //return Ok(outputClaims); }
public async Task <ActionResult> Register() { string input = null; // If not data came in, then return if (this.Request.Body == null) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Request content is null", HttpStatusCode.Conflict))); } // Read the input claims from the request body using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8)) { input = await reader.ReadToEndAsync(); } // Check input content value if (string.IsNullOrEmpty(input)) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Request content is empty", HttpStatusCode.Conflict))); } // Convert the input string into InputClaimsModel object InputClaimsModel inputClaims = InputClaimsModel.Parse(input); if (inputClaims == null) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Can not deserialize input claims", HttpStatusCode.Conflict))); } // Check input email address for local and social accounts if (string.IsNullOrEmpty(inputClaims.email) && string.IsNullOrEmpty(inputClaims.signInName)) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Email address is empty", HttpStatusCode.Conflict))); } // Check input phone number if (string.IsNullOrEmpty(inputClaims.phoneNumber)) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Phone number is empty", HttpStatusCode.Conflict))); } var phoneNumberMatch = Regex.Match(inputClaims.phoneNumber, @"\+(9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|4[987654310]|3[9643210]|2[70]|7|1)(\d{1,14})$"); if (!phoneNumberMatch.Success || phoneNumberMatch.Groups.Count != 3) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Phone number is not in the correct format", HttpStatusCode.Conflict))); } using (var client = new HttpClient()) { var requestUri = $"https://api.authy.com/protected/json/users/new"; var requestForm = new Dictionary <string, string>(); requestForm.Add("user[email]", inputClaims.GetEamilAddress()); requestForm.Add("user[cellphone]", phoneNumberMatch.Groups[2].Value); requestForm.Add("user[country_code]", phoneNumberMatch.Groups[1].Value); var requestContent = new FormUrlEncodedContent(requestForm); client.DefaultRequestHeaders.Add("X-Authy-API-Key", AppSettings.Key); try { var response = await client.PostAsync(requestUri, requestContent); response.EnsureSuccessStatusCode(); dynamic responseContent = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync()); string authyId = ""; if ((bool)responseContent.success) { authyId = (string)responseContent.user.id; } else { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("An unexpected error occurred creating the Authy user.", HttpStatusCode.Conflict))); } B2CResponseModel outputClaims = new B2CResponseModel() { authyId = authyId }; return(Ok(outputClaims)); } catch (Exception ex) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("An unexpected error occurred creating the Authy user." + ex.Message, HttpStatusCode.Conflict))); } } }
public async Task <ActionResult> Migrate() { string input = null; // If not data came in, then return if (this.Request.Body == null) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Request content is null", HttpStatusCode.Conflict))); } // Read the input claims from the request body using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8)) { input = await reader.ReadToEndAsync(); } // Check input content value if (string.IsNullOrEmpty(input)) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Request content is empty", HttpStatusCode.Conflict))); } // Convert the input string into InputClaimsModel object InputClaimsModel inputClaims = InputClaimsModel.Parse(input); if (inputClaims == null) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Can not deserialize input claims", HttpStatusCode.Conflict))); } if (string.IsNullOrEmpty(inputClaims.signInName)) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("User 'signInName' is null or empty", HttpStatusCode.Conflict))); } //if (string.IsNullOrEmpty(inputClaims.password)) //{ // return StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Password is null or empty", HttpStatusCode.Conflict)); //} // Initiate the output claim object B2CResponseModel outputClaims = new B2CResponseModel("", HttpStatusCode.OK); // Create a retrieve operation that takes a customer entity. // Note: Azure Blob Table query is case sensitive, always set the input email to lower case var retrieveOperation = TableOperation.Retrieve <UserTableEntity>(Consts.MigrationTablePartition, inputClaims.signInName.ToLower()); CloudTable table = await GetSignUpTable(this.AppSettings.BlobStorageConnectionString); // Execute the retrieve operation. TableResult tableEntity = await table.ExecuteAsync(retrieveOperation); if (tableEntity != null && tableEntity.Result != null) { UserTableEntity userMigrationEntity = ((UserTableEntity)tableEntity.Result); try { outputClaims.needToMigrate = "local"; // Compare the password entered by the user and the one in the migration table. // Don't compare in password reset flow (useInputPassword is true) if (inputClaims.useInputPassword || (inputClaims.password == userMigrationEntity.Password)) { outputClaims.newPassword = inputClaims.password; outputClaims.email = inputClaims.signInName; outputClaims.displayName = userMigrationEntity.DisplayName; outputClaims.surName = userMigrationEntity.LastName; outputClaims.givenName = userMigrationEntity.FirstName; // Remove the user entity from migration table TableOperation deleteOperation = TableOperation.Delete((UserTableEntity)tableEntity.Result); await table.ExecuteAsync(deleteOperation); } else { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Your password is incorrect (migration API)", HttpStatusCode.Conflict))); } } catch (Exception ex) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel($"User migration error: {ex.Message}", HttpStatusCode.Conflict))); } } return(Ok(outputClaims)); }
public async Task <ActionResult> CheckAppAttributes() { string input = null; // If not data came in, then return if (this.Request.Body == null) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Request content is null", HttpStatusCode.Conflict))); } // Read the input claims from the request body using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8)) { input = await reader.ReadToEndAsync(); } // Check input content value if (string.IsNullOrEmpty(input)) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Request content is empty", HttpStatusCode.Conflict))); } // Convert the input string into InputClaimsModel object InputClaimsModel inputClaims = InputClaimsModel.Parse(input); if (inputClaims == null) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("Can not deserialize input claims", HttpStatusCode.Conflict))); } if (string.IsNullOrEmpty(inputClaims.correlationId)) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("User 'requestId' is null or empty", HttpStatusCode.Conflict))); } if (string.IsNullOrEmpty(inputClaims.userId)) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("User 'userId' is null or empty", HttpStatusCode.Conflict))); } if (string.IsNullOrEmpty(inputClaims.ipAddress)) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("User 'ipAddress' is null or empty", HttpStatusCode.Conflict))); } if (string.IsNullOrEmpty(inputClaims.appId)) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel("User 'appId' is null or empty", HttpStatusCode.Conflict))); } string requestId = Guid.NewGuid().ToString(); try { if (inputClaims.appId == "0239a9cc-309c-4d41-87f1-31288feb2e82" && string.IsNullOrEmpty(inputClaims.city)) { CloudTable table = await GetSignUpTable(); IdentityEntity identityEntity = new IdentityEntity("SignInRequest", requestId); identityEntity.ipAddress = this.Request.HttpContext.Connection.RemoteIpAddress.ToString(); identityEntity.userId = inputClaims.userId; identityEntity.appId = inputClaims.appId; identityEntity.correlationId = inputClaims.correlationId.ToString(); TableOperation insertOperation = TableOperation.InsertOrReplace(identityEntity); await table.ExecuteAsync(insertOperation); //Output claims B2CResponseModel b2CResponseModel = new B2CResponseModel("Ok", HttpStatusCode.OK); b2CResponseModel.collectData = true; b2CResponseModel.requestId = EncryptAndBase64(requestId); return(Ok(b2CResponseModel)); } else { //Output claims B2CResponseModel b2CResponseModel = new B2CResponseModel("Ok", HttpStatusCode.OK); b2CResponseModel.collectData = false; return(Ok(b2CResponseModel)); } } catch (Exception ex) { return(StatusCode((int)HttpStatusCode.Conflict, new B2CResponseModel(ex.Message, HttpStatusCode.Conflict))); } }