Inheritance: TokenScope
 public VstsMsaAuthentication(
     VstsTokenScope tokenScope,
     ICredentialStore personalAccessTokenStore,
     ITokenStore adaRefreshTokenStore = null)
     : base(tokenScope,
            personalAccessTokenStore,
            adaRefreshTokenStore)
 {
     this.VstsAuthority = new VstsAzureAuthority(DefaultAuthorityHost);
 }
 /// <summary>
 /// Invoked by a derived classes implementation. Allows custom back-end implementations to be used.
 /// </summary>
 /// <param name="tokenScope">The desired scope of the acquired personal access token(s).</param>
 /// <param name="personalAccessTokenStore">The secret store for acquired personal access token(s).</param>
 /// <param name="adaRefreshTokenStore">The secret store for acquired Azure refresh token(s).</param>
 protected BaseVstsAuthentication(
     VstsTokenScope tokenScope,
     ICredentialStore personalAccessTokenStore,
     ITokenStore adaRefreshTokenStore = null)
     : this(tokenScope, personalAccessTokenStore)
 {
     this.AdaRefreshTokenStore = adaRefreshTokenStore ?? this.AdaRefreshTokenStore;
     this.VstsAdalTokenCache = new VstsAdalTokenCache();
     this.VstsIdeTokenCache = new TokenRegistry();
 }
        protected BaseVstsAuthentication(VstsTokenScope tokenScope, ICredentialStore personalAccessTokenStore)
        {
            if (ReferenceEquals(tokenScope, null))
                throw new ArgumentNullException(nameof(TokenScope));
            if (ReferenceEquals(personalAccessTokenStore, null))
                throw new ArgumentNullException(nameof(personalAccessTokenStore));

            this.ClientId = DefaultClientId;
            this.Resource = DefaultResource;
            this.TokenScope = tokenScope;
            this.PersonalAccessTokenStore = personalAccessTokenStore;
            this.VstsAuthority = new VstsAzureAuthority();
        }
        /// <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 BaseVstsAuthentication(VstsTokenScope tokenScope, ICredentialStore personalAccessTokenStore)
        {
            if (tokenScope == null)
                throw new ArgumentNullException("scope", "The `scope` parameter is null or invalid.");
            if (personalAccessTokenStore == null)
                throw new ArgumentNullException("personalAccessTokenStore", "The `personalAccessTokenStore` paramter is null or invalid.");

            AdalTrace.TraceSource.Switch.Level = SourceLevels.Off;
            AdalTrace.LegacyTraceSwitch.Level = TraceLevel.Off;

            this.ClientId = DefaultClientId;
            this.Resource = DefaultResource;
            this.TokenScope = tokenScope;
            this.PersonalAccessTokenStore = personalAccessTokenStore;
            this.AdaRefreshTokenStore = new SecretStore(AdalRefreshPrefx);
            this.VstsAuthority = new VstsAzureAuthority();
        }
 /// <summary>
 ///
 /// </summary>
 /// <param name="tenantId">
 /// <para>The unique identifier for the responsible Azure tenant.</para>
 /// <para>Use <see cref="BaseVstsAuthentication.GetAuthentication"/>
 /// to detect the tenant identity and create the authentication object.</para>
 /// </param>
 /// <param name="tokenScope">The scope of all access tokens acquired by the authority.</param>
 /// <param name="personalAccessTokenStore">The secure secret store for storing any personal
 /// access tokens acquired.</param>
 /// <param name="adaRefreshTokenStore">The secure secret store for storing any Azure tokens
 /// acquired.</param>
 public VstsAadAuthentication(
     Guid tenantId,
     VstsTokenScope tokenScope,
     ICredentialStore personalAccessTokenStore)
     : base(tokenScope, personalAccessTokenStore)
 {
     if (tenantId == Guid.Empty)
     {
         this.VstsAuthority = new VstsAzureAuthority(AzureAuthority.DefaultAuthorityHostUrl);
     }
     else
     {
         // create an authority host URL in the format of https://login.microsoft.com/12345678-9ABC-DEF0-1234-56789ABCDEF0
         string authorityHost = AzureAuthority.GetAuthorityUrl(tenantId);
         this.VstsAuthority = new VstsAzureAuthority(authorityHost);
     }
 }
