예제 #1
0
        /// <summary>Rolls a generic GET request to Atlas</summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        protected async Task <HttpResponseMessage> GetRequest(Uri uri)
        {
            HttpResponseMessage final = null;

            if (uri == null || String.IsNullOrWhiteSpace(uri.AbsoluteUri))
            {
                return(final);
            }

            // setup a new client
            HttpClient client = this.Client(uri);

            // setup the first request
            HttpRequestMessage req1 = new HttpRequestMessage(HttpMethod.Get, uri);

            req1.Headers.Clear();

            // send the 'login' request
            HttpResponseMessage resp1 = await client.SendAsync(req1);

            // at this point we expect a 401 with details for the Authorization header

            // pull apart the auth response
            string        authHeader = resp1.Headers.WwwAuthenticate?.ToString();
            WWWAuthFields header     = this.ParseWWWAuth(authHeader);

            // send a 2nd request with Authorization populated with details from www-authenticate
            HttpRequestMessage req2 = new HttpRequestMessage(HttpMethod.Get, uri);

            req2.Headers.Clear();
            req2.Headers.Add("Authorization", GetDigestHeader(uri.AbsolutePath, header, HttpMethod.Get));
            final = await client.SendAsync(req2);

            return(final);
        }
예제 #2
0
        /// <summary>Pause or resume the specified cluster</summary>
        /// <param name="projID"></param>
        /// <param name="clusterName"></param>
        /// <param name="pause">Pass true to pause the cluster, false to resume the cluster</param>
        /// <returns></returns>
        /// <remarks>PATCH is similar to POST but Pause is the only method using this for now so its not yet broken out</remarks>
        public async Task <AtlasCluster> PauseCluster(string projID, string clusterName, bool pause = false)
        {
            if (String.IsNullOrWhiteSpace(projID) || String.IsNullOrWhiteSpace(clusterName))
            {
                return(null);
            }

            projID      = projID.Trim();
            clusterName = clusterName.Trim();

            Uri uri = new Uri($"{_apiBase}{_dir}/groups/{projID}/clusters/{clusterName}");

            HttpResponseMessage final = null;

            try
            {
                // make a client
                HttpClient client = this.Client(uri);

                // roll the body
                string body = JsonConvert.SerializeObject(new { paused = pause }).ToLower();

                HttpRequestMessage req1 = new HttpRequestMessage(HttpMethod.Patch, uri);
                req1.Headers.Clear();

                // add the body
                req1.Content = new StringContent(body, Encoding.UTF8, "application/json");
                byte[] bytes = Encoding.UTF8.GetBytes(body);
                req1.Content.Headers.Add("Content-Length", bytes.Length.ToString());

                // send the first request
                HttpResponseMessage resp1 = await client.SendAsync(req1);

                // at this point we expect a 401 with details for the Authorization header

                // pull apart the auth response
                string        authHeader = resp1.Headers.WwwAuthenticate?.ToString();
                WWWAuthFields header     = this.ParseWWWAuth(authHeader);

                // send a 2nd request with Authorization populated with details from www-authenticate
                HttpRequestMessage req2 = new HttpRequestMessage(HttpMethod.Patch, uri);
                req2.Headers.Clear();
                req2.Headers.Add("Authorization", this.GetDigestHeader(uri.AbsolutePath, header, HttpMethod.Patch));

                // add the body again
                req2.Content = req1.Content;

                // send the 2nd request
                final = await client.SendAsync(req2);
            }
            catch (System.Exception)
            {
                throw;
            }

            string json = (IsGZipped(final)) ? Decompress(final) : await final.Content.ReadAsStringAsync();

            return(JsonConvert.DeserializeObject <AtlasCluster>(json));
        }
예제 #3
0
        /// <summary>Create an Auth Header Digest</summary>
        /// <remarks>If you continue to use the orginal Auth request you need to increment the nonce value each request</remarks>
        private string GetDigestHeader(string dir, WWWAuthFields header, HttpMethod method)
        {
            // increment on subsequent calls if you re-use
            int nc = 1;

            // create a client nonce
            string cnonce = this.Noncer(8);

            string h1   = $"{_publicKey}:{header.Realm}:{_privateKey}".HashToMD5();
            string h2   = $"{method.ToString().ToUpperInvariant()}:{dir}".HashToMD5();
            string resp = $"{h1}:{header.Nonce}:{nc:00000000}:{cnonce}:{header.QoP}:{h2}".HashToMD5();

            return($"Digest username=\"{_publicKey}\", realm=\"{header.Realm}\", nonce=\"{header.Nonce}\", uri=\"{dir}\", algorithm=MD5, response=\"{resp}\", qop={header.QoP}, nc={nc:00000000}, cnonce=\"{cnonce}\"");
        }
예제 #4
0
        /// <summary>Parses all the WWW Auth Fields to a struct</summary>
        /// <param name="header"></param>
        /// <returns></returns>
        /// <remarks>
        /// Use whatever parsing technique makes you happy. A couple are in StringExtensions
        /// An www auth header will look something like this
        /// Digest realm="MMS Public API", domain="", nonce="kWVA9Ciu7lNaN5QdjPe8kxPMReVjbt+B", algorithm=MD5, qop="auth", stale=false
        /// </remarks>
        private WWWAuthFields ParseWWWAuth(string header)
        {
            WWWAuthFields results = new WWWAuthFields();

            if (String.IsNullOrWhiteSpace(header))
            {
                return(results);
            }

            Dictionary <string, string> dict = header.PairsToDictionary(true);

            results.Realm = (dict.ContainsKey("realm")) ? dict["realm"] : String.Empty;
            results.Nonce = (dict.ContainsKey("nonce")) ? dict["nonce"] : String.Empty;
            results.QoP   = (dict.ContainsKey("qop")) ? dict["qop"] : String.Empty;

            return(results);
        }