private async Task <Uri> GetRelativeUriAsync(IEnumerable <object> additionalRouteValues, object queryParams, CancellationToken cancellationToken) { var routeValues = this.routeValues.Concat(additionalRouteValues ?? Enumerable.Empty <object>()).ToList(); var destructuredQueryParams = this.DestructureQueryParamsObjectRecursively(queryParams).Where(item => item.Value != null).ToList(); bool transformRouteValues = false; bool transformQueryParamters = false; if ((transformRouteValues = routeValues.Any(x => x is CurrentUserIdPlaceholder)) || (transformQueryParamters = destructuredQueryParams.Any(x => x.Value is CurrentUserIdPlaceholder))) { var currentUser = await this.contextData.CurrentUserProvider.GetAsync(cancellationToken).ConfigureAwait(false); if (transformRouteValues) { routeValues = routeValues.Select(x => x is CurrentUserIdPlaceholder ? currentUser.Id : x).ToList(); } if (transformQueryParamters) { destructuredQueryParams = destructuredQueryParams .Select(x => x.Value is CurrentUserIdPlaceholder ? new KeyValuePair <string, object>(x.Key, currentUser.Id) : x) .ToList(); } } var result = SpotifyUriUtils.GetRelativeUri(routeValues, destructuredQueryParams); return(result); }
private async Task <AuthorizationResult> AuthorizeInnerAsync(string codeChallenge, CancellationToken cancellationToken) { var authorizationOptions = this.authorizationOptionsProvider.Get(); var originalCsrfToken = this.csfrTokenProvider.Get(); var redirectUri = this.authorizationRedirectUriProvider.Get(); var queryParams = new List <KeyValuePair <string, object> > { new KeyValuePair <string, object>("client_id", authorizationOptions.ClientId), new KeyValuePair <string, object>("response_type", "code"), new KeyValuePair <string, object>("scope", string.Join(" ", authorizationOptions.Scopes ?? Enumerable.Empty <string>())), new KeyValuePair <string, object>("show_dialog", authorizationOptions.ShowDialog), new KeyValuePair <string, object>("state", originalCsrfToken), new KeyValuePair <string, object>("redirect_uri", redirectUri) }; if (codeChallenge != null) { queryParams.Add(new KeyValuePair <string, object>("code_challenge_method", "S256")); queryParams.Add(new KeyValuePair <string, object>("code_challenge", codeChallenge)); } var authenticationUriBuilder = new UriBuilder(authorizationOptions.AuthorizationEndpoint) { Query = SpotifyUriUtils.GetQueryString(queryParams) }; var enrichedRedirectUri = await this.authorizationInteractionClient.AuthorizeAsync( authenticationUriBuilder.Uri, redirectUri, cancellationToken).ConfigureAwait(false); var redirectQueryParams = HttpUtility.ParseQueryString(enrichedRedirectUri.Query); var states = redirectQueryParams.GetValues("state") ?? Array.Empty <string>(); if (states.Length != 1 || states.First() != originalCsrfToken) { throw new SpotifyAuthorizationException("Invalid state has been returned from the Spotify Accounts Service."); } var error = redirectQueryParams.GetValues("error")?.FirstOrDefault(); if (!string.IsNullOrEmpty(error)) { throw new SpotifyAuthorizationException($"Error '{error}' has been returned from the Spotify Accounts Service."); } var codes = redirectQueryParams.GetValues("code") ?? Array.Empty <string>(); if (codes.Length != 1 || string.IsNullOrEmpty(codes.First())) { throw new SpotifyAuthorizationException("An invalid authorization code has been returned from the Spotify Accounts Service."); } return(new AuthorizationResult(codes.First(), redirectUri)); }
private string GetCodeChallenge(string codeVerifier) { byte[] hash; using (var sha256 = SHA256.Create()) { hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier)); } return(SpotifyUriUtils.ConvertToBase64UriString(hash)); }
public string Get() { var bytes = new byte[32]; using (var rng = new RNGCryptoServiceProvider()) { rng.GetBytes(bytes); } return(SpotifyUriUtils.ConvertToBase64UriString(bytes)); }
public void ShouldGetRelativeUri() { // Arrange var routeValues = new object[] { "value1", 123, "value?2" }; var queryParams = new List <KeyValuePair <string, object> > { new KeyValuePair <string, object>("key1", "value1"), new KeyValuePair <string, object>("ke 1", new Uri("http://localhost/te%20st?ke%201=test%20value&key2=value2")) }; // Act var result = SpotifyUriUtils.GetRelativeUri(routeValues, queryParams); // Assert result.Should().Be("value1/123/value%3F2?key1=value1&ke%201=http%3A%2F%2Flocalhost%2Fte%2520st%3Fke%25201%3Dtest%2520value%26key2%3Dvalue2"); }
public void ShouldConvertToBase64UriString() { // Arrange + Act + Assert SpotifyUriUtils.ConvertToBase64UriString(Encoding.UTF8.GetBytes("Test")).Should().Be("VGVzdA"); }