Esempio n. 7
0
        private static StringContent GetAccessTokenRequestBody(TargetUri targetUri, Token accessToken, VstsTokenScope tokenScope, TimeSpan?duration = null)
        {
            const string ContentBasicJsonFormat = "{{ \"scope\" : \"{0}\", \"targetAccounts\" : [\"{1}\"], \"displayName\" : \"Git: {2} on {3}\" }}";
            const string ContentTimedJsonFormat = "{{ \"scope\" : \"{0}\", \"targetAccounts\" : [\"{1}\"], \"displayName\" : \"Git: {2} on {3}\", \"validTo\": \"{4:u}\" }}";
            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 = (duration.HasValue && duration.Value > TimeSpan.FromHours(1))
                ? string.Format(ContentTimedJsonFormat, tokenScope, accessToken.TargetIdentity, targetUri, Environment.MachineName, DateTime.UtcNow + duration.Value)
                : string.Format(ContentBasicJsonFormat, tokenScope, accessToken.TargetIdentity, targetUri, Environment.MachineName);
            StringContent content = new StringContent(jsonContent, Encoding.UTF8, HttpJsonContentType);

            return(content);
        }
        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;
        }
        /// <summary>
        /// Creates a new authentication broker based for the specified resource.
        /// </summary>
        /// <param name="targetUri">The resource for which authentication is being requested.</param>
        /// <param name="scope">The scope of the access being requested.</param>
        /// <param name="personalAccessTokenStore">Storage container for personal access token secrets.</param>
        /// <param name="adaRefreshTokenStore">Storage container for Azure access token secrets.</param>
        /// <param name="authentication">
        /// An implementation of <see cref="BaseAuthentication"/> if one was detected;
        /// <see langword="null"/> otherwise.
        /// </param>
        /// <returns>
        /// <see langword="true"/> if an authority could be determined; <see langword="false"/> otherwise.
        /// </returns>
        public static BaseAuthentication GetAuthentication(
            TargetUri targetUri,
            VstsTokenScope scope,
            ICredentialStore personalAccessTokenStore)
        {
            BaseSecureStore.ValidateTargetUri(targetUri);
            if (ReferenceEquals(scope, null))
                throw new ArgumentNullException(nameof(scope));
            if (ReferenceEquals(personalAccessTokenStore, null))
                throw new ArgumentNullException(nameof(personalAccessTokenStore));

            BaseAuthentication authentication = null;

            Guid tenantId;
            if (DetectAuthority(targetUri, out tenantId))
            {
                // empty Guid is MSA, anything else is AAD
                if (tenantId == Guid.Empty)
                {
                    Git.Trace.WriteLine("MSA authority detected.");
                    authentication = new VstsMsaAuthentication(scope, personalAccessTokenStore);
                }
                else
                {
                    Git.Trace.WriteLine($"AAD authority for tenant '{tenantId}' detected.");
                    authentication = new VstsAadAuthentication(tenantId, scope, personalAccessTokenStore);
                    (authentication as VstsAadAuthentication).TenantId = tenantId;
                }
            }

            return authentication;
        }
Esempio n. 10
0
 public VstsMsaAuthentication(VstsTokenScope tokenScope, ICredentialStore personalAccessTokenStore)
     : base(tokenScope, personalAccessTokenStore)
 {
     this.VstsAuthority = new VstsAzureAuthority(DefaultAuthorityHost);
 }
Esempio n. 11
0
        /// <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)
        {
            const string AccessTokenHeader = "Bearer";

            Debug.Assert(targetUri != null, "The targetUri parameter is null");
            Debug.Assert(accessToken != null && !String.IsNullOrWhiteSpace(accessToken.Value) && (accessToken.Type == TokenType.Access || accessToken.Type == TokenType.Federated), "The accessToken parameter is null or invalid");
            Debug.Assert(tokenScope != null);

            Trace.WriteLine("VstsAzureAuthority::GeneratePersonalAccessToken");

            try
            {
                // create a `HttpClient` with a minimum number of redirects, default creds, and a reasonable timeout (access token generation seems to hang occasionally)
                using (HttpClientHandler handler = new HttpClientHandler()
                {
                    MaxAutomaticRedirections = 2,
                    UseDefaultCredentials = true
                })
                    using (HttpClient httpClient = new HttpClient(handler)
                    {
                        Timeout = TimeSpan.FromMilliseconds(RequestTimeout)
                    })
                    {
                        httpClient.DefaultRequestHeaders.Add("User-Agent", Global.UserAgent);

                        switch (accessToken.Type)
                        {
                        case TokenType.Access:
                            Trace.WriteLine("   using Azure access token to acquire personal access token");

                            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(AccessTokenHeader, accessToken.Value);
                            break;

                        case TokenType.Federated:
                            Trace.WriteLine("   using federated authentication token to acquire personal access token");

                            httpClient.DefaultRequestHeaders.Add("Cookie", accessToken.Value);
                            break;

                        default:
                            return(null);
                        }

                        if (await PopulateTokenTargetId(targetUri, accessToken))
                        {
                            Uri requestUri;
                            if (TryCreateRequestUri(targetUri, requireCompactToken, out requestUri))
                            {
                                Trace.WriteLine("   request url is " + requestUri);

                                using (StringContent content = GetAccessTokenRequestBody(targetUri, accessToken, tokenScope))
                                    using (HttpResponseMessage response = await httpClient.PostAsync(requestUri, content))
                                    {
                                        if (response.StatusCode == HttpStatusCode.OK)
                                        {
                                            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);

                                                    Trace.WriteLine("   personal access token acquisition succeeded.");

                                                    return(token);
                                                }
                                            }
                                        }
                                    }
                            }
                        }
                    }
            }
            catch
            {
                Trace.WriteLine("   an error occurred.");
            }

            Trace.WriteLine("   personal access token acquisition failed.");

            return(null);
        }
