/// <summary> /// Retries the login process after user consent to change session. /// </summary> /// <param name="request">The request to retry.</param> /// <param name="response">The response received from the server.</param> private async void RetryLogin(JsonObject request, JsonValue response) { // Ask the user consent to override session var consent = await App.DisplayAlert( Localization.ConfirmationDialogTitle, Localization.ConfirmationSesionChange, Localization.ButtonConfirm, Localization.Cancel); // If the user consent received if (consent) { // Modify the request based on server response var grantType = response.GetItemOrDefault("grant_type").GetStringValueOrDefault(string.Empty); if (!string.IsNullOrEmpty(grantType)) { request["grant_type"] = grantType; } var state = response.GetItemOrDefault("state").GetStringValueOrDefault(string.Empty); if (!string.IsNullOrEmpty(state)) { request["state"] = state; } // Resent the request to the server request.Add("override", true); WebHelper.SendAsync( Uris.GetLoginUri(), request.AsHttpContent(), this.ProcessLoginResult, () => this.IsBusy = false); } else { // Cancel the task this.UserName = string.Empty; this.Password = string.Empty; this.OnPropertyChanged(nameof(this.Password)); this.IsBusy = false; } }
/// <summary> /// Resumes the log in with the specified provider. /// </summary> /// <param name="authorizationUri">The user authorization URI.</param> private void ResumeLoginWith(Uri authorizationUri) { // Get the saved OAUTH state var stateString = Settings.Instance.GetValue(Settings.OauthToken, "{}"); var oauthState = (JsonObject)Json.Json.Read(stateString); Settings.Instance.Remove(Settings.OauthToken); // Get the query parameters from the URI Debug.WriteLine("ResumeLoginWith({0})", authorizationUri); var query = authorizationUri.Query; if ((query.Length > 0) && (query[0] == '?')) { query = query.Substring(1); } // Parse the keys and values var pairs = query.Split('&'); var arguments = new Dictionary <string, string>(); foreach (var pair in pairs) { var split = pair.Split('='); arguments.Add( Uri.UnescapeDataString(split[0]), split.Length > 1 ? Uri.UnescapeDataString(split[1]) : string.Empty); } // If error is present if (arguments.ContainsKey("error")) { // Report error to the user App.DisplayAlert( Localization.ErrorDialogTitle, Localization.ErrorCancelled, Localization.DialogDismiss); return; } // Add the result to the saved state foreach (var kvp in arguments) { oauthState.Add(kvp.Key, kvp.Value); } // Add the device and push token var deviceId = ((App)Application.Current).DeviceId; var pushToken = ((App)Application.Current).PushToken; oauthState.Add("device", deviceId); if (!string.IsNullOrEmpty(pushToken)) { oauthState.Add("push_token", pushToken); } // Setup error handlers // - If session is already opened by another device, request user consent var handlers = new Dictionary <System.Net.HttpStatusCode, Action <JsonValue> > { { System.Net.HttpStatusCode.Conflict, resp => this.RetryLogin(oauthState, resp) } }; // Send request to the server this.IsBusy = true; WebHelper.SendAsync( Uris.GetLoginUri(), oauthState.AsHttpContent(), this.ProcessLoginResult, () => this.IsBusy = false, handlers); }
/// <summary> /// Logs in the user with the provided credentials. /// </summary> private void Login() { // Login the user System.Diagnostics.Debug.WriteLine("{0}:{1}", this.UserName, this.Password); // If already logging in if (this.IsBusy) { return; } // Validate that the user name is a valid email var user = this.UserName.Trim().ToLower(); var isEmail = Regex.IsMatch( user, @"\A(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\Z", RegexOptions.IgnoreCase); if (!isEmail) { App.DisplayAlert( Localization.ErrorDialogTitle, Localization.ErrorInvalidUserLogin, Localization.DialogDismiss); return; } // Validate that the password is present if (this.Password.Length <= 2) { App.DisplayAlert( Localization.ErrorDialogTitle, Localization.ErrorInvalidPassword, Localization.DialogDismiss); return; } // Prepare the data to be send to the server var deviceId = ((App)Application.Current).DeviceId; var request = new Json.JsonObject { { "grant_type", "password" }, { "username", user }, { "password", this.Password }, { "scope", "user submit-report" }, { "device", deviceId } }; // If push token exists var pushToken = ((App)Application.Current).PushToken; if (!string.IsNullOrEmpty(pushToken)) { request.Add("push_token", pushToken); } // Setup error handlers // - If session is already opened by another device, request user consent var handlers = new Dictionary <System.Net.HttpStatusCode, Action <JsonValue> > { { System.Net.HttpStatusCode.Conflict, resp => this.RetryLogin(request, resp) } }; // Send request to the server this.IsBusy = true; WebHelper.SendAsync( Uris.GetLoginUri(), request.AsHttpContent(), this.ProcessLoginResult, () => this.IsBusy = false, handlers); }