/// <summary> /// Get the request token using the consumer id and secret. Also initializes token secret /// </summary> /// <param name="cancellationToken">CancellationToken</param> private async Task GetRequestTokenAsync(CancellationToken cancellationToken = default) { _oAuth1HttpBehaviour.MakeCurrent(); // Create a HttpRequestMessage for the Token-Url var httpRequestMessage = HttpRequestMessageFactory.Create(_oAuth1Settings.TokenMethod, _oAuth1Settings.TokenUrl); // sign it Sign(httpRequestMessage); // Use it to get the response var response = await httpRequestMessage.SendAsync <string>(cancellationToken).ConfigureAwait(false); if (!string.IsNullOrEmpty(response)) { Log.Verbose().WriteLine("Request token response: {0}", response); var resultParameters = UriParseExtensions.QueryStringToDictionary(response); if (resultParameters.TryGetValue(OAuth1Parameters.Token.EnumValueOf(), out var tokenValue)) { Log.Verbose().WriteLine("Storing token {0}", tokenValue); _oAuth1Settings.RequestToken = tokenValue; } if (resultParameters.TryGetValue(OAuth1Parameters.TokenSecret.EnumValueOf(), out var tokenSecretValue)) { Log.Verbose().WriteLine("Storing token secret {0}", tokenSecretValue); _oAuth1Settings.RequestTokenSecret = tokenSecretValue; } } }
/// <summary> /// Get the access token /// </summary> /// <param name="cancellationToken">CancellationToken</param> /// <returns>The access token.</returns> private async Task GetAccessTokenAsync(CancellationToken cancellationToken = default(CancellationToken)) { if (string.IsNullOrEmpty(_oAuth1Settings.AuthorizeToken)) { throw new ArgumentNullException(nameof(_oAuth1Settings.AuthorizeToken), "The authorize token is not set"); } if (_oAuth1Settings.CheckVerifier && string.IsNullOrEmpty(_oAuth1Settings.Token.OAuthTokenVerifier)) { throw new ArgumentNullException(nameof(_oAuth1Settings.Token.OAuthTokenVerifier), "The verifier is not set"); } _oAuth1HttpBehaviour.MakeCurrent(); // Create a HttpRequestMessage for the Token-Url var httpRequestMessage = HttpRequestMessageFactory.Create(_oAuth1Settings.AccessTokenMethod, _oAuth1Settings.AccessTokenUrl); // sign it Sign(httpRequestMessage); // Use it to get the response var response = await httpRequestMessage.SendAsync <string>(cancellationToken).ConfigureAwait(false); if (!string.IsNullOrEmpty(response)) { Log.Verbose().WriteLine("Access token response: {0}", response); var resultParameters = UriParseExtensions.QueryStringToDictionary(response); string tokenValue; if (resultParameters.TryGetValue(OAuth1Parameters.Token.EnumValueOf(), out tokenValue)) { _oAuth1Settings.Token.OAuthToken = tokenValue; resultParameters.Remove(OAuth1Parameters.Token.EnumValueOf()); } string secretValue; if (resultParameters.TryGetValue(OAuth1Parameters.TokenSecret.EnumValueOf(), out secretValue)) { _oAuth1Settings.Token.OAuthTokenSecret = secretValue; resultParameters.Remove(OAuth1Parameters.TokenSecret.EnumValueOf()); } // Process the rest, if someone registed, some services return more values _oAuth1HttpBehaviour?.OnAccessTokenValues?.Invoke(resultParameters); } }
public void TestOutOfBoundCodeReceiverParseTitle() { var queryPartOfTitleRegEx = new Regex(@".*\|\|(?<query>.*)\|\|.*", RegexOptions.IgnoreCase); var state = Guid.NewGuid().ToString(); const string code = "2497hf29ruh234zruif390ugo34t23jfg23"; var query = $"state={state}&code={code}"; var testString = $"Greenshot authenticated with Imgur||{query}|| - Google Chrome"; Assert.False(string.IsNullOrEmpty(testString)); var match = queryPartOfTitleRegEx.Match(testString); Assert.True(match.Success); var queryParameters = match.Groups["query"]?.Value; Assert.NotNull(queryParameters); Assert.NotEmpty(queryParameters); Assert.Equal(query, queryParameters); var dict = UriParseExtensions.QueryStringToDictionary(queryParameters); Assert.Equal(code, dict["code"]); Assert.Equal(state, dict["state"]); }
/// <inheritdoc /> public async Task <object> ConvertFromHttpContentAsync(Type resultType, HttpContent httpContent, CancellationToken cancellationToken = default(CancellationToken)) { if (resultType == null) { throw new ArgumentNullException(nameof(resultType)); } if (httpContent == null) { throw new ArgumentNullException(nameof(httpContent)); } if (!CanConvertFromHttpContent(resultType, httpContent)) { throw new NotSupportedException("Don't calls this, when the CanConvertFromHttpContent returns false!"); } // Get the string from the content var formUriEncodedString = await httpContent.ReadAsStringAsync().ConfigureAwait(false); // Use code in the UriParseExtensions to parse the query string Log.Debug().WriteLine("Read WwwUriEncodedForm data: {0}", formUriEncodedString); // This returns an IEnumerable<KeyValuePair<string, string>> return(UriParseExtensions.QueryStringToKeyValuePairs(formUriEncodedString)); }
/// <summary> /// The OAuth code receiver /// </summary> /// <param name="authorizeMode">which of the AuthorizeModes was used to call the method</param> /// <param name="codeReceiverSettings"></param> /// <param name="cancellationToken">CancellationToken</param> /// <returns>Dictionary with values</returns> public async Task <IDictionary <string, string> > ReceiveCodeAsync(AuthorizeModes authorizeMode, ICodeReceiverSettings codeReceiverSettings, CancellationToken cancellationToken = default) { // Force OOB Uri, if nothing is set if (string.IsNullOrEmpty(codeReceiverSettings.RedirectUrl)) { switch (authorizeMode) { case AuthorizeModes.OutOfBound: codeReceiverSettings.RedirectUrl = "urn:ietf:wg:oauth:2.0:oob"; break; case AuthorizeModes.OutOfBoundAuto: codeReceiverSettings.RedirectUrl = "urn:ietf:wg:oauth:2.0:oob:auto"; break; default: throw new NotSupportedException($"Only {AuthorizeModes.OutOfBound} and {AuthorizeModes.OutOfBoundAuto} are supported modes for this receiver"); } } var uriBuilder = new UriBuilder(codeReceiverSettings.AuthorizationUri) { Query = codeReceiverSettings.AuthorizationUri.QueryToKeyValuePairs() .Select(x => new KeyValuePair <string, string>(x.Key, x.Value.FormatWith(codeReceiverSettings))) .ToQueryString() }; // Get the formatted FormattedAuthUrl var authorizationUrl = uriBuilder.Uri; Log.Debug().WriteLine("Opening a browser with: {0}", authorizationUrl.AbsoluteUri); // Open the url in the default browser var processStartInfo = new ProcessStartInfo(authorizationUrl.AbsoluteUri) { CreateNoWindow = true, UseShellExecute = true }; Process.Start(processStartInfo); Log.Debug().WriteLine("Waiting until a window gets a title with the state {0}", codeReceiverSettings.State); // Wait until a window get's a title which contains the state object var title = await WinEventHook.WindowTileChangeObservable() .Select(info => InteropWindowFactory.CreateFor(info.Handle).Fill()) .Where(interopWindow => !string.IsNullOrEmpty(interopWindow?.Caption)) .Where(interopWindow => interopWindow.Caption.Contains(codeReceiverSettings.State)) // Skip temporary titles, where the redirect URL os briefly seen .Where(interopWindow => interopWindow?.Caption.Contains(codeReceiverSettings.RedirectUrl) != true) .Select(interopWindow => interopWindow.Caption) .Take(1).ToTask(cancellationToken); Log.Debug().WriteLine("Got title {0}", title); if (string.IsNullOrEmpty(title)) { return(new Dictionary <string, string>()); } var match = QueryPartOfTitleRegEx.Match(title); if (!match.Success) { return(UriParseExtensions.QueryStringToDictionary(title)); } var queryParameters = match.Groups["query"]?.Value; if (string.IsNullOrEmpty(queryParameters)) { return(new Dictionary <string, string>()); } Log.Debug().WriteLine("Query parameters: {0}", queryParameters); // Return result of the listening return(UriParseExtensions.QueryStringToDictionary(queryParameters)); }