Esempio n. 12
0
        private 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");

            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);
        }
Esempio n. 13
0
        public static bool Find(string value, out VstsTokenScope vstsScope)
        {
            vstsScope = EnumerateValues().FirstOrDefault(v => StringComparer.OrdinalIgnoreCase.Equals(v.Value, value));

            return(vstsScope != null);
        }
Esempio n. 14
0
 public bool Equals(VstsTokenScope other)
 => TokenScope.Equals(this as TokenScope, other as TokenScope);
        /// <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(Uri targetUri, Token accessToken, VstsTokenScope tokenScope, bool requireCompactToken)
        {
            const string TokenAuthHost = "app.vssps.visualstudio.com";
            const string SessionTokenUrl = "https://" + TokenAuthHost + "/_apis/token/sessiontokens?api-version=1.0";
            const string CompactTokenUrl = SessionTokenUrl + "&tokentype=compact";
            const string AccessTokenHeader = "Bearer";

            Debug.Assert(targetUri != null, "The targetUri parameter is null");
            Debug.Assert(accessToken != null && !String.IsNullOrWhiteSpace(accessToken.Value) && (accessToken.Type == TokenType.Access || accessToken.Type == TokenType.Federated), "The accessToken parameter is null or invalid");
            Debug.Assert(tokenScope != null);

            Trace.WriteLine("VstsAzureAuthority::GeneratePersonalAccessToken");

            try
            {
                // create a `HttpClient` with a minimum number of redirects, default creds, and a reasonable timeout (access token generation seems to hang occasionally)
                using (HttpClientHandler handler = new HttpClientHandler()
                {
                    MaxAutomaticRedirections = 2,
                    UseDefaultCredentials = true
                })
                using (HttpClient httpClient = new HttpClient(handler)
                {
                    Timeout = TimeSpan.FromMilliseconds(RequestTimeout)
                })
                {
                    httpClient.DefaultRequestHeaders.Add("User-Agent", Global.GetUserAgent());

                    switch (accessToken.Type)
                    {
                        case TokenType.Access:
                            Trace.WriteLine("   using Azure access token to acquire personal access token");

                            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(AccessTokenHeader, accessToken.Value);
                            break;

                        case TokenType.Federated:
                            Trace.WriteLine("   using federated authentication token to acquire personal access token");

                            httpClient.DefaultRequestHeaders.Add("Cookie", accessToken.Value);
                            break;

                        default:
                            return null;
                    }

                    if (await PopulateTokenTargetId(targetUri, accessToken))
                    {
                        string requestUrl = requireCompactToken ? CompactTokenUrl : SessionTokenUrl;

                        using (StringContent content = GetAccessTokenRequestBody(targetUri, accessToken, tokenScope))
                        using (HttpResponseMessage response = await httpClient.PostAsync(requestUrl, content))
                        {
                            if (response.StatusCode == HttpStatusCode.OK)
                            {
                                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);

                                        Trace.WriteLine("   personal access token aquisition succeeded.");

                                        return token;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch
            {
                Trace.WriteLine("   an error occured error.");
            }

            Trace.WriteLine("   personal access token aquisition failed.");

            return null;
        }
        /// <summary>
        /// Creates a new authentication broker based for the specified resource.
        /// </summary>
        /// <param name="targetUri">The resource for which authentication is being requested.</param>
        /// <param name="scope">The scope of the access being requested.</param>
        /// <param name="personalAccessTokenStore">Storage container for personal access token secrets.</param>
        /// <param name="adaRefreshTokenStore">Storage container for Azure access token secrets.</param>
        /// <param name="authentication">
        /// An implementation of <see cref="BaseAuthentication"/> if one was detected;
        /// <see langword="null"/> otherwise.
        /// </param>
        /// <returns>
        /// <see langword="true"/> if an authority could be determined; <see langword="false"/> otherwise.
        /// </returns>
        public static bool GetAuthentication(
            TargetUri targetUri,
            VstsTokenScope scope,
            ICredentialStore personalAccessTokenStore,
            ITokenStore adaRefreshTokenStore,
            out BaseAuthentication authentication)
        {
            Trace.WriteLine("BaseVstsAuthentication::DetectAuthority");

            Guid tenantId;
            if (DetectAuthority(targetUri, out tenantId))
            {
                // empty Guid is MSA, anything else is AAD
                if (tenantId == Guid.Empty)
                {
                    Trace.WriteLine("   MSA authority detected");
                    authentication = new VstsMsaAuthentication(scope, personalAccessTokenStore, adaRefreshTokenStore);
                }
                else
                {
                    Trace.WriteLine("   AAD authority for tenant '" + tenantId + "' detected");
                    authentication = new VstsAadAuthentication(tenantId, scope, personalAccessTokenStore, adaRefreshTokenStore);
                    (authentication as VstsAadAuthentication).TenantId = tenantId;
                }
            }
            else
            {
                authentication = null;
            }

            return authentication != null;
        }
        public async Task <Token> GeneratePersonalAccessToken(TargetUri targetUri, Token authorization, VstsTokenScope tokenScope, bool requireCompactToken, TimeSpan?tokenDuration = null)
        {
            if (targetUri is null)
            {
                throw new ArgumentNullException(nameof(targetUri));
            }
            if (authorization is null)
            {
                throw new ArgumentNullException(nameof(authorization));
            }
            if (tokenScope is null)
            {
                throw new ArgumentNullException(nameof(tokenScope));
            }

            try
            {
                var requestUri = await CreatePersonalAccessTokenRequestUri(targetUri, authorization, requireCompactToken);

                var options = new NetworkRequestOptions(true)
                {
                    Authorization = authorization,
                };

                using (StringContent content = GetAccessTokenRequestBody(targetUri, tokenScope, tokenDuration))
                    using (var response = await Network.HttpPostAsync(requestUri, content, options))
                    {
                        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);

                                    Trace.WriteLine($"personal access token acquisition for '{targetUri}' succeeded.");

                                    return(token);
                                }
                            }
                        }

                        Trace.WriteLine($"failed to acquire personal access token for '{targetUri}' [{(int)response.StatusCode} {response.ReasonPhrase}].");
                    }
            }
            catch (Exception exception)
            {
                Trace.WriteException(exception);
            }

            Trace.WriteLine($"personal access token acquisition for '{targetUri}' failed.");

            return(null);
        }
        /// <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);
        }
