Merge lp:~mandel/ubuntuone-windows-installer/refactor_sso into lp:ubuntuone-windows-installer/beta

Proposed by Manuel de la Peña
Status: Merged
Approved by: Rick McBride
Approved revision: 88
Merged at revision: 90
Proposed branch: lp:~mandel/ubuntuone-windows-installer/refactor_sso
Merge into: lp:ubuntuone-windows-installer/beta
Prerequisite: lp:~mandel/ubuntuone-windows-installer/re_enable_keyring_tests
Diff against target: 2731 lines (+2118/-397)
21 files modified
src/Canonical.Ubuntu.SSO.Tests/Canonical.Ubuntu.SSO.Tests.csproj (+7/-0)
src/Canonical.Ubuntu.SSO.Tests/ColonSeparatedSSOCredentialsEncoderFixture.cs (+69/-0)
src/Canonical.Ubuntu.SSO.Tests/JsonSSOCredentialsEncoderFixture.cs (+29/-0)
src/Canonical.Ubuntu.SSO.Tests/SSOLoginProcessorFixture.cs (+98/-0)
src/Canonical.Ubuntu.SSO/Canonical.Ubuntu.SSO.csproj (+11/-1)
src/Canonical.Ubuntu.SSO/ColonSeparatedSSOCredentialsEncoder.cs (+60/-0)
src/Canonical.Ubuntu.SSO/DPAPIDataProtector.cs (+0/-1)
src/Canonical.Ubuntu.SSO/IOAuth.cs (+122/-0)
src/Canonical.Ubuntu.SSO/ISSOCredentialsEncoder.cs (+46/-0)
src/Canonical.Ubuntu.SSO/JsonSSOCredentialsEncoder.cs (+82/-0)
src/Canonical.Ubuntu.SSO/OAuth.cs (+391/-0)
src/Canonical.Ubuntu.SSO/OAuthBase.cs (+0/-358)
src/Canonical.Ubuntu.SSO/SSOException.cs (+57/-0)
src/Canonical.Ubuntu.SSO/SSOLoginException.cs (+57/-0)
src/Canonical.Ubuntu.SSO/SSOLoginProcessor.cs (+154/-1)
src/Canonical.UbuntuOne.Client/Notification/NotificationIconPresenter.cs (+25/-36)
src/Canonical.UbuntuOne.Common/Canonical.UbuntuOne.Common.csproj (+4/-0)
src/Canonical.UbuntuOne.Common/Net/HttpWebRequest.cs (+505/-0)
src/Canonical.UbuntuOne.Common/Net/HttpWebRequestFactory.cs (+59/-0)
src/Canonical.UbuntuOne.Common/Net/IHttpWebRequest.cs (+297/-0)
src/Canonical.UbuntuOne.Common/Net/IHttpWebRequestFactory.cs (+45/-0)
To merge this branch: bzr merge lp:~mandel/ubuntuone-windows-installer/refactor_sso
Reviewer Review Type Date Requested Status
Rick McBride (community) Approve
John Lenton (community) Approve
Review via email: mp+37577@code.launchpad.net

Description of the change

SSO has been refactored to make it more testeable and robust.

