Author: fmantek
Date: Fri Mar 23 06:47:53 2007
New Revision: 117
Added:
trunk/clients/cs/src/core/authexceptions.cs
trunk/clients/cs/src/unittests/authtest.cs
Modified:
trunk/clients/cs/RELEASE_NOTES.txt
trunk/clients/cs/src/VS2003/gdata/gdata.csproj
trunk/clients/cs/src/VS2005.mobile/GDataMobile/GDataMobile.csproj
trunk/clients/cs/src/core/gauthrequest.cs
trunk/clients/cs/src/core/utilities.cs
trunk/clients/cs/src/unittests/caltest.cs
Log:
- added Captcha Handling and more detailed exceptions when the authentication
request fails. See authexceptions.cs for the list of potential exceptions
thrown
Modified: trunk/clients/cs/RELEASE_NOTES.txt
==============================================================================
--- trunk/clients/cs/RELEASE_NOTES.txt (original)
+++ trunk/clients/cs/RELEASE_NOTES.txt Fri Mar 23 06:47:53 2007
@@ -8,6 +8,9 @@
- fixed an issue with the edit/self uris on the entry. They were not correctly
setable.
- fixed an issue that one you used an authenticated service, but did not
supply credentials, we would send
an empty authentication header.
+- added Captcha Handling and more detailed exceptions when the authentication
+ request fails. See authexceptions.cs for the list of potential exceptions
thrown
+- added some preliminary unittests for the new exceptions
== 1.0.9.4 ==
- Google Base: fix for incorrect Price attribute behaviour
Modified: trunk/clients/cs/src/VS2003/gdata/gdata.csproj
==============================================================================
--- trunk/clients/cs/src/VS2003/gdata/gdata.csproj (original)
+++ trunk/clients/cs/src/VS2003/gdata/gdata.csproj Fri Mar 23 06:47:53 2007
@@ -197,6 +197,12 @@
SubType = "Code"
BuildAction = "Compile"
/>
+ <File
+ RelPath = "authexceptions.cs"
+ Link = "..\..\core\authexceptions.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
<File
RelPath = "authsubutil.cs"
Link = "..\..\core\authsubutil.cs"
Modified: trunk/clients/cs/src/VS2005.mobile/GDataMobile/GDataMobile.csproj
==============================================================================
--- trunk/clients/cs/src/VS2005.mobile/GDataMobile/GDataMobile.csproj
(original)
+++ trunk/clients/cs/src/VS2005.mobile/GDataMobile/GDataMobile.csproj Fri Mar
23 06:47:53 2007
@@ -126,7 +126,10 @@
<Compile Include="..\..\core\feedquery.cs">
<Link>feedquery.cs</Link>
</Compile>
- <Compile Include="..\..\core\gauthrequest.cs">
+ <Compile Include="..\..\core\gauthexceptions.cs">
+ <Link>gauthexceptions.cs</Link>
+ </Compile>
+ <Compile Include="..\..\core\gauthrequest.cs">
<Link>gauthrequest.cs</Link>
</Compile>
<Compile Include="..\..\core\gdatabatch.cs">
Added: trunk/clients/cs/src/core/authexceptions.cs
==============================================================================
--- (empty file)
+++ trunk/clients/cs/src/core/authexceptions.cs Fri Mar 23 06:47:53 2007
@@ -0,0 +1,180 @@
+/* Copyright (c) 2006 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+#region Using directives
+
+#define USE_TRACING
+#define USE_LOGGING
+
+using System;
+using System.Xml;
+using System.Net;
+using System.Diagnostics;
+#if WindowsCE || PocketPC
+#else
+using System.Runtime.Serialization;
+#endif
+using System.Security.Permissions;
+using System.IO;
+using System.Text;
+
+
+
+#endregion
+
+
+//////////////////////////////////////////////////////////////////////
+// <summary>custom exceptions</summary>
+//////////////////////////////////////////////////////////////////////
+namespace Google.GData.Client
+{
+
+ //////////////////////////////////////////////////////////////////////
+ /// <summary>standard exception class to be used when authentication
+ /// using Google Client Login fails
+ /// </summary>
+ //////////////////////////////////////////////////////////////////////
+#if WindowsCE || PocketPC
+#else
+ [Serializable]
+#endif
+ public class AuthenticationException : LoggedException
+ {
+ //////////////////////////////////////////////////////////////////////
+ /// <summary>default constructor so that FxCop does not
complain</summary>
+ //////////////////////////////////////////////////////////////////////
+ public AuthenticationException() {}
+
+ /// <summary>
+ /// base constructor, takes a message text
+ /// </summary>
+ /// <param name="msg"></param>
+ public AuthenticationException(String msg) : base(msg) {}
+ }
+
+ /// <summary>thrown when the credentials are wrong</summary>
+ public class InvalidCredentialsException : AuthenticationException
+ {
+ //////////////////////////////////////////////////////////////////////
+ /// <summary>default constructor so that FxCop does not
complain</summary>
+ //////////////////////////////////////////////////////////////////////
+ public InvalidCredentialsException() {}
+ public InvalidCredentialsException(String msg) : base(msg) {}
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ /// <summary>thrown when the account was deleted
+ /// </summary>
+ //////////////////////////////////////////////////////////////////////
+ public class AccountDeletedException : AuthenticationException
+ {
+
//////////////////////////////////////////////////////////////////////
+ /// <summary>default constructor so that FxCop does not
complain</summary>
+
//////////////////////////////////////////////////////////////////////
+ public AccountDeletedException() {}
+ public AccountDeletedException(String msg) : base(msg) {}
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ /// <summary>thrown when the account was disabled
+ /// </summary>
+ //////////////////////////////////////////////////////////////////////
+ public class AccountDisabledException : AuthenticationException
+ {
+
//////////////////////////////////////////////////////////////////////
+ /// <summary>default constructor so that FxCop does not
complain</summary>
+
//////////////////////////////////////////////////////////////////////
+ public AccountDisabledException() {}
+ public AccountDisabledException(String msg) : base(msg) {}
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ /// <summary>the account hoder was not verified
+ /// </summary>
+ //////////////////////////////////////////////////////////////////////
+ public class NotVerifiedException : AuthenticationException
+ {
+
//////////////////////////////////////////////////////////////////////
+ /// <summary>default constructor so that FxCop does not
complain</summary>
+
//////////////////////////////////////////////////////////////////////
+ public NotVerifiedException() {}
+ public NotVerifiedException(String msg) : base(msg) {}
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ /// <summary>The Terms were not agreed with..
+ /// </summary>
+ //////////////////////////////////////////////////////////////////////
+ public class TermsNotAgreedException : AuthenticationException
+ {
+
//////////////////////////////////////////////////////////////////////
+ /// <summary>default constructor so that FxCop does not
complain</summary>
+
//////////////////////////////////////////////////////////////////////
+ public TermsNotAgreedException() {}
+ public TermsNotAgreedException(String msg) : base(msg) {}
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ /// <summary>The service is current not available
+ /// </summary>
+ //////////////////////////////////////////////////////////////////////
+ public class ServiceUnavailableException : AuthenticationException
+ {
+
//////////////////////////////////////////////////////////////////////
+ /// <summary>default constructor so that FxCop does not
complain</summary>
+
//////////////////////////////////////////////////////////////////////
+ public ServiceUnavailableException() {}
+ public ServiceUnavailableException(String msg) : base(msg) {}
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ /// <summary>many unsuccessfull logins might create this...
+ /// </summary>
+ //////////////////////////////////////////////////////////////////////
+ public class CaptchaRequiredException : AuthenticationException
+ {
+ protected string captchaUrl;
+ protected string captchaToken;
+
+
//////////////////////////////////////////////////////////////////////
+ /// <summary>default constructor so that FxCop does not
complain</summary>
+
//////////////////////////////////////////////////////////////////////
+ public CaptchaRequiredException() {}
+ public CaptchaRequiredException(String msg, String url, String
token) : base(msg)
+ {
+ this.captchaUrl = url;
+ this.captchaToken = token;
+ }
+
+
+
//////////////////////////////////////////////////////////////////////
+ /// <summary>Read only accessor for captchaUrl</summary>
+
//////////////////////////////////////////////////////////////////////
+ public string Url
+ {
+ get {return this.captchaUrl;}
+ }
+ // end of accessor for captchaUrl
+
+
//////////////////////////////////////////////////////////////////////
+ /// <summary>Read only accessor for captchaToken</summary>
+
//////////////////////////////////////////////////////////////////////
+ public string Token
+ {
+ get {return this.captchaToken;}
+ }
+ // end of accessor for captchaToken
+ }
+
+} ///end of file
//////////////////////////////////////////////////////////////////////////
Modified: trunk/clients/cs/src/core/gauthrequest.cs
==============================================================================
--- trunk/clients/cs/src/core/gauthrequest.cs (original)
+++ trunk/clients/cs/src/core/gauthrequest.cs Fri Mar 23 06:47:53 2007
@@ -37,6 +37,13 @@
//////////////////////////////////////////////////////////////////////
public class GoogleAuthentication
{
+ /// <summary>account prefix path </summary>
+ public const string AccountPrefix = "/accounts";
+
+ /// <summary>protocol </summary>
+ public const string DefaultProtocol = "https";
+ public const string DefaultDomain = "www.google.com";
+
/// <summary>Google client authentication handler</summary>
public const string UriHandler =
"https://www.google.com/accounts/ClientLogin";
/// <summary>Google client authentication email</summary>
@@ -65,6 +72,10 @@
public const string AccountType = "accountType=";
/// <summary>default value for the account type</summary>
public const string AccountTypeDefault = "HOSTED_OR_GOOGLE";
+ /// <summary>captcha url token</summary>
+ public const string CaptchaAnswer = "logincaptcha=";
+ /// <summary>default value for the account type</summary>
+ public const string CaptchaToken = "logintoken=";
}
/////////////////////////////////////////////////////////////////////////////
@@ -84,6 +95,8 @@
private int numberOfRetries; // holds the number of retries the
request will undertake
private bool fStrictRedirect; // indicates if redirects should
be handled strictly
private string accountType; // indicates the accountType to use
+ private string captchaAnswer; // indicates the captcha Answer in
a challenge
+ private string captchaToken; // indicates the captchaToken in a
challenge
@@ -202,8 +215,27 @@
}
+ //////////////////////////////////////////////////////////////////////
+ /// <summary>property to hold the Answer for a challenge</summary>
+ /// <returns> </returns>
+ //////////////////////////////////////////////////////////////////////
+ public string CaptchaAnswer
+ {
+ get {return this.captchaAnswer;}
+ set {this.captchaAnswer = value;}
+ }
+ // end of accessor public string CaptchaUrl
-
+ //////////////////////////////////////////////////////////////////////
+ /// <summary>property to hold the token for a challenge</summary>
+ /// <returns> </returns>
+ //////////////////////////////////////////////////////////////////////
+ public string CaptchaToken
+ {
+ get {return this.captchaToken;}
+ set {this.captchaToken = value;}
+ }
+ // end of accessor public string CaptchaToken
//////////////////////////////////////////////////////////////////////
@@ -415,6 +447,14 @@
postData += GoogleAuthentication.Password + "=" +
Utilities.UriEncodeReserved(nc.Password) + "&";
postData += GoogleAuthentication.Source + "=" +
Utilities.UriEncodeReserved(this.factory.ApplicationName) + "&";
postData += GoogleAuthentication.Service + "=" +
Utilities.UriEncodeReserved(this.factory.Service) + "&";
+ if (this.factory.CaptchaAnswer != null)
+ {
+ postData += GoogleAuthentication.CaptchaAnswer + "=" +
Utilities.UriEncodeReserved(this.factory.CaptchaAnswer) + "&";
+ }
+ if (this.factory.CaptchaToken != null)
+ {
+ postData += GoogleAuthentication.CaptchaToken + "=" +
Utilities.UriEncodeReserved(this.factory.CaptchaToken) + "&";
+ }
postData += accountType;
byte[] encodedData = encoder.GetBytes(postData);
@@ -428,18 +468,13 @@
}
catch (WebException e)
{
- Tracing.TraceMsg("QueryAuthtoken failed " + e.Status);
- throw new GDataRequestException("Execution of authentication
request failed", e);
+ Tracing.TraceMsg("QueryAuthtoken failed " + e.Status + " " +
e.Message);
+ authResponse = e.Response;
}
HttpWebResponse response = authResponse as HttpWebResponse;
if (response != null)
{
- int code= (int)response.StatusCode;
- if (code != 200)
- {
- throw new GDataRequestException("Execution of
authentication request returned unexpected result: " +code, this.Response);
- }
- // check the content type, it must be text
+ // check the content type, it must be text
if (!response.ContentType.StartsWith(HttpFormPost.ContentType))
{
throw new GDataRequestException("Execution of
authentication request returned unexpected content type: " +
response.ContentType, this.Response);
@@ -449,8 +484,20 @@
{
throw new GDataRequestException("Execution of
authentication request returned unexpected large content length: " +
response.ContentLength, this.Response);
}
+ TokenCollection tokens =
Utilities.ParseStreamInTokenCollection(response.GetResponseStream());
+ authToken = Utilities.FindToken(tokens,
GoogleAuthentication.AuthToken);
+
+ if (authToken == null)
+ {
+ throw getAuthException(tokens);
+ }
+ // 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, this.Response);
+ }
- authToken =
Utilities.ParseValueFormStream(response.GetResponseStream(),
GoogleAuthentication.AuthToken);
}
Tracing.Assert(authToken != null, "did not find an auth token in
QueryAuthToken");
if (authResponse != null)
@@ -460,7 +507,62 @@
return authToken;
}
/////////////////////////////////////////////////////////////////////////////
+
+ /// <summary>
+ /// Returns the respective GDataAuthenticationException given the
return
+ /// values from the login URI handler.
+ /// </summary>
+ /// <param name="tokens">The tokencollection of the parsed return
form</param>
+ /// <returns>AuthenticationException</returns>
+ private AuthenticationException getAuthException(TokenCollection
tokens)
+ {
+
+ String errorName = Utilities.FindToken(tokens, "Error");
+
+ if ("BadAuthentication".Equals(errorName))
+ {
+ return new InvalidCredentialsException("Invalid credentials");
+ }
+ else if ("AccountDeleted".Equals(errorName))
+ {
+ return new AccountDeletedException("Account deleted");
+ }
+ else if ("AccountDisabled".Equals(errorName))
+ {
+ return new AccountDisabledException("Account disabled");
+ }
+ else if ("NotVerified".Equals(errorName))
+ {
+ return new NotVerifiedException("Not verified");
+ }
+ else if ("TermsNotAgreed".Equals(errorName))
+ {
+ return new TermsNotAgreedException("Terms not agreed");
+ }
+ else if ("ServiceUnavailable".Equals(errorName))
+ {
+ return new ServiceUnavailableException("Service unavailable");
+ }
+ else if ("CaptchaRequired".Equals(errorName))
+ {
+ String captchaPath = Utilities.FindToken(tokens, "CaptchaUrl");
+ String captchaToken = Utilities.FindToken(tokens,
"CaptchaToken");
+
+ StringBuilder captchaUrl = new StringBuilder();
+
captchaUrl.Append(GoogleAuthentication.DefaultProtocol).Append("://");
+ captchaUrl.Append(GoogleAuthentication.DefaultDomain);
+ captchaUrl.Append(GoogleAuthentication.AccountPrefix);
+ captchaUrl.Append('/').Append(captchaPath);
+ return new CaptchaRequiredException("Captcha required",
+ captchaUrl.ToString(),
+ captchaToken);
+ }
+ else
+ {
+ return new AuthenticationException("Error authenticating
(check service name)");
+ }
+ }
//////////////////////////////////////////////////////////////////////
/// <summary>Executes the request and prepares the response stream.
Also
Modified: trunk/clients/cs/src/core/utilities.cs
==============================================================================
--- trunk/clients/cs/src/core/utilities.cs (original)
+++ trunk/clients/cs/src/core/utilities.cs Fri Mar 23 06:47:53 2007
@@ -371,22 +371,17 @@
/////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
- /// <summary>parses a form response stream in token form for a
specific value
+ /// <summary>searches tokenCollection for a specific NEXT value.
+ /// The collection is assume to be a key/value pair list, so if
<A,B,C,D> is the list
+ /// A and C are keys, B and D are values
/// </summary>
- /// <param name="inputStream">the stream to read and parse</param>
+ /// <param name="tokens">the TokenCollection to search</param>
/// <param name="key">the key to search for</param>
- /// <returns> the string in the tokenized stream </returns>
+ /// <returns> the value string</returns>
//////////////////////////////////////////////////////////////////////
- static public string ParseValueFormStream(Stream inputStream, string
key)
+ static public string FindToken(TokenCollection tokens, string key)
{
string returnValue = null;
- // get the body and parse it
- ASCIIEncoding encoder = new ASCIIEncoding();
- StreamReader readStream = new StreamReader(inputStream, encoder);
- String body = readStream.ReadToEnd();
- readStream.Close();
- // all we are interested is the token, so we break the string in
parts
- TokenCollection tokens = new TokenCollection(body, new char[2]
{'=', '\n'});
bool fNextOne=false;
foreach (string token in tokens )
@@ -406,6 +401,45 @@
return returnValue;
}
/////////////////////////////////////////////////////////////////////////////
+
+
+ //////////////////////////////////////////////////////////////////////
+ /// <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, new char[2]
{'=', '\n'});
+ return tokens;
+ }
+
/////////////////////////////////////////////////////////////////////////////
+
+
//////////////////////////////////////////////////////////////////////
+ /// <summary>parses a form response stream in token form for a
specific value
+ /// </summary>
+ /// <param name="inputStream">the stream to read and parse</param>
+ /// <param name="key">the key to search for</param>
+ /// <returns> the string in the tokenized stream </returns>
+ //////////////////////////////////////////////////////////////////////
+ static public string ParseValueFormStream(Stream inputStream, string
key)
+ {
+ TokenCollection tokens = ParseStreamInTokenCollection(inputStream);
+ return FindToken(tokens, key);
+ }
+
/////////////////////////////////////////////////////////////////////////////
+
+
//////////////////////////////////////////////////////////////////////
/// <summary>returns a blank emptyDate. That's the default for an
empty string date</summary>
Added: trunk/clients/cs/src/unittests/authtest.cs
==============================================================================
--- (empty file)
+++ trunk/clients/cs/src/unittests/authtest.cs Fri Mar 23 06:47:53 2007
@@ -0,0 +1,235 @@
+/* Copyright (c) 2006 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+#define USE_TRACING
+#define DEBUG
+
+using System;
+using System.IO;
+using System.Xml;
+using System.Collections;
+using System.Configuration;
+using System.Net;
+using NUnit.Framework;
+using Google.GData.Client;
+using Google.GData.Extensions;
+using Google.GData.Calendar;
+using Google.GData.Client.UnitTests;
+
+
+
+
+namespace Google.GData.Client.AuthUnitTests
+{
+ [TestFixture]
+ [Category("GoogleAuthenticationTests")]
+ public class AuthenticationTestSuite : BaseTestClass
+ {
+
+ /// <summary>holds the username to use</summary>
+ protected string userName;
+ /// <summary>holds the password to use</summary>
+ protected string passWord;
+
+ /// <summary>holds the default authhandler</summary>
+ protected string strAuthHandler;
+ /// <summary>holds the default UIR to test against</summary>
+ protected string defaultUri;
+
+ //////////////////////////////////////////////////////////////////////
+ /// <summary>default empty constructor</summary>
+ //////////////////////////////////////////////////////////////////////
+ public AuthenticationTestSuite()
+ {
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ /// <summary>the setup method</summary>
+ //////////////////////////////////////////////////////////////////////
+ [SetUp] public override void InitTest()
+ {
+ base.InitTest();
+ GDataGAuthRequestFactory authFactory = this.factory as
GDataGAuthRequestFactory;
+ if (authFactory != null)
+ {
+ authFactory.Handler = this.strAuthHandler;
+ }
+ }
+
/////////////////////////////////////////////////////////////////////////////
+
+ ////////////////////////////////////////////////////////////////////
+ /// <summary>the end it all method</summary>
+ //////////////////////////////////////////////////////////////////////
+ [TearDown] public override void EndTest()
+ {
+ Tracing.ExitTracing();
+ }
+
/////////////////////////////////////////////////////////////////////////////
+
+
+
+ //////////////////////////////////////////////////////////////////////
+ /// <summary>private void ReadConfigFile()</summary>
+ /// <returns> </returns>
+ //////////////////////////////////////////////////////////////////////
+ protected override void ReadConfigFile()
+ {
+ base.ReadConfigFile();
+
+ IDictionary unitTestDictionary = (IDictionary)
ConfigurationSettings.GetConfig("unitTestSection");
+
+ if (unitTestDictionary != null)
+ {
+ if (unitTestDictionary["authHandler"] != null)
+ {
+ this.strAuthHandler = (string)
unitTestDictionary["authHandler"];
+ Tracing.TraceInfo("Read authHandler value: " +
this.strAuthHandler);
+ }
+ if (unitTestDictionary["userName"] != null)
+ {
+ this.userName = (string) unitTestDictionary["userName"];
+ Tracing.TraceInfo("Read userName value: " +
this.userName);
+ }
+ if (unitTestDictionary["passWord"] != null)
+ {
+ this.passWord = (string) unitTestDictionary["passWord"];
+ Tracing.TraceInfo("Read passWord value: " +
this.passWord);
+ }
+
+ if (unitTestDictionary["calendarURI"] != null)
+ {
+ this.defaultUri = (string)
unitTestDictionary["calendarURI"];
+ Tracing.TraceInfo("Read default URI value: " +
this.defaultUri);
+ }
+
+ }
+ }
+
/////////////////////////////////////////////////////////////////////////////
+
+
+
+ //////////////////////////////////////////////////////////////////////
+ /// <summary>runs an authentication test</summary>
+ //////////////////////////////////////////////////////////////////////
+ [Test] public void PositiveTest()
+ {
+ Tracing.TraceMsg("Entering PositiveTest");
+
+ FeedQuery query = new FeedQuery();
+ Service service = new Service();
+
+ if (this.defaultUri != null)
+ {
+ if (this.userName != null)
+ {
+ NetworkCredential nc = new
NetworkCredential(this.userName, this.passWord);
+ service.Credentials = nc;
+ }
+
+ GDataLoggingRequestFactory factory =
(GDataLoggingRequestFactory) this.factory;
+ factory.MethodOverride = true;
+ service.RequestFactory = this.factory;
+
+ query.Uri = new Uri(this.defaultUri);
+ service.Query(query);
+ service.Credentials = null;
+ factory.MethodOverride = false;
+ }
+ }
+
////////////////////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /// <summary>correct account, invalid password</summary>
+ //////////////////////////////////////////////////////////////////////
+ [Test] public void InvalidCredentialsTest()
+ {
+ Tracing.TraceMsg("Entering InvalidCredentialsTest");
+
+ FeedQuery query = new FeedQuery();
+ Service service = new Service();
+
+ int iCount;
+
+ if (this.defaultUri != null)
+ {
+ if (this.userName != null)
+ {
+ NetworkCredential nc = new
NetworkCredential(this.userName, "wrong");
+ service.Credentials = nc;
+ }
+
+ GDataLoggingRequestFactory factory =
(GDataLoggingRequestFactory) this.factory;
+ factory.MethodOverride = true;
+ service.RequestFactory = this.factory;
+
+ query.Uri = new Uri(this.defaultUri);
+ try
+ {
+ service.Query(query);
+ }
+ catch (InvalidCredentialsException e)
+ {
+ Tracing.TraceMsg("Got the correct Exception");
+ }
+ service.Credentials = null;
+ factory.MethodOverride = false;
+ }
+ }
+
////////////////////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /// <summary>incorrect account</summary>
+ //////////////////////////////////////////////////////////////////////
+ [Test] public void InvalidAccountTest()
+ {
+ Tracing.TraceMsg("Entering InvalidAccountTest");
+
+ FeedQuery query = new FeedQuery();
+ Service service = new Service();
+
+ int iCount;
+
+ if (this.defaultUri != null)
+ {
+ if (this.userName != null)
+ {
+ NetworkCredential nc = new
NetworkCredential(this.userName+"xyz", "wrong");
+ service.Credentials = nc;
+ }
+
+ GDataLoggingRequestFactory factory =
(GDataLoggingRequestFactory) this.factory;
+ factory.MethodOverride = true;
+ service.RequestFactory = this.factory;
+
+ query.Uri = new Uri(this.defaultUri);
+ try
+ {
+ service.Query(query);
+ }
+ catch (InvalidCredentialsException e)
+ {
+ Tracing.TraceMsg("Got the correct Exception");
+ }
+ service.Credentials = null;
+ factory.MethodOverride = false;
+ }
+ }
+
////////////////////////////////////////////////////////////////////////////
+
+ }
/////////////////////////////////////////////////////////////////////////////
+}
+
+
+
+
Modified: trunk/clients/cs/src/unittests/caltest.cs
==============================================================================
--- trunk/clients/cs/src/unittests/caltest.cs (original)
+++ trunk/clients/cs/src/unittests/caltest.cs Fri Mar 23 06:47:53 2007
@@ -32,6 +32,7 @@
namespace Google.GData.Client.UnitTests
{
[TestFixture]
+ [Category("GoogleCalendar")]
public class CalendarTestSuite : BaseTestClass
{
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Google Data API" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/google-help-dataapi?hl=en
-~----------~----~----~----~------~----~------~--~---