Esempio n. 19
0
        private StringContent GetAccessTokenRequestBody(TargetUri targetUri, Token accessToken, VstsTokenScope tokenScope, TimeSpan?duration = null)
        {
            const string ContentBasicJsonFormat = "{{ \"scope\" : \"{0}\", \"targetAccounts\" : [\"{1}\"], \"displayName\" : \"Git: {2} on {3}\" }}";
            const string ContentTimedJsonFormat = "{{ \"scope\" : \"{0}\", \"targetAccounts\" : [\"{1}\"], \"displayName\" : \"Git: {2} on {3}\", \"validTo\": \"{4:u}\" }}";
            const string HttpJsonContentType    = "application/json";

            if (accessToken is null)
            {
                throw new ArgumentNullException(nameof(accessToken));
            }
            if (tokenScope is null)
            {
                throw new ArgumentNullException(nameof(tokenScope));
            }

            Trace.WriteLine($"creating access token scoped to '{tokenScope}' for '{accessToken.TargetIdentity}'");

            string jsonContent = (duration.HasValue && duration.Value > TimeSpan.FromHours(1))
                ? string.Format(ContentTimedJsonFormat, tokenScope, accessToken.TargetIdentity, targetUri, Environment.MachineName, DateTime.UtcNow + duration.Value)
                : string.Format(ContentBasicJsonFormat, tokenScope, accessToken.TargetIdentity, targetUri, Environment.MachineName);
            StringContent content = new StringContent(jsonContent, Encoding.UTF8, HttpJsonContentType);

            return(content);
        }