To post a comment you must log in.
Revision history for this message
John Lenton (chipaca) :
review: Approve
Revision history for this message
Rick McBride (rmcbride) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/Canonical.Ubuntu.SSO.Tests/Canonical.Ubuntu.SSO.Tests.csproj'
--- src/Canonical.Ubuntu.SSO.Tests/Canonical.Ubuntu.SSO.Tests.csproj 2010-10-05 09:58:34 +0000
+++ src/Canonical.Ubuntu.SSO.Tests/Canonical.Ubuntu.SSO.Tests.csproj 2010-10-05 09:58:35 +0000
@@ -48,14 +48,21 @@
48 <Reference Include="System.Xml" />48 <Reference Include="System.Xml" />
49 </ItemGroup>49 </ItemGroup>
50 <ItemGroup>50 <ItemGroup>
51 <Compile Include="ColonSeparatedSSOCredentialsEncoderFixture.cs" />
52 <Compile Include="JsonSSOCredentialsEncoderFixture.cs" />
51 <Compile Include="KeyringFixture.cs" />53 <Compile Include="KeyringFixture.cs" />
52 <Compile Include="Properties\AssemblyInfo.cs" />54 <Compile Include="Properties\AssemblyInfo.cs" />
55 <Compile Include="SSOLoginProcessorFixture.cs" />
53 </ItemGroup>56 </ItemGroup>
54 <ItemGroup>57 <ItemGroup>
55 <ProjectReference Include="..\Canonical.Ubuntu.SSO\Canonical.Ubuntu.SSO.csproj">58 <ProjectReference Include="..\Canonical.Ubuntu.SSO\Canonical.Ubuntu.SSO.csproj">
56 <Project>{9460A771-2589-45DA-9618-9FE8BB7D16E8}</Project>59 <Project>{9460A771-2589-45DA-9618-9FE8BB7D16E8}</Project>
57 <Name>Canonical.Ubuntu.SSO</Name>60 <Name>Canonical.Ubuntu.SSO</Name>
58 </ProjectReference>61 </ProjectReference>
62 <ProjectReference Include="..\Canonical.UbuntuOne.Common\Canonical.UbuntuOne.Common.csproj">
63 <Project>{11353FF8-8E5A-488E-9CB1-873DADD232B9}</Project>
64 <Name>Canonical.UbuntuOne.Common</Name>
65 </ProjectReference>
59 </ItemGroup>66 </ItemGroup>
60 <ItemGroup>67 <ItemGroup>
61 <Folder Include="Service\" />68 <Folder Include="Service\" />
6269
=== added file 'src/Canonical.Ubuntu.SSO.Tests/ColonSeparatedSSOCredentialsEncoderFixture.cs'
--- src/Canonical.Ubuntu.SSO.Tests/ColonSeparatedSSOCredentialsEncoderFixture.cs 1970-01-01 00:00:00 +0000
+++ src/Canonical.Ubuntu.SSO.Tests/ColonSeparatedSSOCredentialsEncoderFixture.cs 2010-10-05 09:58:35 +0000
@@ -0,0 +1,69 @@
1/* Copyright 2010 Canonical Ltd.
2 *
3 * This file is part of UbuntuOne on Windows.
4 *
5 * UbuntuOne on Windows is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License version
7 * as published by the Free Software Foundation.
8 *
9 * Ubuntu One on Windows is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authors: Manuel de la Peña <manuel.delapena@canonical.com>
18 */
19using NUnit.Framework;
20
21namespace Canonical.Ubuntu.SSO.Tests
22{
23 [TestFixture]
24 public class ColonSeparatedSSOCredentialsEncoderFixture
25 {
26 #region Variables
27
28 private ColonSeparatedSSOCredentialsEncoder _encoder;
29
30 #endregion
31
32 #region Setup & TearDown
33
34 [SetUp]
35 public void Setup()
36 {
37 _encoder = new ColonSeparatedSSOCredentialsEncoder();
38 }
39 #endregion
40
41 #region Tests
42
43 [TestCase("firstToken:firstTokenSecret:firstConsumer:firstConsumerSecret", "firstToken", "firstTokenSecret", "firstConsumer", "firstConsumerSecret")]
44 [TestCase("ad180jjd733klru7:hdhd0244k9j7ao03:dpf43f3p2l4k3l03:djr9rjt0jd78jf88%26", "ad180jjd733klru7", "hdhd0244k9j7ao03", "dpf43f3p2l4k3l03", "djr9rjt0jd78jf88%26")]
45 public void EncodeTest(string expected, string token, string tokenSecret, string consumerKey, string consumerSecret)
46 {
47 Assert.AreEqual(expected, _encoder.Encode(token, tokenSecret, consumerKey, consumerSecret));
48 }
49
50 [TestCase("firstToken:firstTokenSecret:firstConsumer:firstConsumerSecret", "firstToken", "firstTokenSecret", "firstConsumer", "firstConsumerSecret")]
51 [TestCase("ad180jjd733klru7:hdhd0244k9j7ao03:dpf43f3p2l4k3l03:djr9rjt0jd78jf88%26", "ad180jjd733klru7", "hdhd0244k9j7ao03", "dpf43f3p2l4k3l03", "djr9rjt0jd78jf88%26")]
52 public void DecodeTest(string secret, string expectedToken, string expectedTokenSecret, string expectedConsumerKey,
53 string expectedConsumerSecret)
54 {
55 string token;
56 string tokenSecret;
57 string consumerKey;
58 string consumerSecret;
59 _encoder.Decode(secret, out token, out tokenSecret, out consumerKey, out consumerSecret);
60 Assert.AreEqual(expectedToken, token);
61 Assert.AreEqual(expectedTokenSecret, tokenSecret);
62 Assert.AreEqual(expectedConsumerKey, consumerKey);
63 Assert.AreEqual(expectedConsumerSecret, consumerSecret);
64 }
65
66 #endregion
67
68 }
69}
070
=== added file 'src/Canonical.Ubuntu.SSO.Tests/JsonSSOCredentialsEncoderFixture.cs'
--- src/Canonical.Ubuntu.SSO.Tests/JsonSSOCredentialsEncoderFixture.cs 1970-01-01 00:00:00 +0000
+++ src/Canonical.Ubuntu.SSO.Tests/JsonSSOCredentialsEncoderFixture.cs 2010-10-05 09:58:35 +0000
@@ -0,0 +1,29 @@
1/* Copyright 2010 Canonical Ltd.
2 *
3 * This file is part of UbuntuOne on Windows.
4 *
5 * UbuntuOne on Windows is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License version
7 * as published by the Free Software Foundation.
8 *
9 * Ubuntu One on Windows is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authors: Manuel de la Peña <manuel.delapena@canonical.com>
18 */
19using System;
20using System.Collections.Generic;
21using System.Linq;
22using System.Text;
23
24namespace Canonical.Ubuntu.SSO.Tests
25{
26 class JsonSSOCredentialsEncoderFixture
27 {
28 }
29}
030
=== added file 'src/Canonical.Ubuntu.SSO.Tests/SSOLoginProcessorFixture.cs'
--- src/Canonical.Ubuntu.SSO.Tests/SSOLoginProcessorFixture.cs 1970-01-01 00:00:00 +0000
+++ src/Canonical.Ubuntu.SSO.Tests/SSOLoginProcessorFixture.cs 2010-10-05 09:58:35 +0000
@@ -0,0 +1,98 @@
1/* Copyright 2010 Canonical Ltd.
2 *
3 * This file is part of UbuntuOne on Windows.
4 *
5 * UbuntuOne on Windows is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License version
7 * as published by the Free Software Foundation.
8 *
9 * Ubuntu One on Windows is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authors: Manuel de la Peña <manuel.delapena@canonical.com>
18 */
19using Canonical.Ubuntu.SSO.Service;
20using Canonical.UbuntuOne.Common.Net;
21using NUnit.Framework;
22using Rhino.Mocks;
23
24namespace Canonical.Ubuntu.SSO.Tests
25{
26 [TestFixture]
27 public class SSOLoginProcessorFixture
28 {
29 #region Variables
30
31 private MockRepository _mocks;
32 private Authentications _auth;
33 private IKeyring _keyring;
34 private ISSOCredentialsEncoder _encode;
35 private IOAuth _oauth;
36 private IHttpWebRequestFactory _requestFactory;
37 private IHttpWebRequest _request;
38 private SSOLoginProcessor _processor;
39
40 #endregion
41
42 #region Setup
43
44 [SetUp]
45 public void Setup()
46 {
47 _mocks = new MockRepository();
48 _auth = _mocks.DynamicMock<Authentications>();
49 _keyring = _mocks.DynamicMock<IKeyring>();
50 _encode = _mocks.DynamicMock<ISSOCredentialsEncoder>();
51 _oauth = _mocks.DynamicMock<IOAuth>();
52 _requestFactory = _mocks.DynamicMock<IHttpWebRequestFactory>();
53 _request = _mocks.DynamicMock<IHttpWebRequest>();
54 _processor = new SSOLoginProcessor
55 {
56 Authentications = _auth,
57 HttpWebRequestFactory = _requestFactory,
58 Keyring = _keyring,
59 OAuth = _oauth,
60 SSOCredentialsEncoder = _encode
61 };
62 }
63
64 #endregion
65
66 #region Tests
67
68 [TestCase("manuel@canonical.com", "Passwd", "UbuntuOne")]
69 [TestCase("mandel@themacaque.com", "Test", "Gwibber")]
70 [ExpectedException(typeof(SSOLoginException))]
71 public void LoginCredentialsExceptionTest(string email, string password, string tokenName)
72 {
73 Assert.Ignore("Not yet implemented");
74 }
75
76 [Test]
77 [ExpectedException(typeof(SSOLoginException))]
78 public void LoginPingExceptionTest()
79 {
80 Assert.Ignore("Not yet implemented");
81 }
82
83 [Test]
84 public void LoginNoSecretTest()
85 {
86 Assert.Ignore("Not yet implemented");
87 }
88
89 [Test]
90 public void LoginSecretTest()
91 {
92 Assert.Ignore("Not yet implemented");
93 }
94
95 #endregion
96
97 }
98}
099
=== modified file 'src/Canonical.Ubuntu.SSO/Canonical.Ubuntu.SSO.csproj'
--- src/Canonical.Ubuntu.SSO/Canonical.Ubuntu.SSO.csproj 2010-10-05 09:58:34 +0000
+++ src/Canonical.Ubuntu.SSO/Canonical.Ubuntu.SSO.csproj 2010-10-05 09:58:35 +0000
@@ -35,6 +35,10 @@
35 <SpecificVersion>False</SpecificVersion>35 <SpecificVersion>False</SpecificVersion>
36 <HintPath>..\..\lib\log4net\log4net.dll</HintPath>36 <HintPath>..\..\lib\log4net\log4net.dll</HintPath>
37 </Reference>37 </Reference>
38 <Reference Include="Newtonsoft.Json, Version=3.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
39 <SpecificVersion>False</SpecificVersion>
40 <HintPath>..\..\lib\JsonNet\Newtonsoft.Json.dll</HintPath>
41 </Reference>
38 <Reference Include="System" />42 <Reference Include="System" />
39 <Reference Include="System.Core">43 <Reference Include="System.Core">
40 <RequiredTargetFramework>3.5</RequiredTargetFramework>44 <RequiredTargetFramework>3.5</RequiredTargetFramework>
@@ -54,6 +58,7 @@
54 <Compile Include="..\Version.cs">58 <Compile Include="..\Version.cs">
55 <Link>Properties\Version.cs</Link>59 <Link>Properties\Version.cs</Link>
56 </Compile>60 </Compile>
61 <Compile Include="ColonSeparatedSSOCredentialsEncoder.cs" />
57 <Compile Include="CredentialsDeniedEventArgs.cs" />62 <Compile Include="CredentialsDeniedEventArgs.cs" />
58 <Compile Include="CredentialsErrorEventArgs.cs" />63 <Compile Include="CredentialsErrorEventArgs.cs" />
59 <Compile Include="CredentialsFoundEventArgs.cs" />64 <Compile Include="CredentialsFoundEventArgs.cs" />
@@ -61,11 +66,14 @@
61 <Compile Include="IDataProtector.cs" />66 <Compile Include="IDataProtector.cs" />
62 <Compile Include="ILoginOrRegisterView.cs" />67 <Compile Include="ILoginOrRegisterView.cs" />
63 <Compile Include="ILoginView.cs" />68 <Compile Include="ILoginView.cs" />
69 <Compile Include="IOAuth.cs" />
64 <Compile Include="IRegistryKey.cs" />70 <Compile Include="IRegistryKey.cs" />
71 <Compile Include="ISSOCredentialsEncoder.cs" />
65 <Compile Include="ISSOLoginProcessor.cs" />72 <Compile Include="ISSOLoginProcessor.cs" />
73 <Compile Include="JsonSSOCredentialsEncoder.cs" />
66 <Compile Include="Keyring.cs" />74 <Compile Include="Keyring.cs" />
67 <Compile Include="LoginCredentialsEventArgs.cs" />75 <Compile Include="LoginCredentialsEventArgs.cs" />
68 <Compile Include="OAuthBase.cs" />76 <Compile Include="OAuth.cs" />
69 <Compile Include="RegistryKeyWrapper.cs" />77 <Compile Include="RegistryKeyWrapper.cs" />
70 <Compile Include="Service\Account.cs" />78 <Compile Include="Service\Account.cs" />
71 <Compile Include="Service\AccountDiff.cs" />79 <Compile Include="Service\AccountDiff.cs" />
@@ -109,6 +117,8 @@
109 <Compile Include="IKeyring.cs" />117 <Compile Include="IKeyring.cs" />
110 <Compile Include="ISSOCredentialsProvider.cs" />118 <Compile Include="ISSOCredentialsProvider.cs" />
111 <Compile Include="Properties\AssemblyInfo.cs" />119 <Compile Include="Properties\AssemblyInfo.cs" />
120 <Compile Include="SSOException.cs" />
121 <Compile Include="SSOLoginException.cs" />
112 <Compile Include="SSOLoginProcessor.cs" />122 <Compile Include="SSOLoginProcessor.cs" />
113 </ItemGroup>123 </ItemGroup>
114 <ItemGroup>124 <ItemGroup>
115125
=== added file 'src/Canonical.Ubuntu.SSO/ColonSeparatedSSOCredentialsEncoder.cs'
--- src/Canonical.Ubuntu.SSO/ColonSeparatedSSOCredentialsEncoder.cs 1970-01-01 00:00:00 +0000
+++ src/Canonical.Ubuntu.SSO/ColonSeparatedSSOCredentialsEncoder.cs 2010-10-05 09:58:35 +0000
@@ -0,0 +1,60 @@
1/* Copyright 2010 Canonical Ltd.
2 *
3 * This file is part of UbuntuOne on Windows.
4 *
5 * UbuntuOne on Windows is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License version
7 * as published by the Free Software Foundation.
8 *
9 * Ubuntu One on Windows is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authors: Manuel de la Peña <manuel.delapena@canonical.com>
18 */
19namespace Canonical.Ubuntu.SSO
20{
21 /// <summary>
22 /// Encode implementation that encodes the oauth token using colons as separators.
23 /// </summary>
24 public class ColonSeparatedSSOCredentialsEncoder : ISSOCredentialsEncoder
25 {
26 #region Implementation of ISSOCredentialsEncoder
27
28 /// <summary>
29 /// Encodes oauth credentials so that they can be stored in a keyring.
30 /// </summary>
31 /// <param name="token">The oauth token.</param>
32 /// <param name="tokenSecret">The oauth secret.</param>
33 /// <param name="consumerKey">The oauth consumer key.</param>
34 /// <param name="consumerSecret">The oauth consumer secret.</param>
35 /// <returns>a stirng that represents the oauth token.</returns>
36 public string Encode(string token, string tokenSecret, string consumerKey, string consumerSecret)
37 {
38 return string.Format("{0}:{1}:{2}:{3}", token, tokenSecret, consumerKey, consumerSecret);
39 }
40
41 /// <summary>
42 /// Decodes the oauth credentials from a single string.
43 /// </summary>
44 /// <param name="secret">The secret that was stored in the keyring.</param>
45 /// <param name="token">Out var where the ouath token will be returned.</param>
46 /// <param name="tokenSecret">Out var where the oauth token secret will be returned.</param>
47 /// <param name="consumerKey">Out var where the oauth consumer key will be returned.</param>
48 /// <param name="consumerSecret">Out var where the oauth consumer secret will be returned.</param>
49 public void Decode(string secret, out string token, out string tokenSecret, out string consumerKey, out string consumerSecret)
50 {
51 var data = secret.Split(":".ToCharArray(),4);
52 token = data[0];
53 tokenSecret = data[1];
54 consumerKey = data[2];
55 consumerSecret = data[3];
56 }
57
58 #endregion
59 }
60}
061
=== modified file 'src/Canonical.Ubuntu.SSO/DPAPIDataProtector.cs'
--- src/Canonical.Ubuntu.SSO/DPAPIDataProtector.cs 2010-10-05 09:58:34 +0000
+++ src/Canonical.Ubuntu.SSO/DPAPIDataProtector.cs 2010-10-05 09:58:35 +0000
@@ -17,7 +17,6 @@
17 * 17 *
18 * Authors: Manuel de la Peña <manuel.delapena@canonical.com>18 * Authors: Manuel de la Peña <manuel.delapena@canonical.com>
19 */19 */
20
21using System.Security.Cryptography;20using System.Security.Cryptography;
22using System.Text;21using System.Text;
23using log4net;22using log4net;
2423
=== added file 'src/Canonical.Ubuntu.SSO/IOAuth.cs'
--- src/Canonical.Ubuntu.SSO/IOAuth.cs 1970-01-01 00:00:00 +0000
+++ src/Canonical.Ubuntu.SSO/IOAuth.cs 2010-10-05 09:58:35 +0000
@@ -0,0 +1,122 @@
1/* Copyright 2010 Canonical Ltd.
2 *
3 * This file is part of UbuntuOne on Windows.
4 *
5 * UbuntuOne on Windows is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License version
7 * as published by the Free Software Foundation.
8 *
9 * Ubuntu One on Windows is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authors: Manuel de la Peña <manuel.delapena@canonical.com>
18 */
19using System;
20using System.Collections.Generic;
21using System.Security.Cryptography;
22
23namespace Canonical.Ubuntu.SSO
24{
25 public interface IOAuth
26 {
27 /// <summary>
28 /// Generate the signature base that is used to produce the signature
29 /// </summary>
30 /// <param name="url">The full url that needs to be signed including its non OAuth url parameters</param>
31 /// <param name="consumerKey">The consumer key</param>
32 /// <param name="token">The token, if available. If not available pass null or an empty string</param>
33 /// <param name="tokenSecret">The token secret, if available. If not available pass null or an empty string</param>
34 /// <param name="httpMethod">The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)</param>
35 /// <param name="nonce"></param>
36 /// <param name="signatureType">The signature type. To use the default values use <see cref="OAuth.SignatureTypes">OAuth.SignatureTypes</see>.</param>
37 /// <param name="timeStamp"></param>
38 /// <param name="normalizedUrl"></param>
39 /// <param name="normalizedRequestParameters"></param>
40 /// <returns>The signature base</returns>
41 string GenerateSignatureBase(Uri url, string consumerKey, string token, string tokenSecret,
42 string httpMethod, string timeStamp, string nonce, string signatureType, out string normalizedUrl,
43 out string normalizedRequestParameters);
44
45 /// <summary>
46 /// Generate the signature value based on the given signature base and hash algorithm
47 /// </summary>
48 /// <param name="signatureBase">The signature based as produced by the GenerateSignatureBase method or by any other means</param>
49 /// <param name="hash">The hash algorithm used to perform the hashing. If the hashing algorithm requires initialization or a key it should be set prior to calling this method</param>
50 /// <returns>A base64 string of the hash value</returns>
51 string GenerateSignatureUsingHash(string signatureBase, HashAlgorithm hash);
52
53 /// <summary>
54 /// Generates a signature using the HMAC-SHA1 algorithm
55 /// </summary>
56 /// <param name="url">The full url that needs to be signed including its non OAuth url parameters</param>
57 /// <param name="consumerKey">The consumer key</param>
58 /// <param name="consumerSecret">The consumer seceret</param>
59 /// <param name="token">The token, if available. If not available pass null or an empty string</param>
60 /// <param name="tokenSecret">The token secret, if available. If not available pass null or an empty string</param>
61 /// <param name="httpMethod">The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)</param>
62 /// <param name="timeStamp"></param>
63 /// <param name="nonce"></param>
64 /// <param name="normalizedUrl"></param>
65 /// <param name="normalizedRequestParameters"></param>
66 /// <returns>A base64 string of the hash value</returns>
67 string GenerateSignature(Uri url, string consumerKey, string consumerSecret, string token,
68 string tokenSecret, string httpMethod, string timeStamp, string nonce, out string normalizedUrl,
69 out string normalizedRequestParameters);
70
71 /// <summary>
72 /// Generates a signature using the specified signatureType
73 /// </summary>
74 /// <param name="url">The full url that needs to be signed including its non OAuth url parameters</param>
75 /// <param name="consumerKey">The consumer key</param>
76 /// <param name="consumerSecret">The consumer seceret</param>
77 /// <param name="token">The token, if available. If not available pass null or an empty string</param>
78 /// <param name="tokenSecret">The token secret, if available. If not available pass null or an empty string</param>
79 /// <param name="httpMethod">The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)</param>
80 /// <param name="nonce"></param>
81 /// <param name="signatureType">The type of signature to use</param>
82 /// <param name="timeStamp"></param>
83 /// <param name="normalizedUrl"></param>
84 /// <param name="normalizedRequestParameters"></param>
85 /// <returns>A base64 string of the hash value</returns>
86 string GenerateSignature(Uri url, string consumerKey, string consumerSecret, string token,
87 string tokenSecret, string httpMethod, string timeStamp, string nonce,
88 OAuth.SignatureTypes signatureType, out string normalizedUrl, out string normalizedRequestParameters);
89
90 /// <summary>
91 /// Returns a key value pair that contains a hedaer that can be used to authenticate a web requet.
92 /// </summary>
93 /// <param name="url">The uri with the web resource.</param>
94 /// <param name="realm">The real that was used for the oauth.</param>
95 /// <param name="consumerKey">The oauth consumer key.</param>
96 /// <param name="consumerSecret">The oauth consumer secret.</param>
97 /// <param name="token">The oauth token.</param>
98 /// <param name="tokenSecret">The aoauth token secret.</param>
99 /// <param name="httpMethod">The http method used for the request.</param>
100 /// <param name="timeStamp">A time stamp.</param>
101 /// <param name="nonce">A once</param>
102 /// <param name="signatureType">Teht ype of signature that will be used.</param>
103 /// <param name="normUrl"></param>
104 /// <param name="normParams"></param>
105 /// <returns>A key value pair where the key is the name of the header and the value is the data of the header.</returns>
106 KeyValuePair<string, string> GenerateHeaderWithSignature(Uri url, string realm, string consumerKey,
107 string consumerSecret, string token, string tokenSecret, string httpMethod, string timeStamp,
108 string nonce, OAuth.SignatureTypes signatureType, out string normUrl, out string normParams);
109
110 /// <summary>
111 /// Generate the timestamp for the signature
112 /// </summary>
113 /// <returns></returns>
114 string GenerateTimeStamp();
115
116 /// <summary>
117 /// Generate a nonce
118 /// </summary>
119 /// <returns></returns>
120 string GenerateNonce();
121 }
122}
0\ No newline at end of file123\ No newline at end of file
1124
=== added file 'src/Canonical.Ubuntu.SSO/ISSOCredentialsEncoder.cs'
--- src/Canonical.Ubuntu.SSO/ISSOCredentialsEncoder.cs 1970-01-01 00:00:00 +0000
+++ src/Canonical.Ubuntu.SSO/ISSOCredentialsEncoder.cs 2010-10-05 09:58:35 +0000
@@ -0,0 +1,46 @@
1/* Copyright 2010 Canonical Ltd.
2 *
3 * This file is part of UbuntuOne on Windows.
4 *
5 * UbuntuOne on Windows is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License version
7 * as published by the Free Software Foundation.
8 *
9 * Ubuntu One on Windows is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authors: Manuel de la Peña <manuel.delapena@canonical.com>
18 */
19namespace Canonical.Ubuntu.SSO
20{
21 /// <summary>
22 /// Interface to be implemented by those object that know how to encode a oauth token so that it is saved as a single string.
23 /// </summary>
24 public interface ISSOCredentialsEncoder
25 {
26 /// <summary>
27 /// When implemented will encode oauth credentials so that they can be stored in a keyring.
28 /// </summary>
29 /// <param name="token">The oauth token.</param>
30 /// <param name="tokenSecret">The oauth secret.</param>
31 /// <param name="consumerKey">The oauth consumer key.</param>
32 /// <param name="consumerSecret">The oauth consumer secret.</param>
33 /// <returns>a stirng that represents the oauth token.</returns>
34 string Encode(string token, string tokenSecret, string consumerKey, string consumerSecret);
35
36 /// <summary>
37 /// When implemented decodes the oauth credentials from a single string.
38 /// </summary>
39 /// <param name="secret">The secret that was stored in the keyring.</param>
40 /// <param name="token">Out var where the ouath token will be returned.</param>
41 /// <param name="tokenSecret">Out var where the oauth token secret will be returned.</param>
42 /// <param name="consumerKey">Out var where the oauth consumer key will be returned.</param>
43 /// <param name="consumerSecret">Out var where the oauth consumer secret will be returned.</param>
44 void Decode(string secret, out string token, out string tokenSecret, out string consumerKey, out string consumerSecret);
45 }
46}
047
=== added file 'src/Canonical.Ubuntu.SSO/JsonSSOCredentialsEncoder.cs'
--- src/Canonical.Ubuntu.SSO/JsonSSOCredentialsEncoder.cs 1970-01-01 00:00:00 +0000
+++ src/Canonical.Ubuntu.SSO/JsonSSOCredentialsEncoder.cs 2010-10-05 09:58:35 +0000
@@ -0,0 +1,82 @@
1/* Copyright 2010 Canonical Ltd.
2 *
3 * This file is part of UbuntuOne on Windows.
4 *
5 * UbuntuOne on Windows is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License version
7 * as published by the Free Software Foundation.
8 *
9 * Ubuntu One on Windows is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authors: Manuel de la Peña <manuel.delapena@canonical.com>
18 */
19using System;
20using Newtonsoft.Json.Linq;
21
22namespace Canonical.Ubuntu.SSO
23{
24 public class JsonSSOCredentialsEncoder : ISSOCredentialsEncoder
25 {
26 #region Implementation of ISSOCredentialsEncoder
27
28 /// <summary>
29 /// When implemented will encode oauth credentials so that they can be stored in a keyring.
30 /// </summary>
31 /// <param name="token">The oauth token.</param>
32 /// <param name="tokenSecret">The oauth secret.</param>
33 /// <param name="consumerKey">The oauth consumer key.</param>
34 /// <param name="consumerSecret">The oauth consumer secret.</param>
35 /// <returns>a stirng that represents the oauth token.</returns>
36 public string Encode(string token, string tokenSecret, string consumerKey, string consumerSecret)
37 {
38 var jobject = new JObject();
39 jobject["consumer_key"] = "";
40 jobject["consumer_secret"] = "";
41 jobject["token"] = "";
42 jobject["token_secret"] = "";
43 return jobject.ToString();
44 }
45
46 /// <summary>
47 /// When implemented decodes the oauth credentials from a single string.
48 /// </summary>
49 /// <param name="secret">The secret that was stored in the keyring.</param>
50 /// <param name="token">Out var where the ouath token will be returned.</param>
51 /// <param name="tokenSecret">Out var where the oauth token secret will be returned.</param>
52 /// <param name="consumerKey">Out var where the oauth consumer key will be returned.</param>
53 /// <param name="consumerSecret">Out var where the oauth consumer secret will be returned.</param>
54 public void Decode(string secret, out string token, out string tokenSecret, out string consumerKey, out string consumerSecret)
55 {
56 var credentials = JObject.Parse(secret);
57 try
58 {
59 consumerKey = (string)credentials["consumer_key"];
60 consumerSecret = (string)credentials["consumer_secret"];
61 token = (string)credentials["token"];
62 tokenSecret = (string)credentials["token_secret"];
63
64 }
65 catch (InvalidCastException e)
66 {
67 // could happen when the json is not formatted as we expected.
68 throw new SSOLoginException("Error when retrieving credentials.", e);
69 }
70 if (string.IsNullOrEmpty(consumerKey)
71 || string.IsNullOrEmpty(consumerSecret)
72 || string.IsNullOrEmpty(token)
73 || string.IsNullOrEmpty(tokenSecret))
74 {
75 // none of them can be null or empty.
76 throw new SSOException("Credentials could not be parsed.");
77 }
78 }
79
80 #endregion
81 }
82}
083
=== added file 'src/Canonical.Ubuntu.SSO/OAuth.cs'
--- src/Canonical.Ubuntu.SSO/OAuth.cs 1970-01-01 00:00:00 +0000
+++ src/Canonical.Ubuntu.SSO/OAuth.cs 2010-10-05 09:58:35 +0000
@@ -0,0 +1,391 @@
1using System;
2using System.Security.Cryptography;
3using System.Collections.Generic;
4using System.Text;
5using System.Web;
6
7namespace Canonical.Ubuntu.SSO
8{
9 public class OAuth : IOAuth
10 {
11
12 /// <summary>
13 /// Provides a predefined set of algorithms that are supported officially by the protocol
14 /// </summary>
15 public enum SignatureTypes
16 {
17 HMACSHA1,
18 PLAINTEXT,
19 RSASHA1
20 }
21
22 /// <summary>
23 /// Provides an internal structure to sort the query parameter
24 /// </summary>
25 protected class QueryParameter
26 {
27 private readonly string _name = null;
28 private readonly string _value = null;
29
30 public QueryParameter(string name, string value)
31 {
32 _name = name;
33 _value = value;
34 }
35
36 public string Name
37 {
38 get { return _name; }
39 }
40
41 public string Value
42 {
43 get { return _value; }
44 }
45 }
46
47 /// <summary>
48 /// Comparer class used to perform the sorting of the query parameters
49 /// </summary>
50 protected class QueryParameterComparer : IComparer<QueryParameter>
51 {
52
53 #region IComparer<QueryParameter> Members
54
55 public int Compare(QueryParameter x, QueryParameter y)
56 {
57 return x.Name == y.Name ? string.Compare(x.Value, y.Value)
58 : string.Compare(x.Name, y.Name);
59 }
60
61 #endregion
62 }
63
64 protected const string OAuthVersion = "1.0";
65 protected const string OAuthParameterPrefix = "oauth_";
66
67 //
68 // List of know and used oauth parameters' names
69 //
70 protected const string OAuthConsumerKeyKey = "oauth_consumer_key";
71 protected const string OAuthCallbackKey = "oauth_callback";
72 protected const string OAuthVersionKey = "oauth_version";
73 protected const string OAuthSignatureMethodKey = "oauth_signature_method";
74 protected const string OAuthSignatureKey = "oauth_signature";
75 protected const string OAuthTimestampKey = "oauth_timestamp";
76 protected const string OAuthNonceKey = "oauth_nonce";
77 protected const string OAuthTokenKey = "oauth_token";
78 protected const string OAuthTokenSecretKey = "oauth_token_secret";
79
80 protected const string HMACSHA1SignatureType = "HMAC-SHA1";
81 protected const string PlainTextSignatureType = "PLAINTEXT";
82 protected const string RSASHA1SignatureType = "RSA-SHA1";
83
84 protected Random Random = new Random();
85
86 protected string UnreservedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";
87
88 /// <summary>
89 /// Helper function to compute a hash value
90 /// </summary>
91 /// <param name="hashAlgorithm">The hashing algoirhtm used. If that algorithm needs some initialization, like HMAC and its derivatives, they should be initialized prior to passing it to this function</param>
92 /// <param name="data">The data to hash</param>
93 /// <returns>a Base64 string of the hash value</returns>
94 private static string ComputeHash(HashAlgorithm hashAlgorithm, string data)
95 {
96 if (hashAlgorithm == null)
97 {
98 throw new ArgumentNullException("hashAlgorithm");
99 }
100
101 if (string.IsNullOrEmpty(data))
102 {
103 throw new ArgumentNullException("data");
104 }
105
106 var dataBuffer = Encoding.ASCII.GetBytes(data);
107 var hashBytes = hashAlgorithm.ComputeHash(dataBuffer);
108
109 return Convert.ToBase64String(hashBytes);
110 }
111
112 /// <summary>
113 /// Internal function to cut out all non oauth query string parameters (all parameters not begining with "oauth_")
114 /// </summary>
115 /// <param name="parameters">The query string part of the Url</param>
116 /// <returns>A list of QueryParameter each containing the parameter name and value</returns>
117 private static List<QueryParameter> GetQueryParameters(string parameters)
118 {
119 if (parameters.StartsWith("?"))
120 {
121 parameters = parameters.Remove(0, 1);
122 }
123
124 var result = new List<QueryParameter>();
125
126 if (!string.IsNullOrEmpty(parameters))
127 {
128 string[] p = parameters.Split('&');
129 foreach (string s in p)
130 {
131 if (!string.IsNullOrEmpty(s) && !s.StartsWith(OAuthParameterPrefix))
132 {
133 if (s.IndexOf('=') > -1)
134 {
135 string[] temp = s.Split('=');
136 result.Add(new QueryParameter(temp[0], temp[1]));
137 }
138 else
139 {
140 result.Add(new QueryParameter(s, string.Empty));
141 }
142 }
143 }
144 }
145
146 return result;
147 }
148
149 /// <summary>
150 /// This is a different Url Encode implementation since the default .NET one outputs the percent encoding in lower case.
151 /// While this is not a problem with the percent encoding spec, it is used in upper case throughout OAuth
152 /// </summary>
153 /// <param name="value">The value to Url encode</param>
154 /// <returns>Returns a Url encoded string</returns>
155 protected string UrlEncode(string value)
156 {
157 var result = new StringBuilder();
158
159 foreach (char symbol in value)
160 {
161 if (UnreservedChars.IndexOf(symbol) != -1)
162 {
163 result.Append(symbol);
164 }
165 else
166 {
167 result.Append('%' + String.Format("{0:X2}", (int)symbol));
168 }
169 }
170
171 return result.ToString();
172 }
173
174 /// <summary>
175 /// Normalizes the request parameters according to the spec
176 /// </summary>
177 /// <param name="parameters">The list of parameters already sorted</param>
178 /// <returns>a string representing the normalized parameters</returns>
179 protected string NormalizeRequestParameters(IList<QueryParameter> parameters)
180 {
181 var sb = new StringBuilder();
182 QueryParameter p;
183 for (var i = 0; i < parameters.Count; i++)
184 {
185 p = parameters[i];
186 sb.AppendFormat("{0}={1}", p.Name, p.Value);
187
188 if (i < parameters.Count - 1)
189 {
190 sb.Append("&");
191 }
192 }
193
194 return sb.ToString();
195 }
196
197 /// <summary>
198 /// Generate the signature base that is used to produce the signature
199 /// </summary>
200 /// <param name="url">The full url that needs to be signed including its non OAuth url parameters</param>
201 /// <param name="consumerKey">The consumer key</param>
202 /// <param name="token">The token, if available. If not available pass null or an empty string</param>
203 /// <param name="tokenSecret">The token secret, if available. If not available pass null or an empty string</param>
204 /// <param name="httpMethod">The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)</param>
205 /// <param name="nonce"></param>
206 /// <param name="signatureType">The signature type. To use the default values use <see cref="OAuth.SignatureTypes">OAuth.SignatureTypes</see>.</param>
207 /// <param name="timeStamp"></param>
208 /// <param name="normalizedUrl"></param>
209 /// <param name="normalizedRequestParameters"></param>
210 /// <returns>The signature base</returns>
211 public string GenerateSignatureBase(Uri url, string consumerKey, string token, string tokenSecret, string httpMethod, string timeStamp, string nonce, string signatureType, out string normalizedUrl, out string normalizedRequestParameters)
212 {
213 if (token == null)
214 {
215 token = string.Empty;
216 }
217
218 if (tokenSecret == null)
219 {
220 tokenSecret = string.Empty;
221 }
222
223 if (string.IsNullOrEmpty(consumerKey))
224 {
225 throw new ArgumentNullException("consumerKey");
226 }
227
228 if (string.IsNullOrEmpty(httpMethod))
229 {
230 throw new ArgumentNullException("httpMethod");
231 }
232
233 if (string.IsNullOrEmpty(signatureType))
234 {
235 throw new ArgumentNullException("signatureType");
236 }
237
238 List<QueryParameter> parameters = GetQueryParameters(url.Query);
239 parameters.Add(new QueryParameter(OAuthVersionKey, OAuthVersion));
240 parameters.Add(new QueryParameter(OAuthNonceKey, nonce));
241 parameters.Add(new QueryParameter(OAuthTimestampKey, timeStamp));
242 parameters.Add(new QueryParameter(OAuthSignatureMethodKey, signatureType));
243 parameters.Add(new QueryParameter(OAuthConsumerKeyKey, consumerKey));
244
245 if (!string.IsNullOrEmpty(token))
246 {
247 parameters.Add(new QueryParameter(OAuthTokenKey, token));
248 }
249
250 parameters.Sort(new QueryParameterComparer());
251
252 normalizedUrl = string.Format("{0}://{1}", url.Scheme, url.Host);
253 if (!((url.Scheme == "http" && url.Port == 80) || (url.Scheme == "https" && url.Port == 443)))
254 {
255 normalizedUrl += ":" + url.Port;
256 }
257 normalizedUrl += url.AbsolutePath;
258 normalizedRequestParameters = NormalizeRequestParameters(parameters);
259
260 var signatureBase = new StringBuilder();
261 signatureBase.AppendFormat("{0}&", httpMethod.ToUpper());
262 signatureBase.AppendFormat("{0}&", UrlEncode(normalizedUrl));
263 signatureBase.AppendFormat("{0}", UrlEncode(normalizedRequestParameters));
264
265 return signatureBase.ToString();
266 }
267
268 /// <summary>
269 /// Generate the signature value based on the given signature base and hash algorithm
270 /// </summary>
271 /// <param name="signatureBase">The signature based as produced by the GenerateSignatureBase method or by any other means</param>
272 /// <param name="hash">The hash algorithm used to perform the hashing. If the hashing algorithm requires initialization or a key it should be set prior to calling this method</param>
273 /// <returns>A base64 string of the hash value</returns>
274 public string GenerateSignatureUsingHash(string signatureBase, HashAlgorithm hash)
275 {
276 return ComputeHash(hash, signatureBase);
277 }
278
279 /// <summary>
280 /// Generates a signature using the HMAC-SHA1 algorithm
281 /// </summary>
282 /// <param name="url">The full url that needs to be signed including its non OAuth url parameters</param>
283 /// <param name="consumerKey">The consumer key</param>
284 /// <param name="consumerSecret">The consumer seceret</param>
285 /// <param name="token">The token, if available. If not available pass null or an empty string</param>
286 /// <param name="tokenSecret">The token secret, if available. If not available pass null or an empty string</param>
287 /// <param name="httpMethod">The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)</param>
288 /// <param name="timeStamp"></param>
289 /// <param name="nonce"></param>
290 /// <param name="normalizedUrl"></param>
291 /// <param name="normalizedRequestParameters"></param>
292 /// <returns>A base64 string of the hash value</returns>
293 public string GenerateSignature(Uri url, string consumerKey, string consumerSecret, string token, string tokenSecret, string httpMethod, string timeStamp, string nonce, out string normalizedUrl, out string normalizedRequestParameters)
294 {
295 return GenerateSignature(url, consumerKey, consumerSecret, token, tokenSecret, httpMethod, timeStamp, nonce, SignatureTypes.HMACSHA1, out normalizedUrl, out normalizedRequestParameters);
296 }
297
298 /// <summary>
299 /// Generates a signature using the specified signatureType
300 /// </summary>
301 /// <param name="url">The full url that needs to be signed including its non OAuth url parameters</param>
302 /// <param name="consumerKey">The consumer key</param>
303 /// <param name="consumerSecret">The consumer seceret</param>
304 /// <param name="token">The token, if available. If not available pass null or an empty string</param>
305 /// <param name="tokenSecret">The token secret, if available. If not available pass null or an empty string</param>
306 /// <param name="httpMethod">The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)</param>
307 /// <param name="nonce"></param>
308 /// <param name="signatureType">The type of signature to use</param>
309 /// <param name="timeStamp"></param>
310 /// <param name="normalizedUrl"></param>
311 /// <param name="normalizedRequestParameters"></param>
312 /// <returns>A base64 string of the hash value</returns>
313 public string GenerateSignature(Uri url, string consumerKey, string consumerSecret, string token, string tokenSecret, string httpMethod, string timeStamp, string nonce, SignatureTypes signatureType, out string normalizedUrl, out string normalizedRequestParameters)
314 {
315 normalizedUrl = null;
316 normalizedRequestParameters = null;
317
318 switch (signatureType)
319 {
320 case SignatureTypes.PLAINTEXT:
321 return HttpUtility.UrlEncode(string.Format("{0}&{1}", consumerSecret, tokenSecret));
322 case SignatureTypes.HMACSHA1:
323 var signatureBase = GenerateSignatureBase(url, consumerKey, token, tokenSecret, httpMethod, timeStamp, nonce, HMACSHA1SignatureType, out normalizedUrl, out normalizedRequestParameters);
324
325 var hmacsha1 = new HMACSHA1();
326 hmacsha1.Key = Encoding.ASCII.GetBytes(string.Format("{0}&{1}", UrlEncode(consumerSecret), string.IsNullOrEmpty(tokenSecret) ? "" : UrlEncode(tokenSecret)));
327
328 return GenerateSignatureUsingHash(signatureBase, hmacsha1);
329 case SignatureTypes.RSASHA1:
330 throw new NotImplementedException();
331 default:
332 throw new ArgumentException("Unknown signature type", "signatureType");
333 }
334 }
335
336 /// <summary>
337 /// Returns a key value pair that contains a hedaer that can be used to authenticate a web requet.
338 /// </summary>
339 /// <param name="url">The uri with the web resource.</param>
340 /// <param name="realm">The real that was used for the oauth.</param>
341 /// <param name="consumerKey">The oauth consumer key.</param>
342 /// <param name="consumerSecret">The oauth consumer secret.</param>
343 /// <param name="token">The oauth token.</param>
344 /// <param name="tokenSecret">The aoauth token secret.</param>
345 /// <param name="httpMethod">The http method used for the request.</param>
346 /// <param name="timeStamp">A time stamp.</param>
347 /// <param name="nonce">A once</param>
348 /// <param name="signatureType">Teht ype of signature that will be used.</param>
349 /// <returns>A key value pair where the key is the name of the header and the value is the data of the header.</returns>
350 public KeyValuePair<string, string> GenerateHeaderWithSignature(Uri url, string realm, string consumerKey,
351 string consumerSecret, string token, string tokenSecret, string httpMethod, string timeStamp,
352 string nonce, SignatureTypes signatureType, out string normUrl, out string normParams)
353 {
354 var signature = GenerateSignature(url,
355 consumerKey, consumerSecret, token, tokenSecret,
356 httpMethod, timeStamp, nonce, SignatureTypes.HMACSHA1,
357 out normUrl, out normParams);
358
359 // Construct the OAuth header
360 var headerData = normParams + "&" + HttpUtility.UrlEncode("oauth_signature") + "=" + HttpUtility.UrlEncode(signature);
361 headerData = headerData.Replace("&", @""",");
362 headerData = headerData.Replace("=", @"=""");
363 headerData += @"""";
364 headerData = ((string.IsNullOrEmpty(realm)) ? "OAuth realm=\"\"," :
365 string.Format("OAuth realm=\"{0}\",", realm)) + headerData;
366 return new KeyValuePair<string, string>("Authorization", headerData);
367 }
368
369 /// <summary>
370 /// Generate the timestamp for the signature
371 /// </summary>
372 /// <returns></returns>
373 public virtual string GenerateTimeStamp()
374 {
375 // Default implementation of UNIX time of the current UTC time
376 TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
377 return Convert.ToInt64(ts.TotalSeconds).ToString();
378 }
379
380 /// <summary>
381 /// Generate a nonce
382 /// </summary>
383 /// <returns></returns>
384 public virtual string GenerateNonce()
385 {
386 // Just a simple implementation of a random number between 123400 and 9999999
387 return Random.Next(123400, 9999999).ToString();
388 }
389
390 }
391}
0\ No newline at end of file392\ No newline at end of file
1393
=== removed file 'src/Canonical.Ubuntu.SSO/OAuthBase.cs'
--- src/Canonical.Ubuntu.SSO/OAuthBase.cs 2010-10-05 09:58:34 +0000
+++ src/Canonical.Ubuntu.SSO/OAuthBase.cs 1970-01-01 00:00:00 +0000
@@ -1,358 +0,0 @@
1using System;
2using System.Security.Cryptography;
3using System.Collections.Generic;
4using System.Text;
5using System.Web;
6
7namespace OAuth
8{
9 public class OAuthBase
10 {
11
12 /// <summary>
13 /// Provides a predefined set of algorithms that are supported officially by the protocol
14 /// </summary>
15 public enum SignatureTypes
16 {
17 HMACSHA1,
18 PLAINTEXT,
19 RSASHA1
20 }
21
22 /// <summary>
23 /// Provides an internal structure to sort the query parameter
24 /// </summary>
25 protected class QueryParameter
26 {
27 private readonly string _name = null;
28 private readonly string _value = null;
29
30 public QueryParameter(string name, string value)
31 {
32 _name = name;
33 _value = value;
34 }
35
36 public string Name
37 {
38 get { return _name; }
39 }
40
41 public string Value
42 {
43 get { return _value; }
44 }
45 }
46
47 /// <summary>
48 /// Comparer class used to perform the sorting of the query parameters
49 /// </summary>
50 protected class QueryParameterComparer : IComparer<QueryParameter>
51 {
52
53 #region IComparer<QueryParameter> Members
54
55 public int Compare(QueryParameter x, QueryParameter y)
56 {
57 return x.Name == y.Name ? string.Compare(x.Value, y.Value)
58 : string.Compare(x.Name, y.Name);
59 }
60
61 #endregion
62 }
63
64 protected const string OAuthVersion = "1.0";
65 protected const string OAuthParameterPrefix = "oauth_";
66
67 //
68 // List of know and used oauth parameters' names
69 //
70 protected const string OAuthConsumerKeyKey = "oauth_consumer_key";
71 protected const string OAuthCallbackKey = "oauth_callback";
72 protected const string OAuthVersionKey = "oauth_version";
73 protected const string OAuthSignatureMethodKey = "oauth_signature_method";
74 protected const string OAuthSignatureKey = "oauth_signature";
75 protected const string OAuthTimestampKey = "oauth_timestamp";
76 protected const string OAuthNonceKey = "oauth_nonce";
77 protected const string OAuthTokenKey = "oauth_token";
78 protected const string OAuthTokenSecretKey = "oauth_token_secret";
79
80 protected const string HMACSHA1SignatureType = "HMAC-SHA1";
81 protected const string PlainTextSignatureType = "PLAINTEXT";
82 protected const string RSASHA1SignatureType = "RSA-SHA1";
83
84 protected Random Random = new Random();
85
86 protected string UnreservedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";
87
88 /// <summary>
89 /// Helper function to compute a hash value
90 /// </summary>
91 /// <param name="hashAlgorithm">The hashing algoirhtm used. If that algorithm needs some initialization, like HMAC and its derivatives, they should be initialized prior to passing it to this function</param>
92 /// <param name="data">The data to hash</param>
93 /// <returns>a Base64 string of the hash value</returns>
94 private static string ComputeHash(HashAlgorithm hashAlgorithm, string data)
95 {
96 if (hashAlgorithm == null)
97 {
98 throw new ArgumentNullException("hashAlgorithm");
99 }
100
101 if (string.IsNullOrEmpty(data))
102 {
103 throw new ArgumentNullException("data");
104 }
105
106 var dataBuffer = Encoding.ASCII.GetBytes(data);
107 var hashBytes = hashAlgorithm.ComputeHash(dataBuffer);
108
109 return Convert.ToBase64String(hashBytes);
110 }
111
112 /// <summary>
113 /// Internal function to cut out all non oauth query string parameters (all parameters not begining with "oauth_")
114 /// </summary>
115 /// <param name="parameters">The query string part of the Url</param>
116 /// <returns>A list of QueryParameter each containing the parameter name and value</returns>
117 private static List<QueryParameter> GetQueryParameters(string parameters)
118 {
119 if (parameters.StartsWith("?"))
120 {
121 parameters = parameters.Remove(0, 1);
122 }
123
124 var result = new List<QueryParameter>();
125
126 if (!string.IsNullOrEmpty(parameters))
127 {
128 string[] p = parameters.Split('&');
129 foreach (string s in p)
130 {
131 if (!string.IsNullOrEmpty(s) && !s.StartsWith(OAuthParameterPrefix))
132 {
133 if (s.IndexOf('=') > -1)
134 {
135 string[] temp = s.Split('=');
136 result.Add(new QueryParameter(temp[0], temp[1]));
137 }
138 else
139 {
140 result.Add(new QueryParameter(s, string.Empty));
141 }
142 }
143 }
144 }
145
146 return result;
147 }
148
149 /// <summary>
150 /// This is a different Url Encode implementation since the default .NET one outputs the percent encoding in lower case.
151 /// While this is not a problem with the percent encoding spec, it is used in upper case throughout OAuth
152 /// </summary>
153 /// <param name="value">The value to Url encode</param>
154 /// <returns>Returns a Url encoded string</returns>
155 protected string UrlEncode(string value)
156 {
157 var result = new StringBuilder();
158
159 foreach (char symbol in value)
160 {
161 if (UnreservedChars.IndexOf(symbol) != -1)
162 {
163 result.Append(symbol);
164 }
165 else
166 {
167 result.Append('%' + String.Format("{0:X2}", (int)symbol));
168 }
169 }
170
171 return result.ToString();
172 }
173
174 /// <summary>
175 /// Normalizes the request parameters according to the spec
176 /// </summary>
177 /// <param name="parameters">The list of parameters already sorted</param>
178 /// <returns>a string representing the normalized parameters</returns>
179 protected string NormalizeRequestParameters(IList<QueryParameter> parameters)
180 {
181 var sb = new StringBuilder();
182 QueryParameter p;
183 for (var i = 0; i < parameters.Count; i++)
184 {
185 p = parameters[i];
186 sb.AppendFormat("{0}={1}", p.Name, p.Value);
187
188 if (i < parameters.Count - 1)
189 {
190 sb.Append("&");
191 }
192 }
193
194 return sb.ToString();
195 }
196
197 /// <summary>
198 /// Generate the signature base that is used to produce the signature
199 /// </summary>
200 /// <param name="url">The full url that needs to be signed including its non OAuth url parameters</param>
201 /// <param name="consumerKey">The consumer key</param>
202 /// <param name="token">The token, if available. If not available pass null or an empty string</param>
203 /// <param name="tokenSecret">The token secret, if available. If not available pass null or an empty string</param>
204 /// <param name="httpMethod">The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)</param>
205 /// <param name="nonce"></param>
206 /// <param name="signatureType">The signature type. To use the default values use <see cref="OAuthBase.SignatureTypes">OAuthBase.SignatureTypes</see>.</param>
207 /// <param name="timeStamp"></param>
208 /// <param name="normalizedUrl"></param>
209 /// <param name="normalizedRequestParameters"></param>
210 /// <returns>The signature base</returns>
211 public string GenerateSignatureBase(Uri url, string consumerKey, string token, string tokenSecret, string httpMethod, string timeStamp, string nonce, string signatureType, out string normalizedUrl, out string normalizedRequestParameters)
212 {
213 if (token == null)
214 {
215 token = string.Empty;
216 }
217
218 if (tokenSecret == null)
219 {
220 tokenSecret = string.Empty;
221 }
222
223 if (string.IsNullOrEmpty(consumerKey))
224 {
225 throw new ArgumentNullException("consumerKey");
226 }
227
228 if (string.IsNullOrEmpty(httpMethod))
229 {
230 throw new ArgumentNullException("httpMethod");
231 }
232
233 if (string.IsNullOrEmpty(signatureType))
234 {
235 throw new ArgumentNullException("signatureType");
236 }
237
238 List<QueryParameter> parameters = GetQueryParameters(url.Query);
239 parameters.Add(new QueryParameter(OAuthVersionKey, OAuthVersion));
240 parameters.Add(new QueryParameter(OAuthNonceKey, nonce));
241 parameters.Add(new QueryParameter(OAuthTimestampKey, timeStamp));
242 parameters.Add(new QueryParameter(OAuthSignatureMethodKey, signatureType));
243 parameters.Add(new QueryParameter(OAuthConsumerKeyKey, consumerKey));
244
245 if (!string.IsNullOrEmpty(token))
246 {
247 parameters.Add(new QueryParameter(OAuthTokenKey, token));
248 }
249
250 parameters.Sort(new QueryParameterComparer());
251
252 normalizedUrl = string.Format("{0}://{1}", url.Scheme, url.Host);
253 if (!((url.Scheme == "http" && url.Port == 80) || (url.Scheme == "https" && url.Port == 443)))
254 {
255 normalizedUrl += ":" + url.Port;
256 }
257 normalizedUrl += url.AbsolutePath;
258 normalizedRequestParameters = NormalizeRequestParameters(parameters);
259
260 var signatureBase = new StringBuilder();
261 signatureBase.AppendFormat("{0}&", httpMethod.ToUpper());
262 signatureBase.AppendFormat("{0}&", UrlEncode(normalizedUrl));
263 signatureBase.AppendFormat("{0}", UrlEncode(normalizedRequestParameters));
264
265 return signatureBase.ToString();
266 }
267
268 /// <summary>
269 /// Generate the signature value based on the given signature base and hash algorithm
270 /// </summary>
271 /// <param name="signatureBase">The signature based as produced by the GenerateSignatureBase method or by any other means</param>
272 /// <param name="hash">The hash algorithm used to perform the hashing. If the hashing algorithm requires initialization or a key it should be set prior to calling this method</param>
273 /// <returns>A base64 string of the hash value</returns>
274 public string GenerateSignatureUsingHash(string signatureBase, HashAlgorithm hash)
275 {
276 return ComputeHash(hash, signatureBase);
277 }
278
279 /// <summary>
280 /// Generates a signature using the HMAC-SHA1 algorithm
281 /// </summary>
282 /// <param name="url">The full url that needs to be signed including its non OAuth url parameters</param>
283 /// <param name="consumerKey">The consumer key</param>
284 /// <param name="consumerSecret">The consumer seceret</param>
285 /// <param name="token">The token, if available. If not available pass null or an empty string</param>
286 /// <param name="tokenSecret">The token secret, if available. If not available pass null or an empty string</param>
287 /// <param name="httpMethod">The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)</param>
288 /// <param name="timeStamp"></param>
289 /// <param name="nonce"></param>
290 /// <param name="normalizedUrl"></param>
291 /// <param name="normalizedRequestParameters"></param>
292 /// <returns>A base64 string of the hash value</returns>
293 public string GenerateSignature(Uri url, string consumerKey, string consumerSecret, string token, string tokenSecret, string httpMethod, string timeStamp, string nonce, out string normalizedUrl, out string normalizedRequestParameters)
294 {
295 return GenerateSignature(url, consumerKey, consumerSecret, token, tokenSecret, httpMethod, timeStamp, nonce, SignatureTypes.HMACSHA1, out normalizedUrl, out normalizedRequestParameters);
296 }
297
298 /// <summary>
299 /// Generates a signature using the specified signatureType
300 /// </summary>
301 /// <param name="url">The full url that needs to be signed including its non OAuth url parameters</param>
302 /// <param name="consumerKey">The consumer key</param>
303 /// <param name="consumerSecret">The consumer seceret</param>
304 /// <param name="token">The token, if available. If not available pass null or an empty string</param>
305 /// <param name="tokenSecret">The token secret, if available. If not available pass null or an empty string</param>
306 /// <param name="httpMethod">The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)</param>
307 /// <param name="nonce"></param>
308 /// <param name="signatureType">The type of signature to use</param>
309 /// <param name="timeStamp"></param>
310 /// <param name="normalizedUrl"></param>
311 /// <param name="normalizedRequestParameters"></param>
312 /// <returns>A base64 string of the hash value</returns>
313 public string GenerateSignature(Uri url, string consumerKey, string consumerSecret, string token, string tokenSecret, string httpMethod, string timeStamp, string nonce, SignatureTypes signatureType, out string normalizedUrl, out string normalizedRequestParameters)
314 {
315 normalizedUrl = null;
316 normalizedRequestParameters = null;
317
318 switch (signatureType)
319 {
320 case SignatureTypes.PLAINTEXT:
321 return HttpUtility.UrlEncode(string.Format("{0}&{1}", consumerSecret, tokenSecret));
322 case SignatureTypes.HMACSHA1:
323 var signatureBase = GenerateSignatureBase(url, consumerKey, token, tokenSecret, httpMethod, timeStamp, nonce, HMACSHA1SignatureType, out normalizedUrl, out normalizedRequestParameters);
324
325 var hmacsha1 = new HMACSHA1();
326 hmacsha1.Key = Encoding.ASCII.GetBytes(string.Format("{0}&{1}", UrlEncode(consumerSecret), string.IsNullOrEmpty(tokenSecret) ? "" : UrlEncode(tokenSecret)));
327
328 return GenerateSignatureUsingHash(signatureBase, hmacsha1);
329 case SignatureTypes.RSASHA1:
330 throw new NotImplementedException();
331 default:
332 throw new ArgumentException("Unknown signature type", "signatureType");
333 }
334 }
335
336 /// <summary>
337 /// Generate the timestamp for the signature
338 /// </summary>
339 /// <returns></returns>
340 public virtual string GenerateTimeStamp()
341 {
342 // Default implementation of UNIX time of the current UTC time
343 TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
344 return Convert.ToInt64(ts.TotalSeconds).ToString();
345 }
346
347 /// <summary>
348 /// Generate a nonce
349 /// </summary>
350 /// <returns></returns>
351 public virtual string GenerateNonce()
352 {
353 // Just a simple implementation of a random number between 123400 and 9999999
354 return Random.Next(123400, 9999999).ToString();
355 }
356
357 }
358}
359\ No newline at end of file0\ No newline at end of file
3601
=== added file 'src/Canonical.Ubuntu.SSO/SSOException.cs'
--- src/Canonical.Ubuntu.SSO/SSOException.cs 1970-01-01 00:00:00 +0000
+++ src/Canonical.Ubuntu.SSO/SSOException.cs 2010-10-05 09:58:35 +0000
@@ -0,0 +1,57 @@
1/* Copyright 2010 Canonical Ltd.
2 *
3 * This file is part of UbuntuOne on Windows.
4 *
5 * UbuntuOne on Windows is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License version
7 * as published by the Free Software Foundation.
8 *
9 * Ubuntu One on Windows is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authors: Manuel de la Peña <manuel.delapena@canonical.com>
18 */
19using System;
20
21namespace Canonical.Ubuntu.SSO
22{
23 /// <summary>
24 /// Root exception class for all those SSO problems.
25 /// </summary>
26 public class SSOException : Exception
27 {
28 /// <summary>
29 /// Creates a new instance of the class with no message or inner exception.
30 /// </summary>
31 public SSOException()
32 {
33
34 }
35
36 /// <summary>
37 /// Creates a new instance of the class with the given message.
38 /// </summary>
39 /// <param name="message">The message to be carried by the exception.</param>
40 public SSOException(string message)
41 : base(message)
42 {
43
44 }
45
46 /// <summary>
47 /// Creates a new instance of the class with the given message and inner exception.
48 /// </summary>
49 /// <param name="message">The message to be carried by the exception.</param>
50 /// <param name="e">The inner exception.</param>
51 public SSOException(string message, Exception e)
52 : base(message, e)
53 {
54
55 }
56 }
57}
058
=== added file 'src/Canonical.Ubuntu.SSO/SSOLoginException.cs'
--- src/Canonical.Ubuntu.SSO/SSOLoginException.cs 1970-01-01 00:00:00 +0000
+++ src/Canonical.Ubuntu.SSO/SSOLoginException.cs 2010-10-05 09:58:35 +0000
@@ -0,0 +1,57 @@
1/* Copyright 2010 Canonical Ltd.
2 *
3 * This file is part of UbuntuOne on Windows.
4 *
5 * UbuntuOne on Windows is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License version
7 * as published by the Free Software Foundation.
8 *
9 * Ubuntu One on Windows is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authors: Manuel de la Peña <manuel.delapena@canonical.com>
18 */
19using System;
20
21namespace Canonical.Ubuntu.SSO
22{
23 /// <summary>
24 /// Exception thrown when there are errors during a login.
25 /// </summary>
26 public class SSOLoginException : SSOException
27 {
28 /// <summary>
29 /// Creates a new instance of the class with no message or inner exception.
30 /// </summary>
31 public SSOLoginException()
32 {
33
34 }
35
36 /// <summary>
37 /// Creates a new instance of the class with the given message.
38 /// </summary>
39 /// <param name="message">The message to be carried by the exception.</param>
40 public SSOLoginException(string message)
41 : base(message)
42 {
43
44 }
45
46 /// <summary>
47 /// Creates a new instance of the class with the given message and inner exception.
48 /// </summary>
49 /// <param name="message">The message to be carried by the exception.</param>
50 /// <param name="e">The inner exception.</param>
51 public SSOLoginException(string message, Exception e)
52 : base(message, e)
53 {
54
55 }
56 }
57}
058
=== modified file 'src/Canonical.Ubuntu.SSO/SSOLoginProcessor.cs'
--- src/Canonical.Ubuntu.SSO/SSOLoginProcessor.cs 2010-09-20 11:21:19 +0000
+++ src/Canonical.Ubuntu.SSO/SSOLoginProcessor.cs 2010-10-05 09:58:35 +0000
@@ -18,6 +18,10 @@
18 * Authors: Manuel de la Peña <manuel.delapena@canonical.com>18 * Authors: Manuel de la Peña <manuel.delapena@canonical.com>
19 */19 */
20using System;20using System;
21using System.Net;
22using Canonical.Ubuntu.SSO.Service;
23using Canonical.UbuntuOne.Common.Net;
24using Newtonsoft.Json.Linq;
2125
22namespace Canonical.Ubuntu.SSO26namespace Canonical.Ubuntu.SSO
23{27{
@@ -27,6 +31,126 @@
27 /// </summary>31 /// </summary>
28 public class SSOLoginProcessor : ISSOLoginProcessor32 public class SSOLoginProcessor : ISSOLoginProcessor
29 {33 {
34 private const string ApplicationTokenName = "Ubuntu One @ {0} (Windows)";
35 internal const string KeyringName = "Default";
36 internal const string ApplicationName = "UbuntuOne";
37
38 #region DI properties
39
40 /// <summary>
41 /// Gets and sets the Authentications rest service that is used to authenticate the user.
42 /// </summary>
43 public Authentications Authentications { get; set; }
44
45 /// <summary>
46 /// Gets and sets the keyring that will be used to store the secrets.
47 /// </summary>
48 public IKeyring Keyring { get; set; }
49
50 /// <summary>
51 /// Gets and sets the credential encoder that will be used to encode the oauth credentials
52 /// before they are saved in the keyring.
53 /// </summary>
54 public ISSOCredentialsEncoder SSOCredentialsEncoder { get; set; }
55
56 /// <summary>
57 /// Gets and sets the object that will take care of the oauth operations.
58 /// </summary>
59 public IOAuth OAuth { get; set; }
60
61 public IHttpWebRequestFactory HttpWebRequestFactory { get; set; }
62
63 #endregion
64
65 #region Helper methods}
66
67 /// <summary>
68 /// Creates an oauth request that can access a protected web resource.
69 /// </summary>
70 /// <param name="uri">The uri where the resource is found.</param>
71 /// <param name="httpMethod">The request berb to be used.</param>
72 /// <param name="consumerKey">Consumer key from oauth.</param>
73 /// <param name="consumerSecret">Consumer secret from oauth.</param>
74 /// <param name="token">Token from oauth.</param>
75 /// <param name="tokenSecret">Token secret from oauth.</param>
76 /// <returns>A webrequest that can be used to access the resource.</returns>
77 public IHttpWebRequest MakeRequest(string uri, string httpMethod, string consumerKey, string consumerSecret, string token, string tokenSecret)
78 {
79 // Form the full REST request url
80 var url = new Uri(uri);
81 string normUrl;
82 string normParams;
83
84 // get oauth header
85 var authHeader = OAuth.GenerateHeaderWithSignature(url, string.Empty, consumerKey, consumerSecret,
86 token, tokenSecret, httpMethod, OAuth.GenerateTimeStamp(), OAuth.GenerateNonce(), SSO.OAuth.SignatureTypes.HMACSHA1,
87 out normUrl, out normParams);
88
89 var request = HttpWebRequestFactory.Create(url);
90 request.Headers.Add(authHeader.Key, authHeader.Value);
91 return request;
92 }
93
94 /// <summary>
95 /// Pings the Ubuntu One server so that the SSO tokens are added to them and they know how to identify the user.
96 /// </summary>
97 /// <param name="email">The email used by the user to register to u1.</param>
98 /// <param name="consumerKey">The oauth consumer key.</param>
99 /// <param name="consumerSecret">The oauth consumer secret.</param>
100 /// <param name="token">The oauth token.</param>
101 /// <param name="tokenSecret">The oauth secret.</param>
102 private void PingUbuntuOneServer(string email, string consumerKey, string consumerSecret, string token, string tokenSecret)
103 {
104 // ping the service to make it download the tokens
105 var pingRequest = MakeRequest(Constants.PingUrl + email, "GET", consumerKey, consumerSecret,
106 token, tokenSecret);
107 try
108 {
109 pingRequest.GetResponse();
110 }
111 catch (Exception e)
112 {
113 throw new SSOException("Credentials could not be sent to Ubuntu One servers", e);
114 }
115 }
116
117 /// <summary>
118 /// Allows to parse the json that is returned by the rest service to extract that credentials.
119 /// </summary>
120 /// <param name="credentialsJson">Json that contains the credentials info.</param>
121 /// <param name="consumerKey">Out var where the oauth consumer key will be returned.</param>
122 /// <param name="consumerSecret">Out var where the oauth consumer secret will be returned.</param>
123 /// <param name="token">Out var where the oauth token secret will be returned.</param>
124 /// <param name="tokenSecret">Out var where the oauth token secret will be returned.</param>
125 private static void ParseCredentials(string credentialsJson, out string consumerKey, out string consumerSecret, out string token,
126 out string tokenSecret)
127 {
128 var credentials = JObject.Parse(credentialsJson);
129 try
130 {
131 consumerKey = (string)credentials["consumer_key"];
132 consumerSecret = (string)credentials["consumer_secret"];
133 token = (string)credentials["token"];
134 tokenSecret = (string)credentials["token_secret"];
135
136 }
137 catch (InvalidCastException e)
138 {
139 // could happen when the json is not formatted as we expected.
140 throw new SSOLoginException("Error when retrieving credentials.", e);
141 }
142 if (string.IsNullOrEmpty(consumerKey)
143 || string.IsNullOrEmpty(consumerSecret)
144 || string.IsNullOrEmpty(token)
145 || string.IsNullOrEmpty(tokenSecret))
146 {
147 // none of them can be null or empty.
148 throw new SSOLoginException("Credentials have missing values..");
149 }
150
151 }
152 #endregion
153
30 #region Implementation of ISSOLoginProcessor154 #region Implementation of ISSOLoginProcessor
31155
32 /// <summary>156 /// <summary>
@@ -61,7 +185,36 @@
61 /// <returns>A string with the sso credentials.</returns>185 /// <returns>A string with the sso credentials.</returns>
62 public string Login(string email, string password, string tokenName)186 public string Login(string email, string password, string tokenName)
63 {187 {
64 throw new NotImplementedException();188 var secret = Keyring.GetSecretByName(KeyringName, ApplicationName);
189 if (secret == null)
190 {
191 try
192 {
193 // credentials are not present in the keyring, therefore we will have to get them from the
194 // rest service
195 string token;
196 string tokenSecret;
197 string consumerKey;
198 string consumerSecret;
199
200 // the rest server returns json, we need to parse it.
201 ParseCredentials(Authentications.Authenticate(email, password, tokenName),
202 out consumerKey, out consumerSecret, out token, out tokenSecret);
203 secret = SSOCredentialsEncoder.Encode(token, tokenSecret, consumerKey, consumerSecret);
204 // ping the service to make it download the tokens
205 PingUbuntuOneServer(email, consumerKey, consumerKey, token, tokenSecret);
206 Keyring.CreateSecret(KeyringName, ApplicationName, secret);
207 }
208 catch (WebException e)
209 {
210 throw new SSOLoginException("Unable to login", e);
211 }
212 catch (Exception e)
213 {
214 throw new SSOLoginException("Unable to login", e);
215 }
216 }
217 return secret;
65 }218 }
66219
67 /// <summary>220 /// <summary>
68221
=== modified file 'src/Canonical.UbuntuOne.Client/Notification/NotificationIconPresenter.cs'
--- src/Canonical.UbuntuOne.Client/Notification/NotificationIconPresenter.cs 2010-10-05 09:58:34 +0000
+++ src/Canonical.UbuntuOne.Client/Notification/NotificationIconPresenter.cs 2010-10-05 09:58:35 +0000
@@ -1,25 +1,25 @@
1// Copyright 2010 Canonical Ltd.1/* Copyright 2010 Canonical Ltd.
2// 2 *
3// This file is part of UbuntuOne on Windows.3 * This file is part of UbuntuOne on Windows.
4// 4 *
5// UbuntuOne on Windows is free software: you can redistribute it and/or modify 5 * UbuntuOne on Windows is free software: you can redistribute it and/or modify
6// it under the terms of the GNU Lesser General Public License version 6 * it under the terms of the GNU Lesser General Public License version
7// as published by the Free Software Foundation. 7 * as published by the Free Software Foundation.
8// 8 *
9// Ubuntu One on Windows is distributed in the hope that it will be useful,9 * Ubuntu One on Windows is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU Lesser General Public License for more details. 12 * GNU Lesser General Public License for more details.
13//13 *
14// You should have received a copy of the GNU Lesser General Public License 14 * You should have received a copy of the GNU Lesser General Public License
15// along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>.15 * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>.
16// 16 *
17// Authors: Manuel de la Peña <manuel.delapena@canonical.com>17 * Authors: Manuel de la Peña <manuel.delapena@canonical.com>
18 */
18using System;19using System;
19using System.Diagnostics;20using System.Diagnostics;
20using System.IO;21using System.IO;
21using System.Net;22using System.Net;
22using System.Web;
23using System.Windows;23using System.Windows;
24using Canonical.Ubuntu.SSO;24using Canonical.Ubuntu.SSO;
25using Canonical.Ubuntu.SSO.Service;25using Canonical.Ubuntu.SSO.Service;
@@ -29,7 +29,6 @@
29using Canonical.UbuntuOne.Common.Utils;29using Canonical.UbuntuOne.Common.Utils;
30using log4net;30using log4net;
31using Newtonsoft.Json.Linq;31using Newtonsoft.Json.Linq;
32using OAuth;
3332
34namespace Canonical.UbuntuOne.Client.Notification33namespace Canonical.UbuntuOne.Client.Notification
35{34{
@@ -148,33 +147,23 @@
148147
149 #region Helper methods148 #region Helper methods
150149
151 public HttpWebRequest MakeRequest(string uri, string consumerKey, string consumerSecret, string toke, string tokenSecret)150 public HttpWebRequest MakeRequest(string uri, string consumerKey, string consumerSecret, string token, string tokenSecret)
152 {151 {
153 // Form the full REST request url152 // Form the full REST request url
154 Uri url = new Uri(uri);153 Uri url = new Uri(uri);
155154
156 // Instantiate OAuthBase and declare variables155 // Instantiate OAuthBase and declare variables
157 var oAuth = new OAuthBase();156 var oAuth = new OAuth();
158 var nonce = oAuth.GenerateNonce();157
159 var timeStamp = oAuth.GenerateTimeStamp();
160 var normUrl = string.Empty;158 var normUrl = string.Empty;
161 var normParams = string.Empty;159 var normParams = string.Empty;
162 var strRequest = string.Empty;
163160
164 // Create an OAuth signature161 var authHeader = oAuth.GenerateHeaderWithSignature(url, string.Empty, consumerKey, consumerSecret,
165 string signature = oAuth.GenerateSignature(url,162 token, tokenSecret, "GET", oAuth.GenerateTimeStamp(), oAuth.GenerateNonce(), OAuth.SignatureTypes.HMACSHA1,
166 consumerKey, consumerSecret, toke, tokenSecret,
167 "GET", timeStamp, nonce, OAuthBase.SignatureTypes.HMACSHA1,
168 out normUrl, out normParams);163 out normUrl, out normParams);
169164
170 // Construct the OAuth authenticated REST url
171 strRequest = normParams + "&" + HttpUtility.UrlEncode("oauth_signature") + "=" + HttpUtility.UrlEncode(signature);
172 strRequest = strRequest.Replace("&", @""",");
173 strRequest = strRequest.Replace("=", @"=""");
174 strRequest += @"""";
175 strRequest = @"OAuth realm=""""," + strRequest;
176 var request = WebRequest.Create(normUrl) as HttpWebRequest;165 var request = WebRequest.Create(normUrl) as HttpWebRequest;
177 request.Headers.Add("Authorization", strRequest);166 request.Headers.Add(authHeader.Key, authHeader.Value);
178 return request;167 return request;
179 }168 }
180169
181170
=== modified file 'src/Canonical.UbuntuOne.Common/Canonical.UbuntuOne.Common.csproj'
--- src/Canonical.UbuntuOne.Common/Canonical.UbuntuOne.Common.csproj 2010-08-30 17:30:31 +0000
+++ src/Canonical.UbuntuOne.Common/Canonical.UbuntuOne.Common.csproj 2010-10-05 09:58:35 +0000
@@ -57,6 +57,10 @@
57 <Compile Include="Container\ObjectsContainer.cs" />57 <Compile Include="Container\ObjectsContainer.cs" />
58 <Compile Include="Container\SpringContainer.cs" />58 <Compile Include="Container\SpringContainer.cs" />
59 <Compile Include="Container\UnsatisfiedDependencyException.cs" />59 <Compile Include="Container\UnsatisfiedDependencyException.cs" />
60 <Compile Include="Net\HttpWebRequest.cs" />
61 <Compile Include="Net\HttpWebRequestFactory.cs" />
62 <Compile Include="Net\IHttpWebRequestFactory.cs" />
63 <Compile Include="Net\IHttpWebRequest.cs" />
60 <Compile Include="OperationContracts\IEventNotifier.cs" />64 <Compile Include="OperationContracts\IEventNotifier.cs" />
61 <Compile Include="Security\IAuthentication.cs" />65 <Compile Include="Security\IAuthentication.cs" />
62 <Compile Include="Threading\IDispatcher.cs" />66 <Compile Include="Threading\IDispatcher.cs" />
6367
=== added directory 'src/Canonical.UbuntuOne.Common/Net'
=== added file 'src/Canonical.UbuntuOne.Common/Net/HttpWebRequest.cs'
--- src/Canonical.UbuntuOne.Common/Net/HttpWebRequest.cs 1970-01-01 00:00:00 +0000
+++ src/Canonical.UbuntuOne.Common/Net/HttpWebRequest.cs 2010-10-05 09:58:35 +0000
@@ -0,0 +1,505 @@
1/*
2 * Copyright 2010 Canonical Ltd.
3 *
4 * This file is part of UbuntuOne on Windows.
5 *
6 * UbuntuOne on Windows is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License version
8 * as published by the Free Software Foundation.
9 *
10 * Ubuntu One on Windows is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Manuel de la Peña <manuel.delapena@canonical.com>
19 */
20using System;
21using System.IO;
22using System.Net;
23using System.Net.Cache;
24using System.Net.Security;
25using System.Security.Cryptography.X509Certificates;
26using System.Security.Principal;
27using RealHttpRequest = System.Net.HttpWebRequest;
28
29namespace Canonical.UbuntuOne.Common.Net
30{
31 /// <summary>
32 /// Wrapper around the System.Net.HttpWebRequest.
33 /// </summary>
34 internal class HttpWebRequest : IHttpWebRequest
35 {
36 #region Variables
37
38 private RealHttpRequest _request;
39
40 #endregion
41
42 #region Constructors
43
44 /// <summary>
45 /// Internal constructor that can only be used by a httpweb request factory.
46 /// </summary>
47 /// <param name="httpWebRequest"></param>
48 internal HttpWebRequest(RealHttpRequest httpWebRequest)
49 {
50 _request = httpWebRequest;
51 }
52
53 #endregion
54
55 #region Implementation of IHttpWebRequest
56
57 /// <summary>
58 /// Gets and sets value of the Accept HTTP header. The default value is null.
59 /// </summary>
60 public string Accept
61 {
62 get { return _request.Accept; }
63 set { _request.Accept = value; }
64 }
65
66 /// <summary>
67 /// Gets and sets the uri that responds to the request.
68 /// </summary>
69 public Uri Address
70 {
71 get { return _request.Address; }
72 }
73
74 /// <summary>
75 /// Gets and sets if the request should automatically follow redirection responses
76 /// </summary>
77 public bool AllowAutoRedirect
78 {
79 get { return _request.AllowAutoRedirect; }
80 set { _request.AllowAutoRedirect = value; }
81 }
82
83 /// <summary>
84 /// Enables buffering of the data sent to the Internet resource
85 /// </summary>
86 public bool AllowWriteStreamBuffering
87 {
88 get { return _request.AllowWriteStreamBuffering; }
89 set { _request.AllowWriteStreamBuffering = value; }
90 }
91
92 /// <summary>
93 /// Gets and sets the auhentication lavel used.
94 /// </summary>
95 public AuthenticationLevel AuthenticationLevel
96 {
97 get { return _request.AuthenticationLevel; }
98 set { _request.AuthenticationLevel = value; }
99 }
100
101 /// <summary>
102 /// Gets and sets the type of decompression that is used.
103 /// </summary>
104 public DecompressionMethods AutomaticDecompression
105 {
106 get { return _request.AutomaticDecompression; }
107 set { _request.AutomaticDecompression = value; }
108 }
109
110 /// <summary>
111 /// Gets or sets the cache policy used by the request.
112 /// </summary>
113 public RequestCachePolicy CachePolicy
114 {
115 get { return _request.CachePolicy; }
116 set { _request.CachePolicy = value; }
117 }
118
119 /// <summary>
120 /// Gets and sets the certificates used by the request.
121 /// </summary>
122 public X509CertificateCollection ClientCertificates
123 {
124 get { return _request.ClientCertificates; }
125 set { _request.ClientCertificates = value; }
126 }
127
128 /// <summary>
129 /// Gets and sets the Connection HTTP header
130 /// </summary>
131 public string Connection
132 {
133 get { return _request.Connection; }
134 set { _request.Connection = value; }
135 }
136
137 /// <summary>
138 /// Gets and sets the name of the connection group for this request
139 /// </summary>
140 public string ConnectionGroupName
141 {
142 get { return _request.ConnectionGroupName; }
143 set { _request.ConnectionGroupName = value; }
144 }
145
146 /// <summary>
147 /// Gets and sets the number of bytes of data to send to the Internet resource.
148 /// </summary>
149 public long ContentLength
150 {
151 get { return _request.ContentLength; }
152 set { _request.ContentLength = value; }
153 }
154
155 /// <summary>
156 /// Gets and sets the content type of the request.
157 /// </summary>
158 public string ContentType
159 {
160 get { return _request.ContentType; }
161 set { _request.ContentType = value; }
162 }
163
164 /// <summary>
165 /// Gets and sets the delegate that implements the callback method that
166 /// executes when an HTTP Continue response is returned from the Internet resource.
167 /// </summary>
168 public HttpContinueDelegate ContinueDelegate
169 {
170 get { return _request.ContinueDelegate; }
171 set { _request.ContinueDelegate = value; }
172 }
173
174 /// <summary>
175 /// Gets and sets cookies container associated with this request.
176 /// </summary>
177 public CookieContainer CookieContainer
178 {
179 get { return _request.CookieContainer; }
180 set { _request.CookieContainer = value; }
181 }
182
183 /// <summary>
184 /// Gets and sets the credentials used with the request.
185 /// </summary>
186 public ICredentials Credentials
187 {
188 get { return _request.Credentials; }
189 set { _request.Credentials = value; }
190 }
191
192 /// <summary>
193 /// Gets and sets the data header of the request.
194 /// </summary>
195 public DateTime Date
196 {
197 get { throw new NotImplementedException(); }
198 set { throw new NotImplementedException(); }
199 }
200
201 /// <summary>
202 /// Gets and sets the Expect HTTP header.
203 /// </summary>
204 public string Expect
205 {
206 get { return _request.Expect; }
207 set { _request.Expect = value; }
208 }
209
210 /// <summary>
211 /// Gets if a response has been received.
212 /// </summary>
213 public bool HaveResponse
214 {
215 get { return _request.HaveResponse; }
216 }
217
218 /// <summary>
219 /// Gets and sets the headers of the request,
220 /// </summary>
221 public WebHeaderCollection Headers
222 {
223 get { return _request.Headers; }
224 set { _request.Headers = value; }
225 }
226
227 /// <summary>
228 /// Gets and sets the Host header.
229 /// </summary>
230 public string Host
231 {
232 get { throw new NotImplementedException(); }
233 set { throw new NotImplementedException(); }
234 }
235
236 /// <summary>
237 /// A DateTime that contains the contents of the If-Modified-Since HTTP header.
238 /// </summary>
239 public DateTime IfModifiedSince
240 {
241 get { return _request.IfModifiedSince; }
242 set { _request.IfModifiedSince = value; }
243 }
244
245 /// <summary>
246 /// Gets and sets the the impersonation level.
247 /// </summary>
248 public TokenImpersonationLevel ImpersonationLevel
249 {
250 get { return _request.ImpersonationLevel; }
251 set { _request.ImpersonationLevel = value; }
252 }
253
254 /// <summary>
255 /// Gets and sets if the request should have a Connection HTTP header.
256 /// </summary>
257 public bool KeepAlive
258 {
259 get { return _request.KeepAlive; }
260 set { _request.KeepAlive = value; }
261 }
262
263 /// <summary>
264 /// Gets and sets the max number of redirections.
265 /// </summary>
266 public int MaximumAutomaticRedirections
267 {
268 get { return _request.MaximumAutomaticRedirections; }
269 set { _request.MaximumAutomaticRedirections = value; }
270 }
271
272 /// <summary>
273 /// Gets and sets The length, in kilobytes (1024 bytes), of the response headers.
274 /// </summary>
275 public int MaximumResponseHeadersLength
276 {
277 get { return _request.MaximumResponseHeadersLength; }
278 set { _request.MaximumResponseHeadersLength = value; }
279 }
280
281 /// <summary>
282 /// The media type of the request.
283 /// </summary>
284 public string MediaType
285 {
286 get { return _request.MediaType; }
287 set { _request.MediaType = value; }
288 }
289
290 /// <summary>
291 /// Gets and sets the request method.
292 /// </summary>
293 public string Method
294 {
295 get { return _request.Method; }
296 set { _request.Method = value; }
297 }
298
299 /// <summary>
300 /// Gets and sets if the request should be pipelined
301 /// </summary>
302 public bool Pipelined
303 {
304 get { return _request.Pipelined; }
305 set { _request.Pipelined = value; }
306 }
307
308 /// <summary>
309 /// Gets and sets if an HTTP Authorization header with requests after authentication has taken place;
310 /// </summary>
311 public bool PreAuthenticate
312 {
313 get { return _request.PreAuthenticate; }
314 set { _request.PreAuthenticate = value; }
315 }
316
317 /// <summary>
318 /// Gets and sets the protol version used.
319 /// </summary>
320 public Version ProtocolVersion
321 {
322 get { return _request.ProtocolVersion; }
323 set { _request.ProtocolVersion = value; }
324 }
325
326 /// <summary>
327 /// Gets and sets the proxy information.
328 /// </summary>
329 public IWebProxy Proxy
330 {
331 get { return _request.Proxy; }
332 set { _request.Proxy = value; }
333 }
334
335 /// <summary>
336 /// Gets and sets the number of milliseconds before the writing or reading times out..
337 /// </summary>
338 public int ReadWriteTimeout
339 {
340 get { return _request.ReadWriteTimeout; }
341 set { _request.ReadWriteTimeout = value; }
342 }
343
344 /// <summary>
345 /// Gets and sets the Referer HTTP header.
346 /// </summary>
347 public string Referer
348 {
349 get { return _request.Referer; }
350 set { _request.Referer = value; }
351 }
352
353 /// <summary>
354 /// Gets the resource uri used by the request.
355 /// </summary>
356 public Uri RequestUri
357 {
358 get { return _request.RequestUri; }
359 }
360
361 /// <summary>
362 /// Ges and sets if the request should be sent in chuckes.
363 /// </summary>
364 public bool SendChunked
365 {
366 get { return _request.SendChunked; }
367 set { _request.SendChunked = value; }
368 }
369
370 /// <summary>
371 /// Gets the service point that represents the internet resource.
372 /// </summary>
373 public ServicePoint ServicePoint
374 {
375 get { return _request.ServicePoint; }
376 }
377
378 /// <summary>
379 /// Gets and sets the number of milliseconds to wait before the request times out.
380 /// </summary>
381 public int Timeout
382 {
383 get { return _request.Timeout; }
384 set { _request.Timeout = value; }
385 }
386
387 /// <summary>
388 /// Gets and sets the Transfer-encoding HTTP header.
389 /// </summary>
390 public string TransferEncoding
391 {
392 get { return _request.TransferEncoding; }
393 set { _request.TransferEncoding = value; }
394 }
395
396 /// <summary>
397 /// Gets and sets if the authenticated connection is kept opened.
398 /// </summary>
399 public bool UnsafeAuthenticatedConnectionSharing
400 {
401 get { return _request.UnsafeAuthenticatedConnectionSharing; }
402 set { _request.UnsafeAuthenticatedConnectionSharing = value; }
403 }
404
405 /// <summary>
406 /// Gets and sets if the default credentials are used.
407 /// </summary>
408 public bool UseDefaultCredentials
409 {
410 get { return _request.UseDefaultCredentials; }
411 set { _request.UseDefaultCredentials = value; }
412 }
413
414 /// <summary>
415 /// Gets or sets the User-agent HTTP header;
416 /// </summary>
417 public string UserAgent
418 {
419 get { return _request.UserAgent; }
420 set { _request.UserAgent = value; }
421 }
422
423 /// <summary>
424 /// Cancels a request to a resource
425 /// </summary>
426 public void Abort()
427 {
428 _request.Abort();
429 }
430
431 /// <summary>
432 /// Begins an asynchronous request for a Stream object to use to write data.
433 /// </summary>
434 /// <param name="callback">The delegate to execute.</param>
435 /// <param name="state">Teh state object of the request. </param>
436 /// <returns>An async result.</returns>
437 public IAsyncResult BeginGetRequestStream(AsyncCallback callback, object state)
438 {
439 return _request.BeginGetRequestStream(callback, state);
440 }
441
442 /// <summary>
443 /// Begins an asynchronous request to an Internet resource.
444 /// </summary>
445 /// <param name="callback">Teh deleaget.</param>
446 /// <param name="state">Teh state object fo the response.</param>
447 /// <returns>an asyn result.</returns>
448 public IAsyncResult BeginGetResponse(AsyncCallback callback, object state)
449 {
450 return _request.BeginGetResponse(callback, state);
451 }
452
453 /// <summary>
454 /// Ends an asynchronous request for a Stream object to use to write data.
455 /// </summary>
456 /// <param name="asyncResult">The result from the async request.</param>
457 /// <returns>Teh stream from teh request.</returns>
458 public Stream EndGetRequestStream(IAsyncResult asyncResult)
459 {
460 return EndGetRequestStream(asyncResult);
461 }
462
463 /// <summary>
464 /// Ends an asynchronous request for a Stream object to use to write data and outputs
465 /// the TransportContext associated with the stream.
466 /// </summary>
467 /// <param name="asyncResult">The async result from the request stream.</param>
468 /// <param name="context">The context of the request.</param>
469 /// <returns>The request stream.</returns>
470 public Stream EndGetRequestStream(IAsyncResult asyncResult, out TransportContext context)
471 {
472 return _request.EndGetRequestStream(asyncResult, out context);
473 }
474
475 /// <summary>
476 /// Ends an asynchronous request to an Internet resource.
477 /// </summary>
478 /// <param name="asyncResult">The async result from the asyn response.</param>
479 /// <returns>Teh response frm the internet resource.</returns>
480 public WebResponse EndGetResponse(IAsyncResult asyncResult)
481 {
482 return _request.EndGetResponse(asyncResult);
483 }
484
485 /// <summary>
486 /// Gets a Stream object to use to write request data.
487 /// </summary>
488 /// <returns>Teh stream to which write the request.</returns>
489 public Stream GetRequestStream()
490 {
491 return _request.GetRequestStream();
492 }
493
494 /// <summary>
495 /// Returns a response from an Internet resource.
496 /// </summary>
497 /// <returns>Teh response from the resource.</returns>
498 public WebResponse GetResponse()
499 {
500 return _request.GetResponse();
501 }
502
503 #endregion
504 }
505}
0506
=== added file 'src/Canonical.UbuntuOne.Common/Net/HttpWebRequestFactory.cs'
--- src/Canonical.UbuntuOne.Common/Net/HttpWebRequestFactory.cs 1970-01-01 00:00:00 +0000
+++ src/Canonical.UbuntuOne.Common/Net/HttpWebRequestFactory.cs 2010-10-05 09:58:35 +0000
@@ -0,0 +1,59 @@
1/*
2 * Copyright 2010 Canonical Ltd.
3 *
4 * This file is part of UbuntuOne on Windows.
5 *
6 * UbuntuOne on Windows is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License version
8 * as published by the Free Software Foundation.
9 *
10 * Ubuntu One on Windows is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Manuel de la Peña <manuel.delapena@canonical.com>
19 */
20using System;
21using System.Net;
22using RealHttpRequest = System.Net.HttpWebRequest;
23
24namespace Canonical.UbuntuOne.Common.Net
25{
26 /// <summary>
27 /// Class that creates IHttpWebRequest that can be used to request an internet resource.
28 /// </summary>
29 internal class HttpWebRequestFactory : IHttpWebRequestFactory
30 {
31 #region Implementation of IHttpWebRequestFactory
32
33 /// <summary>
34 /// Creates a new webrequest that will be used to request an internet resource that is identified
35 /// by the given uri.
36 /// </summary>
37 /// <param name="uri">A string with the uri that identifies the internet resource.</param>
38 /// <returns>An IHttpWebRequest that can be used to request an internet resource.</returns>
39 public IHttpWebRequest Create(string uri)
40 {
41 var realRequest = WebRequest.Create(uri) as RealHttpRequest;
42 return new HttpWebRequest(realRequest);
43 }
44
45 /// <summary>
46 /// Creates a webrequest that will be used to request an internet resource that is identified by
47 /// the given uri.
48 /// </summary>
49 /// <param name="uri">An object that identifies the web request.</param>
50 /// <returns>An HttpWebRequest that can be used to request an internet resource.</returns>
51 public IHttpWebRequest Create(Uri uri)
52 {
53 var realRequest = WebRequest.Create(uri) as RealHttpRequest;
54 return new HttpWebRequest(realRequest);
55 }
56
57 #endregion
58 }
59}
060
=== added file 'src/Canonical.UbuntuOne.Common/Net/IHttpWebRequest.cs'
--- src/Canonical.UbuntuOne.Common/Net/IHttpWebRequest.cs 1970-01-01 00:00:00 +0000
+++ src/Canonical.UbuntuOne.Common/Net/IHttpWebRequest.cs 2010-10-05 09:58:35 +0000
@@ -0,0 +1,297 @@
1/*
2 * Copyright 2010 Canonical Ltd.
3 *
4 * This file is part of UbuntuOne on Windows.
5 *
6 * UbuntuOne on Windows is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License version
8 * as published by the Free Software Foundation.
9 *
10 * Ubuntu One on Windows is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Manuel de la Peña <manuel.delapena@canonical.com>
19 */
20using System;
21using System.IO;
22using System.Net;
23using System.Net.Cache;
24using System.Net.Security;
25using System.Security.Cryptography.X509Certificates;
26using System.Security.Principal;
27
28namespace Canonical.UbuntuOne.Common.Net
29{
30 /// <summary>
31 /// Helper interface that wrapps the HttpWebRequest class from System.Net
32 /// </summary>
33 public interface IHttpWebRequest
34 {
35 /// <summary>
36 /// Gets and sets value of the Accept HTTP header. The default value is null.
37 /// </summary>
38 string Accept { get; set; }
39
40 /// <summary>
41 /// Gets and sets the uri that responds to the request.
42 /// </summary>
43 Uri Address { get; }
44
45 /// <summary>
46 /// Gets and sets if the request should automatically follow redirection responses
47 /// </summary>
48 bool AllowAutoRedirect { get; set; }
49
50 /// <summary>
51 /// Enables buffering of the data sent to the Internet resource
52 /// </summary>
53 bool AllowWriteStreamBuffering { get; set; }
54
55 /// <summary>
56 /// Gets and sets the auhentication lavel used.
57 /// </summary>
58 AuthenticationLevel AuthenticationLevel { get; set; }
59
60 /// <summary>
61 /// Gets and sets the type of decompression that is used.
62 /// </summary>
63 DecompressionMethods AutomaticDecompression { get; set; }
64
65 /// <summary>
66 /// Gets or sets the cache policy used by the request.
67 /// </summary>
68 RequestCachePolicy CachePolicy { get; set; }
69
70 /// <summary>
71 /// Gets and sets the certificates used by the request.
72 /// </summary>
73 X509CertificateCollection ClientCertificates { get; set; }
74
75 /// <summary>
76 /// Gets and sets the Connection HTTP header
77 /// </summary>
78 string Connection { get; set; }
79
80 /// <summary>
81 /// Gets and sets the name of the connection group for this request
82 /// </summary>
83 string ConnectionGroupName { get; set; }
84
85 /// <summary>
86 /// Gets and sets the number of bytes of data to send to the Internet resource.
87 /// </summary>
88 long ContentLength { get; set; }
89
90 /// <summary>
91 /// Gets and sets the content type of the request.
92 /// </summary>
93 string ContentType { get; set; }
94
95 /// <summary>
96 /// Gets and sets the delegate that implements the callback method that
97 /// executes when an HTTP Continue response is returned from the Internet resource.
98 /// </summary>
99 HttpContinueDelegate ContinueDelegate { get; set; }
100
101 /// <summary>
102 /// Gets and sets cookies container associated with this request.
103 /// </summary>
104 CookieContainer CookieContainer { get; set; }
105
106 /// <summary>
107 /// Gets and sets the credentials used with the request.
108 /// </summary>
109 ICredentials Credentials { get; set; }
110
111 /// <summary>
112 /// Gets and sets the data header of the request.
113 /// </summary>
114 DateTime Date { get; set; }
115
116 /// <summary>
117 /// Gets and sets the Expect HTTP header.
118 /// </summary>
119 string Expect { get; set; }
120
121 /// <summary>
122 /// Gets if a response has been received.
123 /// </summary>
124 bool HaveResponse { get; }
125
126 /// <summary>
127 /// Gets and sets the headers of the request,
128 /// </summary>
129 WebHeaderCollection Headers { get; set; }
130
131 /// <summary>
132 /// Gets and sets the Host header.
133 /// </summary>
134 string Host { get; set; }
135
136 /// <summary>
137 /// A DateTime that contains the contents of the If-Modified-Since HTTP header.
138 /// </summary>
139 DateTime IfModifiedSince { get; set; }
140
141 /// <summary>
142 /// Gets and sets the the impersonation level.
143 /// </summary>
144 TokenImpersonationLevel ImpersonationLevel { get; set; }
145
146 /// <summary>
147 /// Gets and sets if the request should have a Connection HTTP header.
148 /// </summary>
149 bool KeepAlive { get; set; }
150
151 /// <summary>
152 /// Gets and sets the max number of redirections.
153 /// </summary>
154 int MaximumAutomaticRedirections { get; set; }
155
156 /// <summary>
157 /// Gets and sets The length, in kilobytes (1024 bytes), of the response headers.
158 /// </summary>
159 int MaximumResponseHeadersLength { get; set; }
160
161 /// <summary>
162 /// The media type of the request.
163 /// </summary>
164 string MediaType { get; set; }
165
166 /// <summary>
167 /// Gets and sets the request method.
168 /// </summary>
169 string Method { get; set; }
170
171 /// <summary>
172 /// Gets and sets if the request should be pipelined
173 /// </summary>
174 bool Pipelined { get; set; }
175
176 /// <summary>
177 /// Gets and sets if an HTTP Authorization header with requests after authentication has taken place;
178 /// </summary>
179 bool PreAuthenticate { get; set; }
180
181 /// <summary>
182 /// Gets and sets the protol version used.
183 /// </summary>
184 Version ProtocolVersion { get; set; }
185
186 /// <summary>
187 /// Gets and sets the proxy information.
188 /// </summary>
189 IWebProxy Proxy { get; set; }
190
191 /// <summary>
192 /// Gets and sets the number of milliseconds before the writing or reading times out..
193 /// </summary>
194 int ReadWriteTimeout { get; set; }
195
196 /// <summary>
197 /// Gets and sets the Referer HTTP header.
198 /// </summary>
199 string Referer { get; set; }
200
201 /// <summary>
202 /// Gets the resource uri used by the request.
203 /// </summary>
204 Uri RequestUri { get; }
205
206 /// <summary>
207 /// Ges and sets if the request should be sent in chuckes.
208 /// </summary>
209 bool SendChunked { get; set; }
210
211 /// <summary>
212 /// Gets the service point that represents the internet resource.
213 /// </summary>
214 ServicePoint ServicePoint { get; }
215
216 /// <summary>
217 /// Gets and sets the number of milliseconds to wait before the request times out.
218 /// </summary>
219 int Timeout { get; set; }
220
221 /// <summary>
222 /// Gets and sets the Transfer-encoding HTTP header.
223 /// </summary>
224 string TransferEncoding { get; set; }
225
226 /// <summary>
227 /// Gets and sets if the authenticated connection is kept opened.
228 /// </summary>
229 bool UnsafeAuthenticatedConnectionSharing { get; set; }
230
231 /// <summary>
232 /// Gets and sets if the default credentials are used.
233 /// </summary>
234 bool UseDefaultCredentials { get; set; }
235
236 /// <summary>
237 /// Gets or sets the User-agent HTTP header;
238 /// </summary>
239 string UserAgent { get; set; }
240
241 /// <summary>
242 /// Cancels a request to a resource
243 /// </summary>
244 void Abort();
245
246 /// <summary>
247 /// Begins an asynchronous request for a Stream object to use to write data.
248 /// </summary>
249 /// <param name="callback">The delegate to execute.</param>
250 /// <param name="state">Teh state object of the request. </param>
251 /// <returns>An async result.</returns>
252 IAsyncResult BeginGetRequestStream(AsyncCallback callback,Object state);
253
254 /// <summary>
255 /// Begins an asynchronous request to an Internet resource.
256 /// </summary>
257 /// <param name="callback">Teh deleaget.</param>
258 /// <param name="state">Teh state object fo the response.</param>
259 /// <returns>an asyn result.</returns>
260 IAsyncResult BeginGetResponse(AsyncCallback callback,Object state);
261
262 /// <summary>
263 /// Ends an asynchronous request for a Stream object to use to write data.
264 /// </summary>
265 /// <param name="asyncResult">The result from the async request.</param>
266 /// <returns>Teh stream from teh request.</returns>
267 Stream EndGetRequestStream(IAsyncResult asyncResult);
268
269 /// <summary>
270 /// Ends an asynchronous request for a Stream object to use to write data and outputs
271 /// the TransportContext associated with the stream.
272 /// </summary>
273 /// <param name="asyncResult">The async result from the request stream.</param>
274 /// <param name="context">The context of the request.</param>
275 /// <returns>The request stream.</returns>
276 Stream EndGetRequestStream(IAsyncResult asyncResult,out TransportContext context);
277
278 /// <summary>
279 /// Ends an asynchronous request to an Internet resource.
280 /// </summary>
281 /// <param name="asyncResult">The async result from the asyn response.</param>
282 /// <returns>Teh response frm the internet resource.</returns>
283 WebResponse EndGetResponse(IAsyncResult asyncResult);
284
285 /// <summary>
286 /// Gets a Stream object to use to write request data.
287 /// </summary>
288 /// <returns>Teh stream to which write the request.</returns>
289 Stream GetRequestStream();
290
291 /// <summary>
292 /// Returns a response from an Internet resource.
293 /// </summary>
294 /// <returns>Teh response from the resource.</returns>
295 WebResponse GetResponse();
296 }
297}
0298
=== added file 'src/Canonical.UbuntuOne.Common/Net/IHttpWebRequestFactory.cs'
--- src/Canonical.UbuntuOne.Common/Net/IHttpWebRequestFactory.cs 1970-01-01 00:00:00 +0000
+++ src/Canonical.UbuntuOne.Common/Net/IHttpWebRequestFactory.cs 2010-10-05 09:58:35 +0000
@@ -0,0 +1,45 @@
1/*
2 * Copyright 2010 Canonical Ltd.
3 *
4 * This file is part of UbuntuOne on Windows.
5 *
6 * UbuntuOne on Windows is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License version
8 * as published by the Free Software Foundation.
9 *
10 * Ubuntu One on Windows is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Manuel de la Peña <manuel.delapena@canonical.com>
19 */
20using System;
21
22namespace Canonical.UbuntuOne.Common.Net
23{
24 /// <summary>
25 /// Simple interface to be implemented by those objects that are able to create web requests.
26 /// </summary>
27 public interface IHttpWebRequestFactory
28 {
29 /// <summary>
30 /// Creates a new webrequest that will be used to request an internet resource that is identified
31 /// by the given uri.
32 /// </summary>
33 /// <param name="uri">A string with the uri that identifies the internet resource.</param>
34 /// <returns>An IHttpWebRequest that can be used to request an internet resource.</returns>
35 IHttpWebRequest Create(string uri);
36
37 /// <summary>
38 /// Creates a webrequest that will be used to request an internet resource that is identified by
39 /// the given uri.
40 /// </summary>
41 /// <param name="uri">An object that identifies the web request.</param>
42 /// <returns>An HttpWebRequest that can be used to request an internet resource.</returns>
43 IHttpWebRequest Create(Uri uri);
44 }
45}

Subscribers

People subscribed via source and target branches

to all changes: