Exemple #1
0
        /// <summary>converts a form response stream to a TokenCollection,
        /// by parsing the contents of the stream for newlines and equal signs
        /// the input stream is assumed to be an ascii encoded form resonse
        /// </summary>
        /// <param name="inputStream">the stream to read and parse</param>
        /// <returns> the resulting TokenCollection </returns>
        static public TokenCollection ParseStreamInTokenCollection(Stream inputStream)
        {
            // get the body and parse it
            ASCIIEncoding encoder    = new ASCIIEncoding();
            StreamReader  readStream = new StreamReader(inputStream, encoder);
            String        body       = readStream.ReadToEnd();

            readStream.Close();
            Tracing.TraceMsg("got the following body back: " + body);
            // all we are interested is the token, so we break the string in parts
            TokenCollection tokens = new TokenCollection(body, '=', true, 2);

            return(tokens);
        }
Exemple #2
0
        /////////////////////////////////////////////////////////////////////////////


        //////////////////////////////////////////////////////////////////////
        /// <summary>Event chaining. We catch this by the baseFeedParsers, which
        /// would not do anything with the gathered data. We pass the event up
        /// to the user; if the user doesn't discard it, we add the entry to our
        /// collection</summary>
        /// <param name="sender"> the object which send the event</param>
        /// <param name="e">FeedParserEventArguments, holds the feed entry</param>
        /// <returns> </returns>
        //////////////////////////////////////////////////////////////////////
        protected void OnNewExtensionElement(object sender, ExtensionElementEventArgs e)
        {
            // by default, if our event chain is not hooked, the underlying parser will add it
            Tracing.TraceCall("received new extension element notification");
            Tracing.Assert(e != null, "e should not be null");
            if (e == null)
            {
                throw new ArgumentNullException("e");
            }
            if (this.NewExtensionElement != null)
            {
                Tracing.TraceMsg("\t calling event dispatcher");
                this.NewExtensionElement(sender, e);
            }
        }
Exemple #3
0
        /////////////////////////////////////////////////////////////////////////////


        //////////////////////////////////////////////////////////////////////
        /// <summary>Event chaining. We catch this by the baseFeedParsers, which
        /// would not do anything with the gathered data. We pass the event up
        /// to the user; if the user doesn't discard it, we add the entry to our
        /// collection</summary>
        /// <param name="sender"> the object which send the event</param>
        /// <param name="e">FeedParserEventArguments, holds the feed entry</param>
        /// <returns> </returns>
        //////////////////////////////////////////////////////////////////////
        protected void OnParsedNewEntry(object sender, FeedParserEventArgs e)
        {
            // by default, if our event chain is not hooked, add it to the collection
            Tracing.TraceCall("received new item notification");
            Tracing.Assert(e != null, "e should not be null");
            if (e == null)
            {
                throw new ArgumentNullException("e");
            }
            if (this.NewAtomEntry != null)
            {
                Tracing.TraceMsg("\t calling event dispatcher");
                this.NewAtomEntry(this, e);
            }
            // now check the return
            if (!e.DiscardEntry)
            {
                if (!e.CreatingEntry)
                {
                    if (e.Entry != null)
                    {
                        // add it to the collection
                        Tracing.TraceMsg("\t new AtomEntry found, adding to collection");
                        e.Entry.Service = this.Service;
                        this.Entries.Add(e.Entry);
                    }
                    else if (e.Feed != null)
                    {
                        // parsed a feed, set ourselves to it...
                        Tracing.TraceMsg("\t Feed parsed found, parsing is done...");
                    }
                }
                else
                {
                    IVersionAware v = e.Entry as IVersionAware;
                    if (v != null)
                    {
                        v.ProtocolMajor = this.ProtocolMajor;
                        v.ProtocolMinor = this.ProtocolMinor;
                    }
                }
            }

            if (e.DoneParsing)
            {
                this.BaseUriChanged(this.ImpliedBase);
            }
        }
        /// <summary>checks if this is a namespace
        /// declaration that we already added</summary>
        /// <param name="node">XmlNode to check</param>
        /// <returns>true if this node should be skipped </returns>
        protected override bool SkipNode(XmlNode node)
        {
            if (base.SkipNode(node))
            {
                return(true);
            }

            Tracing.TraceMsg("in skipnode for node: " + node.Name + "--" + node.Value);
            if (this.BatchData != null)
            {
                if (node.NodeType == XmlNodeType.Attribute &&
                    node.Name.StartsWith("xmlns") &&
                    (String.Compare(node.Value, BaseNameTable.gBatchNamespace) == 0))
                {
                    return(true);
                }
            }
            return(false);
        }
