public OAuthMessageHandler(HttpMessageHandler innerHandler, IHmacSha1HashProvider hashProvider, string consumerKey, string consumerSecret, Token oAuthToken) : base(innerHandler) { if (hashProvider == null) throw new ArgumentNullException("hashProvider"); if (consumerKey == null) throw new ArgumentNullException("consumerKey"); if (consumerKey.Length == 0) throw new ArgumentException("Consumer key cannot be empty.", "consumerKey"); if (consumerSecret == null) throw new ArgumentNullException("consumerSecret"); if (consumerSecret.Length == 0) throw new ArgumentException("Consumer secret cannot be empty.", "consumerSecret"); if(oAuthToken != null && !oAuthToken.IsValid) throw new ArgumentException("OAuth token is not valid.", "oAuthToken"); if (consumerKey == null) throw new ArgumentNullException("consumerKey"); this.hashProvider = hashProvider; this.consumerKey = consumerKey; this.consumerSecret = consumerSecret; this.oAuthToken = oAuthToken; }
private static string GetToken(Token token) { if (token != null && !string.IsNullOrEmpty(token.Key)) { return string.Format("oauth_token=\"{0}\",", token.Key); } return ""; }
private static string GetConsumerKey(Token consumerToken) { string consumerKey = null; if (consumerToken != null) { consumerKey = consumerToken.Key; } return string.Format("oauth_consumer_key=\"{0}\",", consumerToken.Key); }
public OAuthAuthenticator(Token consumerToken, Token oauthToken, string oauthVerifier) { if (consumerToken == null || string.IsNullOrEmpty(consumerToken.Key) || string.IsNullOrEmpty(consumerToken.Secret)) { throw new ArgumentException("Consumer token or on of its properties can't be null or empty"); } _consumerToken = consumerToken; OAuthToken = oauthToken; OAuthVerifier = oauthVerifier; }
/// <summary> /// Generates a personal access token for use with Visual Studio Online. /// </summary> /// <param name="targetUri"> /// The uniform resource indicator of the resource access tokens are being requested for. /// </param> /// <param name="accessToken"></param> /// <param name="tokenScope"></param> /// <param name="requireCompactToken"></param> /// <returns></returns> public async Task<Token> GeneratePersonalAccessToken(TargetUri targetUri, Token accessToken, VstsTokenScope tokenScope, bool requireCompactToken) { BaseSecureStore.ValidateTargetUri(targetUri); BaseSecureStore.ValidateToken(accessToken); if (ReferenceEquals(tokenScope, null)) throw new ArgumentNullException(nameof(tokenScope)); try { using (HttpClient httpClient = CreateHttpClient(targetUri, accessToken)) { if (await PopulateTokenTargetId(targetUri, accessToken)) { Uri requestUri = await CreatePersonalAccessTokenRequestUri(httpClient, targetUri, requireCompactToken); using (StringContent content = GetAccessTokenRequestBody(targetUri, accessToken, tokenScope)) using (HttpResponseMessage response = await httpClient.PostAsync(requestUri, content)) { if (response.IsSuccessStatusCode) { string responseText = await response.Content.ReadAsStringAsync(); if (!String.IsNullOrWhiteSpace(responseText)) { // find the 'token : <value>' portion of the result content, if any Match tokenMatch = null; if ((tokenMatch = Regex.Match(responseText, @"\s*""token""\s*:\s*""([^\""]+)""\s*", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase)).Success) { string tokenValue = tokenMatch.Groups[1].Value; Token token = new Token(tokenValue, TokenType.Personal); Git.Trace.WriteLine($"personal access token acquisition for '{targetUri}' succeeded."); return token; } } } } } } } catch { Git.Trace.WriteLine("! an error occurred."); } Git.Trace.WriteLine($"personal access token acquisition for '{targetUri}' failed."); return null; }
private static string GetSignature(Token consumerToken, Token token) { string consumerSecret = null; if (consumerToken != null) { consumerSecret = consumerToken.Secret; } string tokenSecret = null; if (token != null) { tokenSecret = token.Secret; } return string.Format("oauth_signature=\"{0}&{1}\",", consumerSecret ?? "", tokenSecret ?? ""); }
private static string GetAuthorizationHeader(Token consumerToken, Token token, string verifier) { var builder = new StringBuilder(); builder.Append("OAuth "); builder.Append(GetConsumerKey(consumerToken)); builder.Append(GetNonce()); builder.Append(GetToken(token)); builder.Append(GetSignature(consumerToken, token)); builder.Append("oauth_signature_method=\"PLAINTEXT\","); builder.Append(GetTimeStamp()); builder.Append(GetVerifier(verifier)); builder.Append("oauth_version=\"1.0\""); return builder.ToString(); }
static bool TryParseElement (Lexer lexer, out TransferCodingWithQualityHeaderValue parsedValue, out Token t) { parsedValue = null; t = lexer.Scan (); if (t != Token.Type.Token) return false; var result = new TransferCodingWithQualityHeaderValue (); result.value = lexer.GetStringValue (t); t = lexer.Scan (); // Parameters parsing if (t == Token.Type.SeparatorSemicolon && (!NameValueHeaderValue.TryParseParameters (lexer, out result.parameters, out t) || t != Token.Type.End)) return false; parsedValue = result; return true; }
public async Task<Token> GetRefreshTokenAsync(Token token) { using (var client = new HttpClient()) { client.DefaultRequestHeaders.Accept.Clear(); var authorizationHeader = Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format("{0}:{1}", ClientId, ClientSecret))); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authorizationHeader); var form = new Dictionary<string, string> { {"grant_type", "refresh_token"}, {"refresh_token", token.RefreshToken} }; var tokenResponse = await client.PostAsync(TokenUrl, new FormUrlEncodedContent(form)); return await tokenResponse.Content.ReadAsAsync<Token>(new[] { new JsonMediaTypeFormatter() }); } }
static bool TryParseElement (Lexer lexer, out MediaTypeWithQualityHeaderValue parsedValue, out Token t) { parsedValue = null; string media; List<NameValueHeaderValue> parameters = null; var token = TryParseMediaType (lexer, out media); if (token == null) { t = Token.Empty; return false; } t = token.Value; if (t == Token.Type.SeparatorSemicolon && (!NameValueHeaderValue.TryParseParameters (lexer, out parameters, out t) || t != Token.Type.End)) return false; parsedValue = new MediaTypeWithQualityHeaderValue (); parsedValue.media_type = media; parsedValue.parameters = parameters; return true; }
static bool TryParseElement (Lexer lexer, out ProductHeaderValue parsedValue, out Token t) { parsedValue = null; t = lexer.Scan (); if (t != Token.Type.Token) return false; parsedValue = new ProductHeaderValue (); parsedValue.Name = lexer.GetStringValue (t); t = lexer.Scan (); if (t == Token.Type.SeparatorSlash) { t = lexer.Scan (); if (t != Token.Type.Token) return false; parsedValue.Version = lexer.GetStringValue (t); t = lexer.Scan (); } return true; }
protected void GetNextStringOrRelType() { NextToken = ReadNextStringOrRelType(); }
internal static bool TryParseParameters (Lexer lexer, out List<NameValueHeaderValue> result, out Token t) { var list = new List<NameValueHeaderValue> (); result = null; while (true) { var attr = lexer.Scan (); if (attr != Token.Type.Token) { t = Token.Empty; return false; } string value = null; t = lexer.Scan (); if (t == Token.Type.SeparatorEqual) { t = lexer.Scan (); if (t != Token.Type.Token && t != Token.Type.QuotedString) return false; value = lexer.GetStringValue (t); t = lexer.Scan (); } list.Add (new NameValueHeaderValue () { Name = lexer.GetStringValue (attr), value = value }); if (t == Token.Type.SeparatorSemicolon) continue; result = list; return true; } }
static bool TryParseElement (Lexer lexer, out NameValueHeaderValue parsedValue, out Token t) { parsedValue = null; t = lexer.Scan (); if (t != Token.Type.Token) return false; parsedValue = new NameValueHeaderValue () { Name = lexer.GetStringValue (t), }; t = lexer.Scan (); if (t == Token.Type.SeparatorEqual) { t = lexer.Scan (); if (t == Token.Type.Token || t == Token.Type.QuotedString) { parsedValue.value = lexer.GetStringValue (t); t = lexer.Scan (); } else { return false; } } return true; }
private static StringContent GetAccessTokenRequestBody(TargetUri targetUri, Token accessToken, VstsTokenScope tokenScope) { const string ContentJsonFormat = "{{ \"scope\" : \"{0}\", \"targetAccounts\" : [\"{1}\"], \"displayName\" : \"Git: {2} on {3}\" }}"; const string HttpJsonContentType = "application/json"; Debug.Assert(accessToken != null && (accessToken.Type == TokenType.Access || accessToken.Type == TokenType.Federated), "The accessToken parameter is null or invalid"); Debug.Assert(tokenScope != null, "The tokenScope parameter is null"); Git.Trace.WriteLine($"creating access token scoped to '{tokenScope}' for '{accessToken.TargetIdentity}'"); string jsonContent = String.Format(ContentJsonFormat, tokenScope, accessToken.TargetIdentity, targetUri, Environment.MachineName); StringContent content = new StringContent(jsonContent, Encoding.UTF8, HttpJsonContentType); return content; }
public string GetStringValue(Token token) { return(s.Substring(token.StartPosition, token.EndPosition - token.StartPosition)); }
public bool TryGetDoubleValue (Token token, out double value) { string s = GetStringValue (token); return double.TryParse (s, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out value); }
public bool TryGetDoubleValue(Token token, out double value) { string s = GetStringValue(token); return(double.TryParse(s, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out value)); }
public bool IsStarStringValue (Token token) { return (token.EndPosition - token.StartPosition) == 1 && s[token.StartPosition] == '*'; }
public TimeSpan? TryGetTimeSpanValue (Token token) { int seconds; if (TryGetNumericValue (token, out seconds)) { return TimeSpan.FromSeconds (seconds); } return null; }
public string GetStringValue (Token start, Token end) { return s.Substring (start.StartPosition, end.EndPosition - start.StartPosition); }
public string GetQuotedStringValue(Token start) { return(s.Substring(start.StartPosition + 1, start.EndPosition - start.StartPosition - 2)); }
public bool IsStarStringValue(Token token) { return((token.EndPosition - token.StartPosition) == 1 && s[token.StartPosition] == '*'); }
protected void GetNextToken() { NextToken = ReadToken(); }
public string GetStringValue(Token start, Token end) { return(s.Substring(start.StartPosition, end.EndPosition - start.StartPosition)); }
public OAuthMessageHandler(IHmacSha1HashProvider hashProvider, string consumerKey, string consumerSecret, Token oAuthToken) : this(new HttpClientHandler(), hashProvider, consumerKey, consumerSecret, oAuthToken) { }
public bool TryGetNumericValue(Token token, out long value) { return(long.TryParse(GetStringValue(token), NumberStyles.None, CultureInfo.InvariantCulture, out value)); }
public string GetStringValue (Token token) { return s.Substring (token.StartPosition, token.EndPosition - token.StartPosition); }
public async Task<bool> PopulateTokenTargetId(TargetUri targetUri, Token accessToken) { BaseSecureStore.ValidateTargetUri(targetUri); BaseSecureStore.ValidateToken(accessToken); string resultId = null; Guid instanceId; try { // create an request to the VSTS deployment data end-point HttpWebRequest request = GetConnectionDataRequest(targetUri, accessToken); Git.Trace.WriteLine($"access token end-point is '{request.Method}' '{request.RequestUri}'."); // send the request and wait for the response using (var response = await request.GetResponseAsync()) using (var stream = response.GetResponseStream()) using (var reader = new StreamReader(stream, Encoding.UTF8)) { string content = await reader.ReadToEndAsync(); Match match; if ((match = Regex.Match(content, @"""instanceId""\s*\:\s*""([^""]+)""", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase)).Success && match.Groups.Count == 2) { resultId = match.Groups[1].Value; } } } catch (WebException webException) { Git.Trace.WriteLine($"server returned '{webException.Status}'."); } if (Guid.TryParse(resultId, out instanceId)) { Git.Trace.WriteLine($"target identity is {resultId}."); accessToken.TargetIdentity = instanceId; return true; } return false; }
public string GetQuotedStringValue (Token start) { return s.Substring (start.StartPosition + 1, start.EndPosition - start.StartPosition - 2); }
/// <summary> /// <para>Validates that <see cref="Token"/> are valid to grant access to the Visual Studio /// Online service represented by the <paramref name="targetUri"/> parameter.</para> /// </summary> /// <param name="targetUri">Uniform resource identifier for a VSTS service.</param> /// <param name="token"> /// <see cref="Token"/> expected to grant access to the VSTS service. /// </param> /// <returns>True if successful; otherwise false.</returns> public async Task<bool> ValidateToken(TargetUri targetUri, Token token) { BaseSecureStore.ValidateTargetUri(targetUri); BaseSecureStore.ValidateToken(token); // personal access tokens are effectively credentials, treat them as such if (token.Type == TokenType.Personal) return await this.ValidateCredentials(targetUri, (Credential)token); try { // create an request to the VSTS deployment data end-point HttpWebRequest request = GetConnectionDataRequest(targetUri, token); Git.Trace.WriteLine($"validating token against '{request.Host}'."); // send the request and wait for the response using (HttpWebResponse response = await request.GetResponseAsync() as HttpWebResponse) { // we're looking for 'OK 200' here, anything else is failure Git.Trace.WriteLine($"server returned: '{response.StatusCode}'."); return response.StatusCode == HttpStatusCode.OK; } } catch (WebException webException) { Git.Trace.WriteLine($"! server returned: '{webException.Message}'."); } catch { Git.Trace.WriteLine("! unexpected error"); } Git.Trace.WriteLine($"token validation for '{targetUri}' failed."); return false; }
public bool TryGetNumericValue (Token token, out long value) { return long.TryParse (GetStringValue (token), NumberStyles.None, CultureInfo.InvariantCulture, out value); }
internal static HttpClient CreateHttpClient(TargetUri targetUri, Token accessToken) { const string AccessTokenHeader = "Bearer"; const string FederatedTokenHeader = "Cookie"; Debug.Assert(targetUri != null, $"The `{nameof(targetUri)}` parameter is null."); Debug.Assert(accessToken != null && !String.IsNullOrWhiteSpace(accessToken.Value), $"The `{nameof(accessToken)}' is null or invalid."); HttpClient httpClient = CreateHttpClient(targetUri); switch (accessToken.Type) { case TokenType.Access: httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(AccessTokenHeader, accessToken.Value); break; case TokenType.Federated: httpClient.DefaultRequestHeaders.Add(FederatedTokenHeader, accessToken.Value); break; default: return null; } return httpClient; }
public bool TryGetDateValue (Token token, out DateTimeOffset value) { string text = token == Token.Type.QuotedString ? s.Substring (token.StartPosition + 1, token.EndPosition - token.StartPosition - 2) : GetStringValue (token); return TryGetDateValue (text, out value); }
internal static HttpWebRequest GetConnectionDataRequest(Uri uri, Token token) { const string BearerPrefix = "Bearer "; Debug.Assert(uri != null && uri.IsAbsoluteUri, $"The `{nameof(uri)}` parameter is null or invalid"); Debug.Assert(token != null && (token.Type == TokenType.Access || token.Type == TokenType.Federated), $"The `{nameof(token)}` parameter is null or invalid"); // create an request to the VSTS deployment data end-point HttpWebRequest request = GetConnectionDataRequest(uri); // different types of tokens are packed differently switch (token.Type) { case TokenType.Access: Git.Trace.WriteLine($"validating adal access token for '{uri}'."); // adal access tokens are packed into the Authorization header string sessionAuthHeader = BearerPrefix + token.Value; request.Headers.Add(HttpRequestHeader.Authorization, sessionAuthHeader); break; case TokenType.Federated: Git.Trace.WriteLine($"validating federated authentication token for '{uri}'."); // federated authentication tokens are sent as cookie(s) request.Headers.Add(HttpRequestHeader.Cookie, token.Value); break; default: Git.Trace.WriteLine("! unsupported token type."); break; } return request; }
public bool ScanCommentOptional (out string value, out Token readToken) { readToken = Scan (); if (readToken != Token.Type.OpenParens) { value = null; return false; } int parens = 1; while (pos < s.Length) { var ch = s[pos]; if (ch == '(') { ++parens; ++pos; continue; } if (ch == ')') { ++pos; if (--parens > 0) continue; var start = readToken.StartPosition; value = s.Substring (start, pos - start); return true; } // any OCTET except CTLs, but including LWS if (ch < 32 || ch > 126) break; ++pos; } value = null; return false; }
static bool TryParseElement(Lexer lexer, out WarningHeaderValue parsedValue, out Token t) { parsedValue = null; t = lexer.Scan(); if (t != Token.Type.Token) { return(false); } int code; if (!lexer.TryGetNumericValue(t, out code) || !IsCodeValid(code)) { return(false); } t = lexer.Scan(); if (t != Token.Type.Token) { return(false); } var next = t; if (lexer.PeekChar() == ':') { lexer.EatChar(); next = lexer.Scan(); if (next != Token.Type.Token) { return(false); } } var value = new WarningHeaderValue(); value.Code = code; value.Agent = lexer.GetStringValue(t, next); t = lexer.Scan(); if (t != Token.Type.QuotedString) { return(false); } value.Text = lexer.GetStringValue(t); t = lexer.Scan(); if (t == Token.Type.QuotedString) { DateTimeOffset date; if (!lexer.TryGetDateValue(t, out date)) { return(false); } value.Date = date; t = lexer.Scan(); } parsedValue = value; return(true); }