Exemple #5
0
        //////////////////////////////////////////////////////////////////////
        /// <summary>Retrieves information about the AuthSub token.
        /// If the <code>key</code> is non-null, the token will be used securely
        /// and the request to revoke the token will be signed.
        /// </summary>
        /// <param name="protocol">the protocol to use to communicate with the server</param>
        /// <param name="domain">the domain at which the authentication server exists</param>
        /// <param name="token">tthe AuthSub token for which to receive information </param>
        /// <param name="key">the private key to sign the request</param>
        /// <returns>the token information in the form of a Dictionary from the name of the
        ///  attribute to the value of the attribute</returns>
        //////////////////////////////////////////////////////////////////////
        public static Dictionary <String, String> GetTokenInfo(String protocol,
                                                               String domain,
                                                               String token,
                                                               AsymmetricAlgorithm key)
        {
            HttpWebResponse response;

            try
            {
                string tokenInfoUrl = GetTokenInfoUrl(protocol, domain);
                Uri    uri          = new Uri(tokenInfoUrl);

                HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;


                string header = formAuthorizationHeader(token, key, uri, "GET");
                request.Headers.Add(header);

                response = request.GetResponse() as HttpWebResponse;
            }
            catch (WebException e)
            {
                Tracing.TraceMsg("GetTokenInfo failed " + e.Status);
                throw new GDataRequestException("Execution of GetTokenInfo", e);
            }

            if (response != null)
            {
                int code = (int)response.StatusCode;
                if (code != 200)
                {
                    throw new GDataRequestException("Execution of revokeToken request returned unexpected result: " + code, response);
                }
                TokenCollection tokens = Utilities.ParseStreamInTokenCollection(response.GetResponseStream());
                if (tokens != null)
                {
                    return(tokens.CreateDictionary());
                }
            }
            return(null);
        }
Exemple #6
0
        //end of public static String exchangeForSessionToken(String onetimeUseToken, PrivateKey key)



        //////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Exchanges the one time use token returned in the URL for a session
        /// token. If the key is non-null, the token will be used securely,
        /// and the request will be signed
        /// </summary>
        /// <param name="protocol">the protocol to use to communicate with the
        /// server</param>
        /// <param name="domain">the domain at which the authentication server
        /// exists</param>
        /// <param name="onetimeUseToken">the token send by google in the URL</param>
        /// <param name="key">the private key used to sign</param>
        /// <returns>the session token</returns>
        //////////////////////////////////////////////////////////////////////
        public static string exchangeForSessionToken(string protocol,
                                                     string domain,
                                                     string onetimeUseToken,
                                                     AsymmetricAlgorithm key)
        {
            HttpWebResponse response     = null;
            string          authSubToken = null;

            try
            {
                string sessionUrl = getSessionTokenUrl(protocol, domain);
                Uri    uri        = new Uri(sessionUrl);

                HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;


                string header = formAuthorizationHeader(onetimeUseToken, key, uri, "GET");
                request.Headers.Add(header);

                response = request.GetResponse() as HttpWebResponse;
            }
            catch (WebException e)
            {
                Tracing.TraceMsg("exchangeForSessionToken failed " + e.Status);
                throw new GDataRequestException("Execution of exchangeForSessionToken", e);
            }
            if (response != null)
            {
                int code = (int)response.StatusCode;
                if (code != 200)
                {
                    throw new GDataRequestException("Execution of exchangeForSessionToken request returned unexpected result: " + code, response);
                }
                // get the body and parse it
                authSubToken = Utilities.ParseValueFormStream(response.GetResponseStream(), GoogleAuthentication.AuthSubToken);
            }

            Tracing.Assert(authSubToken != null, "did not find an auth token in exchangeForSessionToken");

            return(authSubToken);
        }
        /// <summary>
        /// Parses the inner state of the element
        /// </summary>
        /// <param name="e">The extension element that should be added to this entry</param>
        /// <param name="parser">The AtomFeedParser that called this</param>
        public virtual void Parse(ExtensionElementEventArgs e, AtomFeedParser parser)
        {
            if (e == null)
            {
                throw new ArgumentNullException("e");
            }

            Tracing.TraceMsg("Entering Parse on AbstractEntry");
            XmlNode node = e.ExtensionElement;

            if (this.ExtensionFactories != null && this.ExtensionFactories.Count > 0)
            {
                Tracing.TraceMsg("Entring default Parsing for AbstractEntry");

                IExtensionElementFactory f = FindExtensionFactory(node.LocalName,
                                                                  node.NamespaceURI);
                if (f != null)
                {
                    this.ExtensionElements.Add(f.CreateInstance(node, parser));
                    e.DiscardEntry = true;
                }
            }
        }
Exemple #8
0
        //end of private static string generateULONGRnd()



        //////////////////////////////////////////////////////////////////////
        /// <summary>signs the data with the given key</summary>
        /// <param name="dataToSign">the data to sign </param>
        /// <param name="key">the private key to used </param>
        /// <returns> the signed data</returns>
        //////////////////////////////////////////////////////////////////////
        private static byte[] sign(string dataToSign, AsymmetricAlgorithm key)
        {
            byte[] data = new ASCIIEncoding().GetBytes(dataToSign);

            try
            {
                RSACryptoServiceProvider providerRSA = key as RSACryptoServiceProvider;
                if (providerRSA != null)
                {
                    return(providerRSA.SignData(data, new SHA1CryptoServiceProvider()));
                }
                DSACryptoServiceProvider providerDSA = key as DSACryptoServiceProvider;
                if (providerDSA != null)
                {
                    return(providerDSA.SignData(data));
                }
            }
            catch (CryptographicException e)
            {
                Tracing.TraceMsg(e.Message);
            }
            return(null);
        }
Exemple #9
0
        /// <summary>public WebResponse Insert(Uri insertUri, Stream entryStream, ICredentials credentials)</summary>
        /// <param name="feed">the feed this entry should be inserted into</param>
        /// <param name="entry">the entry to be inserted</param>
        /// <returns> the inserted entry</returns>
        AtomEntry IService.Insert(AtomFeed feed, AtomEntry entry)
        {
            Tracing.Assert(feed != null, "feed should not be null");
            if (feed == null)
            {
                throw new ArgumentNullException("feed");
            }

            Tracing.Assert(entry != null, "entry should not be null");
            if (entry == null)
            {
                throw new ArgumentNullException("entry");
            }

            if (feed.ReadOnly)
            {
                throw new GDataRequestException("Can not update a read-only feed");
            }

            Tracing.TraceMsg("Post URI is: " + feed.Post);
            Uri target = new Uri(feed.Post);

            return(Insert(target, entry));
        }
Exemple #10
0
        ///<summary>Deletes an Atom entry when given a Uri</summary>
        ///<param name="uriTarget">The target Uri to call http delete against</param>
        ///<param name="eTag">The eTag of the item to delete. This parameter is used for strong
        /// concurrency support in protocol version 2 and up</param>
        public void Delete(Uri uriTarget, string eTag)
        {
            Tracing.Assert(uriTarget != null, "uri should not be null");
            if (uriTarget == null)
            {
                throw new ArgumentNullException("uriTarget");
            }

            Tracing.TraceMsg("Deleting entry: " + uriTarget.ToString());
            IGDataRequest request = RequestFactory.CreateRequest(GDataRequestType.Delete, uriTarget);

            ISupportsEtag eTarget = request as ISupportsEtag;

            if (eTarget != null && eTag != null)
            {
                eTarget.Etag = eTag;
            }

            request.Credentials = Credentials;
            request.Execute();
            IDisposable disp = request as IDisposable;

            disp.Dispose();
        }
Exemple #11
0
        /// <summary>
        /// event on the Feed to handle extension elements during parsing
        /// </summary>
        /// <param name="e">the event arguments</param>
        /// <param name="parser">the parser that caused this</param>
        protected virtual void HandleExtensionElements(ExtensionElementEventArgs e, AtomFeedParser parser)
        {
            Tracing.TraceMsg("Entering HandleExtensionElements on AbstractFeed");
            XmlNode node = e.ExtensionElement;

            if (this.ExtensionFactories != null && this.ExtensionFactories.Count > 0)
            {
                Tracing.TraceMsg("Entring default Parsing for AbstractFeed");
                foreach (IExtensionElementFactory f in this.ExtensionFactories)
                {
                    Tracing.TraceMsg("Found extension Factories");
                    if (String.Compare(node.NamespaceURI, f.XmlNameSpace, true, CultureInfo.InvariantCulture) == 0)
                    {
                        if (String.Compare(node.LocalName, f.XmlName, true, CultureInfo.InvariantCulture) == 0)
                        {
                            e.Base.ExtensionElements.Add(f.CreateInstance(node, parser));
                            e.DiscardEntry = true;
                            break;
                        }
                    }
                }
            }
            return;
        }
Exemple #12
0
        /// <summary>saves the inner state of the element</summary>
        /// <param name="writer">the xmlWriter to save into </param>
        protected override void SaveInnerXml(XmlWriter writer)
        {
            // saving title
            Tracing.TraceMsg("Entering save inner XML on AtomEntry");

            if (this.batchData != null)
            {
                this.batchData.Save(writer);
            }

            if (this.title != null)
            {
                Tracing.TraceMsg("Saving Title: " + this.Title.Text);
                this.Title.SaveToXml(writer);
            }

            if (this.id != null)
            {
                this.Id.SaveToXml(writer);
            }

            foreach (AtomLink link in this.Links)
            {
                link.SaveToXml(writer);
            }

            foreach (AtomPerson person in this.Authors)
            {
                person.SaveToXml(writer);
            }

            foreach (AtomPerson person in this.Contributors)
            {
                person.SaveToXml(writer);
            }

            foreach (AtomCategory category in this.Categories)
            {
                category.SaveToXml(writer);
            }

            if (this.rights != null)
            {
                this.Rights.SaveToXml(writer);
            }

            if (this.summary != null)
            {
                this.Summary.SaveToXml(writer);
            }

            if (this.content != null)
            {
                this.Content.SaveToXml(writer);
            }

            if (this.source != null)
            {
                this.Source.SaveToXml(writer);
            }

            WriteLocalDateTimeElement(writer, AtomParserNameTable.XmlUpdatedElement, this.Updated);
            WriteLocalDateTimeElement(writer, AtomParserNameTable.XmlPublishedElement, this.Published);
        }
        /// <summary>Executes the request and prepares the response stream. Also
        /// does error checking</summary>
        public virtual void Execute()
        {
            try
            {
                EnsureWebRequest();
                // if we ever handed out a stream, we want to close it before doing the real excecution
                if (this.requestStream != null)
                {
                    this.requestStream.Close();
                }

                Tracing.TraceCall("calling the real execution over the webresponse");
                LogRequest(this.webRequest);
                this.webResponse = this.webRequest.GetResponse();
            }
            catch (WebException e)
            {
                Tracing.TraceCall("GDataRequest::Execute failed: " + this.targetUri.ToString());
                GDataRequestException gde = new GDataRequestException("Execution of request failed: " + this.targetUri.ToString(), e);
                throw gde;
            }

            if (this.webResponse != null)
            {
                this.responseStream = this.webResponse.GetResponseStream();
            }

            LogResponse(this.webResponse);
            if (this.webResponse is HttpWebResponse)
            {
                HttpWebResponse response = this.webResponse as HttpWebResponse;
                HttpWebRequest  request  = this.webRequest as HttpWebRequest;

                this.useGZip = (string.Compare(response.ContentEncoding, "gzip", true, CultureInfo.InvariantCulture) == 0);
                if (this.useGZip)
                {
                    this.responseStream = new GZipStream(this.responseStream, CompressionMode.Decompress);
                }

                Tracing.Assert(response != null, "The response should not be NULL");
                Tracing.Assert(request != null, "The request should not be NULL");

                int code = (int)response.StatusCode;

                Tracing.TraceMsg("Returned ContentType is: " + (response.ContentType == null ? "None" : response.ContentType) + " from URI : " + request.RequestUri.ToString());;
                Tracing.TraceMsg("Returned StatusCode is: " + response.StatusCode + code);

                if (response.StatusCode == HttpStatusCode.Forbidden)
                {
                    // that could imply that we need to reauthenticate
                    Tracing.TraceMsg("need to reauthenticate");
                    throw new GDataForbiddenException("Execution of request returned HttpStatusCode.Forbidden: " +
                                                      this.targetUri.ToString() + response.StatusCode.ToString(), this.webResponse);
                }

                if (response.StatusCode == HttpStatusCode.Conflict)
                {
                    // a put went bad due to a version conflict
                    throw new GDataVersionConflictException("Execution of request returned HttpStatusCode.Conflict: " +
                                                            this.targetUri.ToString() + response.StatusCode.ToString(), this.webResponse);
                }

                if ((this.IfModifiedSince != DateTime.MinValue || this.Etag != null) &&
                    response.StatusCode == HttpStatusCode.NotModified)
                {
                    // Throw an exception for conditional GET
                    throw new GDataNotModifiedException("Content not modified: " + this.targetUri.ToString(), this.webResponse);
                }

                if (response.StatusCode == HttpStatusCode.Redirect ||
                    response.StatusCode == HttpStatusCode.Found ||
                    response.StatusCode == HttpStatusCode.RedirectKeepVerb)
                {
                    Tracing.TraceMsg("throwing for redirect");
                    throw new GDataRedirectException("Execution resulted in a redirect from " + this.targetUri.ToString(), this.webResponse);
                }

                if (code > 299)
                {
                    // treat everything else over 300 as errors
                    throw new GDataRequestException("Execution of request returned unexpected result: " + this.targetUri.ToString() +
                                                    response.StatusCode.ToString(), this.webResponse);
                }

                this.contentLength = response.ContentLength;

                // if we got an etag back, remember it
                this.eTag = response.Headers[GDataRequestFactory.EtagHeader];

                response = null;
                request  = null;
            }
        }
Exemple #14
0
 static public void TraceInfo(string msg)
 {
     Tracing.TraceMsg(msg);
 }
Exemple #15
0
        /// <summary>Executes the request and prepares the response stream. Also
        /// does error checking</summary>
        /// <param name="retryCounter">indicates the n-th time this is run</param>
        protected void Execute(int retryCounter)
        {
            Tracing.TraceCall("GoogleAuth: Execution called");
            try
            {
                CopyRequestData();
                base.Execute();
                if (this.Response is HttpWebResponse)
                {
                    HttpWebResponse response = this.Response as HttpWebResponse;
                    this.responseVersion = new VersionInformation(response.Headers[GDataGAuthRequestFactory.GDataVersion]);
                }
            }
            catch (GDataForbiddenException)
            {
                Tracing.TraceMsg("need to reauthenticate, got a forbidden back");
                // do it again, once, reset AuthToken first and streams first
                Reset();
                this.factory.GAuthToken = null;
                CopyRequestData();
                base.Execute();
            }
            catch (GDataRedirectException re)
            {
                // we got a redirect.
                Tracing.TraceMsg("Got a redirect to: " + re.Location);
                // only reset the base, the auth cookie is still valid
                // and cookies are stored in the factory
                if (this.factory.StrictRedirect)
                {
                    HttpWebRequest http = this.Request as HttpWebRequest;
                    if (http != null)
                    {
                        // only redirect for GET, else throw
                        if (http.Method != HttpMethods.Get)
                        {
                            throw;
                        }
                    }
                }

                // verify that there is a non empty location string
                if (re.Location.Trim().Length == 0)
                {
                    throw;
                }

                Reset();
                this.TargetUri = new Uri(re.Location);
                CopyRequestData();
                base.Execute();
            }
            catch (GDataRequestException re)
            {
                HttpWebResponse webResponse = re.Response as HttpWebResponse;
                if (webResponse != null && webResponse.StatusCode != HttpStatusCode.InternalServerError)
                {
                    Tracing.TraceMsg("Not a server error. Possibly a Bad request or forbidden resource.");
                    Tracing.TraceMsg("We don't want to retry non 500 errors.");
                    throw;
                }
                if (retryCounter > this.factory.NumberOfRetries)
                {
                    Tracing.TraceMsg("Number of retries exceeded");
                    throw;
                }
                Tracing.TraceMsg("Let's retry this");
                // only reset the base, the auth cookie is still valid
                // and cookies are stored in the factory
                Reset();
                this.Execute(retryCounter + 1);
            }
            catch (Exception e)
            {
                Tracing.TraceCall("*** EXCEPTION " + e.GetType().Name + " CAUGHT ***");
                throw;
            }
            finally
            {
                if (this.requestCopy != null)
                {
                    this.requestCopy.Close();
                    this.requestCopy = null;
                }
            }
        }
Exemple #16
0
        /// <summary>goes to the Google auth service, and gets a new auth token</summary>
        /// <returns>the auth token, or NULL if none received</returns>
        public static string QueryClientLoginToken(GDataCredentials gc,
                                                   string serviceName,
                                                   string applicationName,
                                                   bool fUseKeepAlive,
                                                   IWebProxy proxyServer,
                                                   Uri clientLoginHandler)
        {
            Tracing.Assert(gc != null, "Do not call QueryAuthToken with no network credentials");
            if (gc == null)
            {
                throw new System.ArgumentNullException("nc", "No credentials supplied");
            }

            HttpWebRequest authRequest = WebRequest.Create(clientLoginHandler) as HttpWebRequest;

            authRequest.KeepAlive = fUseKeepAlive;

            if (proxyServer != null)
            {
                authRequest.Proxy = proxyServer;
            }

            string accountType = GoogleAuthentication.AccountType;

            if (!String.IsNullOrEmpty(gc.AccountType))
            {
                accountType += gc.AccountType;
            }
            else
            {
                accountType += GoogleAuthentication.AccountTypeDefault;
            }

            WebResponse     authResponse = null;
            HttpWebResponse response     = null;

            string authToken = null;

            try
            {
                authRequest.ContentType = HttpFormPost.Encoding;
                authRequest.Method      = HttpMethods.Post;
                ASCIIEncoding encoder = new ASCIIEncoding();

                string user = gc.Username == null ? "" : gc.Username;
                string pwd  = gc.getPassword() == null ? "" : gc.getPassword();

                // now enter the data in the stream
                string postData = GoogleAuthentication.Email + "=" + Utilities.UriEncodeUnsafe(user) + "&";
                postData += GoogleAuthentication.Password + "=" + Utilities.UriEncodeUnsafe(pwd) + "&";
                postData += GoogleAuthentication.Source + "=" + Utilities.UriEncodeUnsafe(applicationName) + "&";
                postData += GoogleAuthentication.Service + "=" + Utilities.UriEncodeUnsafe(serviceName) + "&";
                if (gc.CaptchaAnswer != null)
                {
                    postData += GoogleAuthentication.CaptchaAnswer + "=" + Utilities.UriEncodeUnsafe(gc.CaptchaAnswer) + "&";
                }
                if (gc.CaptchaToken != null)
                {
                    postData += GoogleAuthentication.CaptchaToken + "=" + Utilities.UriEncodeUnsafe(gc.CaptchaToken) + "&";
                }
                postData += accountType;

                byte[] encodedData = encoder.GetBytes(postData);
                authRequest.ContentLength = encodedData.Length;

                Stream requestStream = authRequest.GetRequestStream();
                requestStream.Write(encodedData, 0, encodedData.Length);
                requestStream.Close();
                authResponse = authRequest.GetResponse();
                response     = authResponse as HttpWebResponse;
            }
            catch (WebException e)
            {
                response = e.Response as HttpWebResponse;
                if (response == null)
                {
                    Tracing.TraceMsg("QueryAuthtoken failed " + e.Status + " " + e.Message);
                    throw;
                }
            }

            if (response != null)
            {
                // check the content type, it must be text
                if (!response.ContentType.StartsWith(HttpFormPost.ReturnContentType))
                {
                    throw new GDataRequestException("Execution of authentication request returned unexpected content type: " + response.ContentType, response);
                }

                TokenCollection tokens = Utilities.ParseStreamInTokenCollection(response.GetResponseStream());
                authToken = Utilities.FindToken(tokens, GoogleAuthentication.AuthToken);

                if (authToken == null)
                {
                    throw Utilities.getAuthException(tokens, response);
                }

                // failsafe. if getAuthException did not catch an error...
                int code = (int)response.StatusCode;
                if (code != 200)
                {
                    throw new GDataRequestException("Execution of authentication request returned unexpected result: " + code, response);
                }
            }

            Tracing.Assert(authToken != null, "did not find an auth token in QueryAuthToken");
            if (authResponse != null)
            {
                authResponse.Close();
            }

            return(authToken);
        }