Merge lp:~mandel/ubuntuone-windows-installer/refactor_sso into lp:ubuntuone-windows-installer/beta
- refactor_sso
- Merge into 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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Rick McBride (community) | Approve | ||
John Lenton (community) | Approve | ||
Review via email:
|
Commit message
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
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
John Lenton (chipaca) : | # |
review:
Approve
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Rick McBride (rmcbride) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/Canonical.Ubuntu.SSO.Tests/Canonical.Ubuntu.SSO.Tests.csproj' |
2 | --- src/Canonical.Ubuntu.SSO.Tests/Canonical.Ubuntu.SSO.Tests.csproj 2010-10-05 09:58:34 +0000 |
3 | +++ src/Canonical.Ubuntu.SSO.Tests/Canonical.Ubuntu.SSO.Tests.csproj 2010-10-05 09:58:35 +0000 |
4 | @@ -48,14 +48,21 @@ |
5 | <Reference Include="System.Xml" /> |
6 | </ItemGroup> |
7 | <ItemGroup> |
8 | + <Compile Include="ColonSeparatedSSOCredentialsEncoderFixture.cs" /> |
9 | + <Compile Include="JsonSSOCredentialsEncoderFixture.cs" /> |
10 | <Compile Include="KeyringFixture.cs" /> |
11 | <Compile Include="Properties\AssemblyInfo.cs" /> |
12 | + <Compile Include="SSOLoginProcessorFixture.cs" /> |
13 | </ItemGroup> |
14 | <ItemGroup> |
15 | <ProjectReference Include="..\Canonical.Ubuntu.SSO\Canonical.Ubuntu.SSO.csproj"> |
16 | <Project>{9460A771-2589-45DA-9618-9FE8BB7D16E8}</Project> |
17 | <Name>Canonical.Ubuntu.SSO</Name> |
18 | </ProjectReference> |
19 | + <ProjectReference Include="..\Canonical.UbuntuOne.Common\Canonical.UbuntuOne.Common.csproj"> |
20 | + <Project>{11353FF8-8E5A-488E-9CB1-873DADD232B9}</Project> |
21 | + <Name>Canonical.UbuntuOne.Common</Name> |
22 | + </ProjectReference> |
23 | </ItemGroup> |
24 | <ItemGroup> |
25 | <Folder Include="Service\" /> |
26 | |
27 | === added file 'src/Canonical.Ubuntu.SSO.Tests/ColonSeparatedSSOCredentialsEncoderFixture.cs' |
28 | --- src/Canonical.Ubuntu.SSO.Tests/ColonSeparatedSSOCredentialsEncoderFixture.cs 1970-01-01 00:00:00 +0000 |
29 | +++ src/Canonical.Ubuntu.SSO.Tests/ColonSeparatedSSOCredentialsEncoderFixture.cs 2010-10-05 09:58:35 +0000 |
30 | @@ -0,0 +1,69 @@ |
31 | +/* Copyright 2010 Canonical Ltd. |
32 | + * |
33 | + * This file is part of UbuntuOne on Windows. |
34 | + * |
35 | + * UbuntuOne on Windows is free software: you can redistribute it and/or modify |
36 | + * it under the terms of the GNU Lesser General Public License version |
37 | + * as published by the Free Software Foundation. |
38 | + * |
39 | + * Ubuntu One on Windows is distributed in the hope that it will be useful, |
40 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
41 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
42 | + * GNU Lesser General Public License for more details. |
43 | + * |
44 | + * You should have received a copy of the GNU Lesser General Public License |
45 | + * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>. |
46 | + * |
47 | + * Authors: Manuel de la Peña <manuel.delapena@canonical.com> |
48 | + */ |
49 | +using NUnit.Framework; |
50 | + |
51 | +namespace Canonical.Ubuntu.SSO.Tests |
52 | +{ |
53 | + [TestFixture] |
54 | + public class ColonSeparatedSSOCredentialsEncoderFixture |
55 | + { |
56 | + #region Variables |
57 | + |
58 | + private ColonSeparatedSSOCredentialsEncoder _encoder; |
59 | + |
60 | + #endregion |
61 | + |
62 | + #region Setup & TearDown |
63 | + |
64 | + [SetUp] |
65 | + public void Setup() |
66 | + { |
67 | + _encoder = new ColonSeparatedSSOCredentialsEncoder(); |
68 | + } |
69 | + #endregion |
70 | + |
71 | + #region Tests |
72 | + |
73 | + [TestCase("firstToken:firstTokenSecret:firstConsumer:firstConsumerSecret", "firstToken", "firstTokenSecret", "firstConsumer", "firstConsumerSecret")] |
74 | + [TestCase("ad180jjd733klru7:hdhd0244k9j7ao03:dpf43f3p2l4k3l03:djr9rjt0jd78jf88%26", "ad180jjd733klru7", "hdhd0244k9j7ao03", "dpf43f3p2l4k3l03", "djr9rjt0jd78jf88%26")] |
75 | + public void EncodeTest(string expected, string token, string tokenSecret, string consumerKey, string consumerSecret) |
76 | + { |
77 | + Assert.AreEqual(expected, _encoder.Encode(token, tokenSecret, consumerKey, consumerSecret)); |
78 | + } |
79 | + |
80 | + [TestCase("firstToken:firstTokenSecret:firstConsumer:firstConsumerSecret", "firstToken", "firstTokenSecret", "firstConsumer", "firstConsumerSecret")] |
81 | + [TestCase("ad180jjd733klru7:hdhd0244k9j7ao03:dpf43f3p2l4k3l03:djr9rjt0jd78jf88%26", "ad180jjd733klru7", "hdhd0244k9j7ao03", "dpf43f3p2l4k3l03", "djr9rjt0jd78jf88%26")] |
82 | + public void DecodeTest(string secret, string expectedToken, string expectedTokenSecret, string expectedConsumerKey, |
83 | + string expectedConsumerSecret) |
84 | + { |
85 | + string token; |
86 | + string tokenSecret; |
87 | + string consumerKey; |
88 | + string consumerSecret; |
89 | + _encoder.Decode(secret, out token, out tokenSecret, out consumerKey, out consumerSecret); |
90 | + Assert.AreEqual(expectedToken, token); |
91 | + Assert.AreEqual(expectedTokenSecret, tokenSecret); |
92 | + Assert.AreEqual(expectedConsumerKey, consumerKey); |
93 | + Assert.AreEqual(expectedConsumerSecret, consumerSecret); |
94 | + } |
95 | + |
96 | + #endregion |
97 | + |
98 | + } |
99 | +} |
100 | |
101 | === added file 'src/Canonical.Ubuntu.SSO.Tests/JsonSSOCredentialsEncoderFixture.cs' |
102 | --- src/Canonical.Ubuntu.SSO.Tests/JsonSSOCredentialsEncoderFixture.cs 1970-01-01 00:00:00 +0000 |
103 | +++ src/Canonical.Ubuntu.SSO.Tests/JsonSSOCredentialsEncoderFixture.cs 2010-10-05 09:58:35 +0000 |
104 | @@ -0,0 +1,29 @@ |
105 | +/* Copyright 2010 Canonical Ltd. |
106 | + * |
107 | + * This file is part of UbuntuOne on Windows. |
108 | + * |
109 | + * UbuntuOne on Windows is free software: you can redistribute it and/or modify |
110 | + * it under the terms of the GNU Lesser General Public License version |
111 | + * as published by the Free Software Foundation. |
112 | + * |
113 | + * Ubuntu One on Windows is distributed in the hope that it will be useful, |
114 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
115 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
116 | + * GNU Lesser General Public License for more details. |
117 | + * |
118 | + * You should have received a copy of the GNU Lesser General Public License |
119 | + * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>. |
120 | + * |
121 | + * Authors: Manuel de la Peña <manuel.delapena@canonical.com> |
122 | + */ |
123 | +using System; |
124 | +using System.Collections.Generic; |
125 | +using System.Linq; |
126 | +using System.Text; |
127 | + |
128 | +namespace Canonical.Ubuntu.SSO.Tests |
129 | +{ |
130 | + class JsonSSOCredentialsEncoderFixture |
131 | + { |
132 | + } |
133 | +} |
134 | |
135 | === added file 'src/Canonical.Ubuntu.SSO.Tests/SSOLoginProcessorFixture.cs' |
136 | --- src/Canonical.Ubuntu.SSO.Tests/SSOLoginProcessorFixture.cs 1970-01-01 00:00:00 +0000 |
137 | +++ src/Canonical.Ubuntu.SSO.Tests/SSOLoginProcessorFixture.cs 2010-10-05 09:58:35 +0000 |
138 | @@ -0,0 +1,98 @@ |
139 | +/* Copyright 2010 Canonical Ltd. |
140 | + * |
141 | + * This file is part of UbuntuOne on Windows. |
142 | + * |
143 | + * UbuntuOne on Windows is free software: you can redistribute it and/or modify |
144 | + * it under the terms of the GNU Lesser General Public License version |
145 | + * as published by the Free Software Foundation. |
146 | + * |
147 | + * Ubuntu One on Windows is distributed in the hope that it will be useful, |
148 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
149 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
150 | + * GNU Lesser General Public License for more details. |
151 | + * |
152 | + * You should have received a copy of the GNU Lesser General Public License |
153 | + * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>. |
154 | + * |
155 | + * Authors: Manuel de la Peña <manuel.delapena@canonical.com> |
156 | + */ |
157 | +using Canonical.Ubuntu.SSO.Service; |
158 | +using Canonical.UbuntuOne.Common.Net; |
159 | +using NUnit.Framework; |
160 | +using Rhino.Mocks; |
161 | + |
162 | +namespace Canonical.Ubuntu.SSO.Tests |
163 | +{ |
164 | + [TestFixture] |
165 | + public class SSOLoginProcessorFixture |
166 | + { |
167 | + #region Variables |
168 | + |
169 | + private MockRepository _mocks; |
170 | + private Authentications _auth; |
171 | + private IKeyring _keyring; |
172 | + private ISSOCredentialsEncoder _encode; |
173 | + private IOAuth _oauth; |
174 | + private IHttpWebRequestFactory _requestFactory; |
175 | + private IHttpWebRequest _request; |
176 | + private SSOLoginProcessor _processor; |
177 | + |
178 | + #endregion |
179 | + |
180 | + #region Setup |
181 | + |
182 | + [SetUp] |
183 | + public void Setup() |
184 | + { |
185 | + _mocks = new MockRepository(); |
186 | + _auth = _mocks.DynamicMock<Authentications>(); |
187 | + _keyring = _mocks.DynamicMock<IKeyring>(); |
188 | + _encode = _mocks.DynamicMock<ISSOCredentialsEncoder>(); |
189 | + _oauth = _mocks.DynamicMock<IOAuth>(); |
190 | + _requestFactory = _mocks.DynamicMock<IHttpWebRequestFactory>(); |
191 | + _request = _mocks.DynamicMock<IHttpWebRequest>(); |
192 | + _processor = new SSOLoginProcessor |
193 | + { |
194 | + Authentications = _auth, |
195 | + HttpWebRequestFactory = _requestFactory, |
196 | + Keyring = _keyring, |
197 | + OAuth = _oauth, |
198 | + SSOCredentialsEncoder = _encode |
199 | + }; |
200 | + } |
201 | + |
202 | + #endregion |
203 | + |
204 | + #region Tests |
205 | + |
206 | + [TestCase("manuel@canonical.com", "Passwd", "UbuntuOne")] |
207 | + [TestCase("mandel@themacaque.com", "Test", "Gwibber")] |
208 | + [ExpectedException(typeof(SSOLoginException))] |
209 | + public void LoginCredentialsExceptionTest(string email, string password, string tokenName) |
210 | + { |
211 | + Assert.Ignore("Not yet implemented"); |
212 | + } |
213 | + |
214 | + [Test] |
215 | + [ExpectedException(typeof(SSOLoginException))] |
216 | + public void LoginPingExceptionTest() |
217 | + { |
218 | + Assert.Ignore("Not yet implemented"); |
219 | + } |
220 | + |
221 | + [Test] |
222 | + public void LoginNoSecretTest() |
223 | + { |
224 | + Assert.Ignore("Not yet implemented"); |
225 | + } |
226 | + |
227 | + [Test] |
228 | + public void LoginSecretTest() |
229 | + { |
230 | + Assert.Ignore("Not yet implemented"); |
231 | + } |
232 | + |
233 | + #endregion |
234 | + |
235 | + } |
236 | +} |
237 | |
238 | === modified file 'src/Canonical.Ubuntu.SSO/Canonical.Ubuntu.SSO.csproj' |
239 | --- src/Canonical.Ubuntu.SSO/Canonical.Ubuntu.SSO.csproj 2010-10-05 09:58:34 +0000 |
240 | +++ src/Canonical.Ubuntu.SSO/Canonical.Ubuntu.SSO.csproj 2010-10-05 09:58:35 +0000 |
241 | @@ -35,6 +35,10 @@ |
242 | <SpecificVersion>False</SpecificVersion> |
243 | <HintPath>..\..\lib\log4net\log4net.dll</HintPath> |
244 | </Reference> |
245 | + <Reference Include="Newtonsoft.Json, Version=3.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> |
246 | + <SpecificVersion>False</SpecificVersion> |
247 | + <HintPath>..\..\lib\JsonNet\Newtonsoft.Json.dll</HintPath> |
248 | + </Reference> |
249 | <Reference Include="System" /> |
250 | <Reference Include="System.Core"> |
251 | <RequiredTargetFramework>3.5</RequiredTargetFramework> |
252 | @@ -54,6 +58,7 @@ |
253 | <Compile Include="..\Version.cs"> |
254 | <Link>Properties\Version.cs</Link> |
255 | </Compile> |
256 | + <Compile Include="ColonSeparatedSSOCredentialsEncoder.cs" /> |
257 | <Compile Include="CredentialsDeniedEventArgs.cs" /> |
258 | <Compile Include="CredentialsErrorEventArgs.cs" /> |
259 | <Compile Include="CredentialsFoundEventArgs.cs" /> |
260 | @@ -61,11 +66,14 @@ |
261 | <Compile Include="IDataProtector.cs" /> |
262 | <Compile Include="ILoginOrRegisterView.cs" /> |
263 | <Compile Include="ILoginView.cs" /> |
264 | + <Compile Include="IOAuth.cs" /> |
265 | <Compile Include="IRegistryKey.cs" /> |
266 | + <Compile Include="ISSOCredentialsEncoder.cs" /> |
267 | <Compile Include="ISSOLoginProcessor.cs" /> |
268 | + <Compile Include="JsonSSOCredentialsEncoder.cs" /> |
269 | <Compile Include="Keyring.cs" /> |
270 | <Compile Include="LoginCredentialsEventArgs.cs" /> |
271 | - <Compile Include="OAuthBase.cs" /> |
272 | + <Compile Include="OAuth.cs" /> |
273 | <Compile Include="RegistryKeyWrapper.cs" /> |
274 | <Compile Include="Service\Account.cs" /> |
275 | <Compile Include="Service\AccountDiff.cs" /> |
276 | @@ -109,6 +117,8 @@ |
277 | <Compile Include="IKeyring.cs" /> |
278 | <Compile Include="ISSOCredentialsProvider.cs" /> |
279 | <Compile Include="Properties\AssemblyInfo.cs" /> |
280 | + <Compile Include="SSOException.cs" /> |
281 | + <Compile Include="SSOLoginException.cs" /> |
282 | <Compile Include="SSOLoginProcessor.cs" /> |
283 | </ItemGroup> |
284 | <ItemGroup> |
285 | |
286 | === added file 'src/Canonical.Ubuntu.SSO/ColonSeparatedSSOCredentialsEncoder.cs' |
287 | --- src/Canonical.Ubuntu.SSO/ColonSeparatedSSOCredentialsEncoder.cs 1970-01-01 00:00:00 +0000 |
288 | +++ src/Canonical.Ubuntu.SSO/ColonSeparatedSSOCredentialsEncoder.cs 2010-10-05 09:58:35 +0000 |
289 | @@ -0,0 +1,60 @@ |
290 | +/* Copyright 2010 Canonical Ltd. |
291 | + * |
292 | + * This file is part of UbuntuOne on Windows. |
293 | + * |
294 | + * UbuntuOne on Windows is free software: you can redistribute it and/or modify |
295 | + * it under the terms of the GNU Lesser General Public License version |
296 | + * as published by the Free Software Foundation. |
297 | + * |
298 | + * Ubuntu One on Windows is distributed in the hope that it will be useful, |
299 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
300 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
301 | + * GNU Lesser General Public License for more details. |
302 | + * |
303 | + * You should have received a copy of the GNU Lesser General Public License |
304 | + * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>. |
305 | + * |
306 | + * Authors: Manuel de la Peña <manuel.delapena@canonical.com> |
307 | + */ |
308 | +namespace Canonical.Ubuntu.SSO |
309 | +{ |
310 | + /// <summary> |
311 | + /// Encode implementation that encodes the oauth token using colons as separators. |
312 | + /// </summary> |
313 | + public class ColonSeparatedSSOCredentialsEncoder : ISSOCredentialsEncoder |
314 | + { |
315 | + #region Implementation of ISSOCredentialsEncoder |
316 | + |
317 | + /// <summary> |
318 | + /// Encodes oauth credentials so that they can be stored in a keyring. |
319 | + /// </summary> |
320 | + /// <param name="token">The oauth token.</param> |
321 | + /// <param name="tokenSecret">The oauth secret.</param> |
322 | + /// <param name="consumerKey">The oauth consumer key.</param> |
323 | + /// <param name="consumerSecret">The oauth consumer secret.</param> |
324 | + /// <returns>a stirng that represents the oauth token.</returns> |
325 | + public string Encode(string token, string tokenSecret, string consumerKey, string consumerSecret) |
326 | + { |
327 | + return string.Format("{0}:{1}:{2}:{3}", token, tokenSecret, consumerKey, consumerSecret); |
328 | + } |
329 | + |
330 | + /// <summary> |
331 | + /// Decodes the oauth credentials from a single string. |
332 | + /// </summary> |
333 | + /// <param name="secret">The secret that was stored in the keyring.</param> |
334 | + /// <param name="token">Out var where the ouath token will be returned.</param> |
335 | + /// <param name="tokenSecret">Out var where the oauth token secret will be returned.</param> |
336 | + /// <param name="consumerKey">Out var where the oauth consumer key will be returned.</param> |
337 | + /// <param name="consumerSecret">Out var where the oauth consumer secret will be returned.</param> |
338 | + public void Decode(string secret, out string token, out string tokenSecret, out string consumerKey, out string consumerSecret) |
339 | + { |
340 | + var data = secret.Split(":".ToCharArray(),4); |
341 | + token = data[0]; |
342 | + tokenSecret = data[1]; |
343 | + consumerKey = data[2]; |
344 | + consumerSecret = data[3]; |
345 | + } |
346 | + |
347 | + #endregion |
348 | + } |
349 | +} |
350 | |
351 | === modified file 'src/Canonical.Ubuntu.SSO/DPAPIDataProtector.cs' |
352 | --- src/Canonical.Ubuntu.SSO/DPAPIDataProtector.cs 2010-10-05 09:58:34 +0000 |
353 | +++ src/Canonical.Ubuntu.SSO/DPAPIDataProtector.cs 2010-10-05 09:58:35 +0000 |
354 | @@ -17,7 +17,6 @@ |
355 | * |
356 | * Authors: Manuel de la Peña <manuel.delapena@canonical.com> |
357 | */ |
358 | - |
359 | using System.Security.Cryptography; |
360 | using System.Text; |
361 | using log4net; |
362 | |
363 | === added file 'src/Canonical.Ubuntu.SSO/IOAuth.cs' |
364 | --- src/Canonical.Ubuntu.SSO/IOAuth.cs 1970-01-01 00:00:00 +0000 |
365 | +++ src/Canonical.Ubuntu.SSO/IOAuth.cs 2010-10-05 09:58:35 +0000 |
366 | @@ -0,0 +1,122 @@ |
367 | +/* Copyright 2010 Canonical Ltd. |
368 | + * |
369 | + * This file is part of UbuntuOne on Windows. |
370 | + * |
371 | + * UbuntuOne on Windows is free software: you can redistribute it and/or modify |
372 | + * it under the terms of the GNU Lesser General Public License version |
373 | + * as published by the Free Software Foundation. |
374 | + * |
375 | + * Ubuntu One on Windows is distributed in the hope that it will be useful, |
376 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
377 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
378 | + * GNU Lesser General Public License for more details. |
379 | + * |
380 | + * You should have received a copy of the GNU Lesser General Public License |
381 | + * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>. |
382 | + * |
383 | + * Authors: Manuel de la Peña <manuel.delapena@canonical.com> |
384 | + */ |
385 | +using System; |
386 | +using System.Collections.Generic; |
387 | +using System.Security.Cryptography; |
388 | + |
389 | +namespace Canonical.Ubuntu.SSO |
390 | +{ |
391 | + public interface IOAuth |
392 | + { |
393 | + /// <summary> |
394 | + /// Generate the signature base that is used to produce the signature |
395 | + /// </summary> |
396 | + /// <param name="url">The full url that needs to be signed including its non OAuth url parameters</param> |
397 | + /// <param name="consumerKey">The consumer key</param> |
398 | + /// <param name="token">The token, if available. If not available pass null or an empty string</param> |
399 | + /// <param name="tokenSecret">The token secret, if available. If not available pass null or an empty string</param> |
400 | + /// <param name="httpMethod">The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)</param> |
401 | + /// <param name="nonce"></param> |
402 | + /// <param name="signatureType">The signature type. To use the default values use <see cref="OAuth.SignatureTypes">OAuth.SignatureTypes</see>.</param> |
403 | + /// <param name="timeStamp"></param> |
404 | + /// <param name="normalizedUrl"></param> |
405 | + /// <param name="normalizedRequestParameters"></param> |
406 | + /// <returns>The signature base</returns> |
407 | + string GenerateSignatureBase(Uri url, string consumerKey, string token, string tokenSecret, |
408 | + string httpMethod, string timeStamp, string nonce, string signatureType, out string normalizedUrl, |
409 | + out string normalizedRequestParameters); |
410 | + |
411 | + /// <summary> |
412 | + /// Generate the signature value based on the given signature base and hash algorithm |
413 | + /// </summary> |
414 | + /// <param name="signatureBase">The signature based as produced by the GenerateSignatureBase method or by any other means</param> |
415 | + /// <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> |
416 | + /// <returns>A base64 string of the hash value</returns> |
417 | + string GenerateSignatureUsingHash(string signatureBase, HashAlgorithm hash); |
418 | + |
419 | + /// <summary> |
420 | + /// Generates a signature using the HMAC-SHA1 algorithm |
421 | + /// </summary> |
422 | + /// <param name="url">The full url that needs to be signed including its non OAuth url parameters</param> |
423 | + /// <param name="consumerKey">The consumer key</param> |
424 | + /// <param name="consumerSecret">The consumer seceret</param> |
425 | + /// <param name="token">The token, if available. If not available pass null or an empty string</param> |
426 | + /// <param name="tokenSecret">The token secret, if available. If not available pass null or an empty string</param> |
427 | + /// <param name="httpMethod">The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)</param> |
428 | + /// <param name="timeStamp"></param> |
429 | + /// <param name="nonce"></param> |
430 | + /// <param name="normalizedUrl"></param> |
431 | + /// <param name="normalizedRequestParameters"></param> |
432 | + /// <returns>A base64 string of the hash value</returns> |
433 | + string GenerateSignature(Uri url, string consumerKey, string consumerSecret, string token, |
434 | + string tokenSecret, string httpMethod, string timeStamp, string nonce, out string normalizedUrl, |
435 | + out string normalizedRequestParameters); |
436 | + |
437 | + /// <summary> |
438 | + /// Generates a signature using the specified signatureType |
439 | + /// </summary> |
440 | + /// <param name="url">The full url that needs to be signed including its non OAuth url parameters</param> |
441 | + /// <param name="consumerKey">The consumer key</param> |
442 | + /// <param name="consumerSecret">The consumer seceret</param> |
443 | + /// <param name="token">The token, if available. If not available pass null or an empty string</param> |
444 | + /// <param name="tokenSecret">The token secret, if available. If not available pass null or an empty string</param> |
445 | + /// <param name="httpMethod">The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)</param> |
446 | + /// <param name="nonce"></param> |
447 | + /// <param name="signatureType">The type of signature to use</param> |
448 | + /// <param name="timeStamp"></param> |
449 | + /// <param name="normalizedUrl"></param> |
450 | + /// <param name="normalizedRequestParameters"></param> |
451 | + /// <returns>A base64 string of the hash value</returns> |
452 | + string GenerateSignature(Uri url, string consumerKey, string consumerSecret, string token, |
453 | + string tokenSecret, string httpMethod, string timeStamp, string nonce, |
454 | + OAuth.SignatureTypes signatureType, out string normalizedUrl, out string normalizedRequestParameters); |
455 | + |
456 | + /// <summary> |
457 | + /// Returns a key value pair that contains a hedaer that can be used to authenticate a web requet. |
458 | + /// </summary> |
459 | + /// <param name="url">The uri with the web resource.</param> |
460 | + /// <param name="realm">The real that was used for the oauth.</param> |
461 | + /// <param name="consumerKey">The oauth consumer key.</param> |
462 | + /// <param name="consumerSecret">The oauth consumer secret.</param> |
463 | + /// <param name="token">The oauth token.</param> |
464 | + /// <param name="tokenSecret">The aoauth token secret.</param> |
465 | + /// <param name="httpMethod">The http method used for the request.</param> |
466 | + /// <param name="timeStamp">A time stamp.</param> |
467 | + /// <param name="nonce">A once</param> |
468 | + /// <param name="signatureType">Teht ype of signature that will be used.</param> |
469 | + /// <param name="normUrl"></param> |
470 | + /// <param name="normParams"></param> |
471 | + /// <returns>A key value pair where the key is the name of the header and the value is the data of the header.</returns> |
472 | + KeyValuePair<string, string> GenerateHeaderWithSignature(Uri url, string realm, string consumerKey, |
473 | + string consumerSecret, string token, string tokenSecret, string httpMethod, string timeStamp, |
474 | + string nonce, OAuth.SignatureTypes signatureType, out string normUrl, out string normParams); |
475 | + |
476 | + /// <summary> |
477 | + /// Generate the timestamp for the signature |
478 | + /// </summary> |
479 | + /// <returns></returns> |
480 | + string GenerateTimeStamp(); |
481 | + |
482 | + /// <summary> |
483 | + /// Generate a nonce |
484 | + /// </summary> |
485 | + /// <returns></returns> |
486 | + string GenerateNonce(); |
487 | + } |
488 | +} |
489 | \ No newline at end of file |
490 | |
491 | === added file 'src/Canonical.Ubuntu.SSO/ISSOCredentialsEncoder.cs' |
492 | --- src/Canonical.Ubuntu.SSO/ISSOCredentialsEncoder.cs 1970-01-01 00:00:00 +0000 |
493 | +++ src/Canonical.Ubuntu.SSO/ISSOCredentialsEncoder.cs 2010-10-05 09:58:35 +0000 |
494 | @@ -0,0 +1,46 @@ |
495 | +/* Copyright 2010 Canonical Ltd. |
496 | + * |
497 | + * This file is part of UbuntuOne on Windows. |
498 | + * |
499 | + * UbuntuOne on Windows is free software: you can redistribute it and/or modify |
500 | + * it under the terms of the GNU Lesser General Public License version |
501 | + * as published by the Free Software Foundation. |
502 | + * |
503 | + * Ubuntu One on Windows is distributed in the hope that it will be useful, |
504 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
505 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
506 | + * GNU Lesser General Public License for more details. |
507 | + * |
508 | + * You should have received a copy of the GNU Lesser General Public License |
509 | + * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>. |
510 | + * |
511 | + * Authors: Manuel de la Peña <manuel.delapena@canonical.com> |
512 | + */ |
513 | +namespace Canonical.Ubuntu.SSO |
514 | +{ |
515 | + /// <summary> |
516 | + /// Interface to be implemented by those object that know how to encode a oauth token so that it is saved as a single string. |
517 | + /// </summary> |
518 | + public interface ISSOCredentialsEncoder |
519 | + { |
520 | + /// <summary> |
521 | + /// When implemented will encode oauth credentials so that they can be stored in a keyring. |
522 | + /// </summary> |
523 | + /// <param name="token">The oauth token.</param> |
524 | + /// <param name="tokenSecret">The oauth secret.</param> |
525 | + /// <param name="consumerKey">The oauth consumer key.</param> |
526 | + /// <param name="consumerSecret">The oauth consumer secret.</param> |
527 | + /// <returns>a stirng that represents the oauth token.</returns> |
528 | + string Encode(string token, string tokenSecret, string consumerKey, string consumerSecret); |
529 | + |
530 | + /// <summary> |
531 | + /// When implemented decodes the oauth credentials from a single string. |
532 | + /// </summary> |
533 | + /// <param name="secret">The secret that was stored in the keyring.</param> |
534 | + /// <param name="token">Out var where the ouath token will be returned.</param> |
535 | + /// <param name="tokenSecret">Out var where the oauth token secret will be returned.</param> |
536 | + /// <param name="consumerKey">Out var where the oauth consumer key will be returned.</param> |
537 | + /// <param name="consumerSecret">Out var where the oauth consumer secret will be returned.</param> |
538 | + void Decode(string secret, out string token, out string tokenSecret, out string consumerKey, out string consumerSecret); |
539 | + } |
540 | +} |
541 | |
542 | === added file 'src/Canonical.Ubuntu.SSO/JsonSSOCredentialsEncoder.cs' |
543 | --- src/Canonical.Ubuntu.SSO/JsonSSOCredentialsEncoder.cs 1970-01-01 00:00:00 +0000 |
544 | +++ src/Canonical.Ubuntu.SSO/JsonSSOCredentialsEncoder.cs 2010-10-05 09:58:35 +0000 |
545 | @@ -0,0 +1,82 @@ |
546 | +/* Copyright 2010 Canonical Ltd. |
547 | + * |
548 | + * This file is part of UbuntuOne on Windows. |
549 | + * |
550 | + * UbuntuOne on Windows is free software: you can redistribute it and/or modify |
551 | + * it under the terms of the GNU Lesser General Public License version |
552 | + * as published by the Free Software Foundation. |
553 | + * |
554 | + * Ubuntu One on Windows is distributed in the hope that it will be useful, |
555 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
556 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
557 | + * GNU Lesser General Public License for more details. |
558 | + * |
559 | + * You should have received a copy of the GNU Lesser General Public License |
560 | + * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>. |
561 | + * |
562 | + * Authors: Manuel de la Peña <manuel.delapena@canonical.com> |
563 | + */ |
564 | +using System; |
565 | +using Newtonsoft.Json.Linq; |
566 | + |
567 | +namespace Canonical.Ubuntu.SSO |
568 | +{ |
569 | + public class JsonSSOCredentialsEncoder : ISSOCredentialsEncoder |
570 | + { |
571 | + #region Implementation of ISSOCredentialsEncoder |
572 | + |
573 | + /// <summary> |
574 | + /// When implemented will encode oauth credentials so that they can be stored in a keyring. |
575 | + /// </summary> |
576 | + /// <param name="token">The oauth token.</param> |
577 | + /// <param name="tokenSecret">The oauth secret.</param> |
578 | + /// <param name="consumerKey">The oauth consumer key.</param> |
579 | + /// <param name="consumerSecret">The oauth consumer secret.</param> |
580 | + /// <returns>a stirng that represents the oauth token.</returns> |
581 | + public string Encode(string token, string tokenSecret, string consumerKey, string consumerSecret) |
582 | + { |
583 | + var jobject = new JObject(); |
584 | + jobject["consumer_key"] = ""; |
585 | + jobject["consumer_secret"] = ""; |
586 | + jobject["token"] = ""; |
587 | + jobject["token_secret"] = ""; |
588 | + return jobject.ToString(); |
589 | + } |
590 | + |
591 | + /// <summary> |
592 | + /// When implemented decodes the oauth credentials from a single string. |
593 | + /// </summary> |
594 | + /// <param name="secret">The secret that was stored in the keyring.</param> |
595 | + /// <param name="token">Out var where the ouath token will be returned.</param> |
596 | + /// <param name="tokenSecret">Out var where the oauth token secret will be returned.</param> |
597 | + /// <param name="consumerKey">Out var where the oauth consumer key will be returned.</param> |
598 | + /// <param name="consumerSecret">Out var where the oauth consumer secret will be returned.</param> |
599 | + public void Decode(string secret, out string token, out string tokenSecret, out string consumerKey, out string consumerSecret) |
600 | + { |
601 | + var credentials = JObject.Parse(secret); |
602 | + try |
603 | + { |
604 | + consumerKey = (string)credentials["consumer_key"]; |
605 | + consumerSecret = (string)credentials["consumer_secret"]; |
606 | + token = (string)credentials["token"]; |
607 | + tokenSecret = (string)credentials["token_secret"]; |
608 | + |
609 | + } |
610 | + catch (InvalidCastException e) |
611 | + { |
612 | + // could happen when the json is not formatted as we expected. |
613 | + throw new SSOLoginException("Error when retrieving credentials.", e); |
614 | + } |
615 | + if (string.IsNullOrEmpty(consumerKey) |
616 | + || string.IsNullOrEmpty(consumerSecret) |
617 | + || string.IsNullOrEmpty(token) |
618 | + || string.IsNullOrEmpty(tokenSecret)) |
619 | + { |
620 | + // none of them can be null or empty. |
621 | + throw new SSOException("Credentials could not be parsed."); |
622 | + } |
623 | + } |
624 | + |
625 | + #endregion |
626 | + } |
627 | +} |
628 | |
629 | === added file 'src/Canonical.Ubuntu.SSO/OAuth.cs' |
630 | --- src/Canonical.Ubuntu.SSO/OAuth.cs 1970-01-01 00:00:00 +0000 |
631 | +++ src/Canonical.Ubuntu.SSO/OAuth.cs 2010-10-05 09:58:35 +0000 |
632 | @@ -0,0 +1,391 @@ |
633 | +using System; |
634 | +using System.Security.Cryptography; |
635 | +using System.Collections.Generic; |
636 | +using System.Text; |
637 | +using System.Web; |
638 | + |
639 | +namespace Canonical.Ubuntu.SSO |
640 | +{ |
641 | + public class OAuth : IOAuth |
642 | + { |
643 | + |
644 | + /// <summary> |
645 | + /// Provides a predefined set of algorithms that are supported officially by the protocol |
646 | + /// </summary> |
647 | + public enum SignatureTypes |
648 | + { |
649 | + HMACSHA1, |
650 | + PLAINTEXT, |
651 | + RSASHA1 |
652 | + } |
653 | + |
654 | + /// <summary> |
655 | + /// Provides an internal structure to sort the query parameter |
656 | + /// </summary> |
657 | + protected class QueryParameter |
658 | + { |
659 | + private readonly string _name = null; |
660 | + private readonly string _value = null; |
661 | + |
662 | + public QueryParameter(string name, string value) |
663 | + { |
664 | + _name = name; |
665 | + _value = value; |
666 | + } |
667 | + |
668 | + public string Name |
669 | + { |
670 | + get { return _name; } |
671 | + } |
672 | + |
673 | + public string Value |
674 | + { |
675 | + get { return _value; } |
676 | + } |
677 | + } |
678 | + |
679 | + /// <summary> |
680 | + /// Comparer class used to perform the sorting of the query parameters |
681 | + /// </summary> |
682 | + protected class QueryParameterComparer : IComparer<QueryParameter> |
683 | + { |
684 | + |
685 | + #region IComparer<QueryParameter> Members |
686 | + |
687 | + public int Compare(QueryParameter x, QueryParameter y) |
688 | + { |
689 | + return x.Name == y.Name ? string.Compare(x.Value, y.Value) |
690 | + : string.Compare(x.Name, y.Name); |
691 | + } |
692 | + |
693 | + #endregion |
694 | + } |
695 | + |
696 | + protected const string OAuthVersion = "1.0"; |
697 | + protected const string OAuthParameterPrefix = "oauth_"; |
698 | + |
699 | + // |
700 | + // List of know and used oauth parameters' names |
701 | + // |
702 | + protected const string OAuthConsumerKeyKey = "oauth_consumer_key"; |
703 | + protected const string OAuthCallbackKey = "oauth_callback"; |
704 | + protected const string OAuthVersionKey = "oauth_version"; |
705 | + protected const string OAuthSignatureMethodKey = "oauth_signature_method"; |
706 | + protected const string OAuthSignatureKey = "oauth_signature"; |
707 | + protected const string OAuthTimestampKey = "oauth_timestamp"; |
708 | + protected const string OAuthNonceKey = "oauth_nonce"; |
709 | + protected const string OAuthTokenKey = "oauth_token"; |
710 | + protected const string OAuthTokenSecretKey = "oauth_token_secret"; |
711 | + |
712 | + protected const string HMACSHA1SignatureType = "HMAC-SHA1"; |
713 | + protected const string PlainTextSignatureType = "PLAINTEXT"; |
714 | + protected const string RSASHA1SignatureType = "RSA-SHA1"; |
715 | + |
716 | + protected Random Random = new Random(); |
717 | + |
718 | + protected string UnreservedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~"; |
719 | + |
720 | + /// <summary> |
721 | + /// Helper function to compute a hash value |
722 | + /// </summary> |
723 | + /// <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> |
724 | + /// <param name="data">The data to hash</param> |
725 | + /// <returns>a Base64 string of the hash value</returns> |
726 | + private static string ComputeHash(HashAlgorithm hashAlgorithm, string data) |
727 | + { |
728 | + if (hashAlgorithm == null) |
729 | + { |
730 | + throw new ArgumentNullException("hashAlgorithm"); |
731 | + } |
732 | + |
733 | + if (string.IsNullOrEmpty(data)) |
734 | + { |
735 | + throw new ArgumentNullException("data"); |
736 | + } |
737 | + |
738 | + var dataBuffer = Encoding.ASCII.GetBytes(data); |
739 | + var hashBytes = hashAlgorithm.ComputeHash(dataBuffer); |
740 | + |
741 | + return Convert.ToBase64String(hashBytes); |
742 | + } |
743 | + |
744 | + /// <summary> |
745 | + /// Internal function to cut out all non oauth query string parameters (all parameters not begining with "oauth_") |
746 | + /// </summary> |
747 | + /// <param name="parameters">The query string part of the Url</param> |
748 | + /// <returns>A list of QueryParameter each containing the parameter name and value</returns> |
749 | + private static List<QueryParameter> GetQueryParameters(string parameters) |
750 | + { |
751 | + if (parameters.StartsWith("?")) |
752 | + { |
753 | + parameters = parameters.Remove(0, 1); |
754 | + } |
755 | + |
756 | + var result = new List<QueryParameter>(); |
757 | + |
758 | + if (!string.IsNullOrEmpty(parameters)) |
759 | + { |
760 | + string[] p = parameters.Split('&'); |
761 | + foreach (string s in p) |
762 | + { |
763 | + if (!string.IsNullOrEmpty(s) && !s.StartsWith(OAuthParameterPrefix)) |
764 | + { |
765 | + if (s.IndexOf('=') > -1) |
766 | + { |
767 | + string[] temp = s.Split('='); |
768 | + result.Add(new QueryParameter(temp[0], temp[1])); |
769 | + } |
770 | + else |
771 | + { |
772 | + result.Add(new QueryParameter(s, string.Empty)); |
773 | + } |
774 | + } |
775 | + } |
776 | + } |
777 | + |
778 | + return result; |
779 | + } |
780 | + |
781 | + /// <summary> |
782 | + /// This is a different Url Encode implementation since the default .NET one outputs the percent encoding in lower case. |
783 | + /// While this is not a problem with the percent encoding spec, it is used in upper case throughout OAuth |
784 | + /// </summary> |
785 | + /// <param name="value">The value to Url encode</param> |
786 | + /// <returns>Returns a Url encoded string</returns> |
787 | + protected string UrlEncode(string value) |
788 | + { |
789 | + var result = new StringBuilder(); |
790 | + |
791 | + foreach (char symbol in value) |
792 | + { |
793 | + if (UnreservedChars.IndexOf(symbol) != -1) |
794 | + { |
795 | + result.Append(symbol); |
796 | + } |
797 | + else |
798 | + { |
799 | + result.Append('%' + String.Format("{0:X2}", (int)symbol)); |
800 | + } |
801 | + } |
802 | + |
803 | + return result.ToString(); |
804 | + } |
805 | + |
806 | + /// <summary> |
807 | + /// Normalizes the request parameters according to the spec |
808 | + /// </summary> |
809 | + /// <param name="parameters">The list of parameters already sorted</param> |
810 | + /// <returns>a string representing the normalized parameters</returns> |
811 | + protected string NormalizeRequestParameters(IList<QueryParameter> parameters) |
812 | + { |
813 | + var sb = new StringBuilder(); |
814 | + QueryParameter p; |
815 | + for (var i = 0; i < parameters.Count; i++) |
816 | + { |
817 | + p = parameters[i]; |
818 | + sb.AppendFormat("{0}={1}", p.Name, p.Value); |
819 | + |
820 | + if (i < parameters.Count - 1) |
821 | + { |
822 | + sb.Append("&"); |
823 | + } |
824 | + } |
825 | + |
826 | + return sb.ToString(); |
827 | + } |
828 | + |
829 | + /// <summary> |
830 | + /// Generate the signature base that is used to produce the signature |
831 | + /// </summary> |
832 | + /// <param name="url">The full url that needs to be signed including its non OAuth url parameters</param> |
833 | + /// <param name="consumerKey">The consumer key</param> |
834 | + /// <param name="token">The token, if available. If not available pass null or an empty string</param> |
835 | + /// <param name="tokenSecret">The token secret, if available. If not available pass null or an empty string</param> |
836 | + /// <param name="httpMethod">The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)</param> |
837 | + /// <param name="nonce"></param> |
838 | + /// <param name="signatureType">The signature type. To use the default values use <see cref="OAuth.SignatureTypes">OAuth.SignatureTypes</see>.</param> |
839 | + /// <param name="timeStamp"></param> |
840 | + /// <param name="normalizedUrl"></param> |
841 | + /// <param name="normalizedRequestParameters"></param> |
842 | + /// <returns>The signature base</returns> |
843 | + 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) |
844 | + { |
845 | + if (token == null) |
846 | + { |
847 | + token = string.Empty; |
848 | + } |
849 | + |
850 | + if (tokenSecret == null) |
851 | + { |
852 | + tokenSecret = string.Empty; |
853 | + } |
854 | + |
855 | + if (string.IsNullOrEmpty(consumerKey)) |
856 | + { |
857 | + throw new ArgumentNullException("consumerKey"); |
858 | + } |
859 | + |
860 | + if (string.IsNullOrEmpty(httpMethod)) |
861 | + { |
862 | + throw new ArgumentNullException("httpMethod"); |
863 | + } |
864 | + |
865 | + if (string.IsNullOrEmpty(signatureType)) |
866 | + { |
867 | + throw new ArgumentNullException("signatureType"); |
868 | + } |
869 | + |
870 | + List<QueryParameter> parameters = GetQueryParameters(url.Query); |
871 | + parameters.Add(new QueryParameter(OAuthVersionKey, OAuthVersion)); |
872 | + parameters.Add(new QueryParameter(OAuthNonceKey, nonce)); |
873 | + parameters.Add(new QueryParameter(OAuthTimestampKey, timeStamp)); |
874 | + parameters.Add(new QueryParameter(OAuthSignatureMethodKey, signatureType)); |
875 | + parameters.Add(new QueryParameter(OAuthConsumerKeyKey, consumerKey)); |
876 | + |
877 | + if (!string.IsNullOrEmpty(token)) |
878 | + { |
879 | + parameters.Add(new QueryParameter(OAuthTokenKey, token)); |
880 | + } |
881 | + |
882 | + parameters.Sort(new QueryParameterComparer()); |
883 | + |
884 | + normalizedUrl = string.Format("{0}://{1}", url.Scheme, url.Host); |
885 | + if (!((url.Scheme == "http" && url.Port == 80) || (url.Scheme == "https" && url.Port == 443))) |
886 | + { |
887 | + normalizedUrl += ":" + url.Port; |
888 | + } |
889 | + normalizedUrl += url.AbsolutePath; |
890 | + normalizedRequestParameters = NormalizeRequestParameters(parameters); |
891 | + |
892 | + var signatureBase = new StringBuilder(); |
893 | + signatureBase.AppendFormat("{0}&", httpMethod.ToUpper()); |
894 | + signatureBase.AppendFormat("{0}&", UrlEncode(normalizedUrl)); |
895 | + signatureBase.AppendFormat("{0}", UrlEncode(normalizedRequestParameters)); |
896 | + |
897 | + return signatureBase.ToString(); |
898 | + } |
899 | + |
900 | + /// <summary> |
901 | + /// Generate the signature value based on the given signature base and hash algorithm |
902 | + /// </summary> |
903 | + /// <param name="signatureBase">The signature based as produced by the GenerateSignatureBase method or by any other means</param> |
904 | + /// <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> |
905 | + /// <returns>A base64 string of the hash value</returns> |
906 | + public string GenerateSignatureUsingHash(string signatureBase, HashAlgorithm hash) |
907 | + { |
908 | + return ComputeHash(hash, signatureBase); |
909 | + } |
910 | + |
911 | + /// <summary> |
912 | + /// Generates a signature using the HMAC-SHA1 algorithm |
913 | + /// </summary> |
914 | + /// <param name="url">The full url that needs to be signed including its non OAuth url parameters</param> |
915 | + /// <param name="consumerKey">The consumer key</param> |
916 | + /// <param name="consumerSecret">The consumer seceret</param> |
917 | + /// <param name="token">The token, if available. If not available pass null or an empty string</param> |
918 | + /// <param name="tokenSecret">The token secret, if available. If not available pass null or an empty string</param> |
919 | + /// <param name="httpMethod">The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)</param> |
920 | + /// <param name="timeStamp"></param> |
921 | + /// <param name="nonce"></param> |
922 | + /// <param name="normalizedUrl"></param> |
923 | + /// <param name="normalizedRequestParameters"></param> |
924 | + /// <returns>A base64 string of the hash value</returns> |
925 | + 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) |
926 | + { |
927 | + return GenerateSignature(url, consumerKey, consumerSecret, token, tokenSecret, httpMethod, timeStamp, nonce, SignatureTypes.HMACSHA1, out normalizedUrl, out normalizedRequestParameters); |
928 | + } |
929 | + |
930 | + /// <summary> |
931 | + /// Generates a signature using the specified signatureType |
932 | + /// </summary> |
933 | + /// <param name="url">The full url that needs to be signed including its non OAuth url parameters</param> |
934 | + /// <param name="consumerKey">The consumer key</param> |
935 | + /// <param name="consumerSecret">The consumer seceret</param> |
936 | + /// <param name="token">The token, if available. If not available pass null or an empty string</param> |
937 | + /// <param name="tokenSecret">The token secret, if available. If not available pass null or an empty string</param> |
938 | + /// <param name="httpMethod">The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)</param> |
939 | + /// <param name="nonce"></param> |
940 | + /// <param name="signatureType">The type of signature to use</param> |
941 | + /// <param name="timeStamp"></param> |
942 | + /// <param name="normalizedUrl"></param> |
943 | + /// <param name="normalizedRequestParameters"></param> |
944 | + /// <returns>A base64 string of the hash value</returns> |
945 | + 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) |
946 | + { |
947 | + normalizedUrl = null; |
948 | + normalizedRequestParameters = null; |
949 | + |
950 | + switch (signatureType) |
951 | + { |
952 | + case SignatureTypes.PLAINTEXT: |
953 | + return HttpUtility.UrlEncode(string.Format("{0}&{1}", consumerSecret, tokenSecret)); |
954 | + case SignatureTypes.HMACSHA1: |
955 | + var signatureBase = GenerateSignatureBase(url, consumerKey, token, tokenSecret, httpMethod, timeStamp, nonce, HMACSHA1SignatureType, out normalizedUrl, out normalizedRequestParameters); |
956 | + |
957 | + var hmacsha1 = new HMACSHA1(); |
958 | + hmacsha1.Key = Encoding.ASCII.GetBytes(string.Format("{0}&{1}", UrlEncode(consumerSecret), string.IsNullOrEmpty(tokenSecret) ? "" : UrlEncode(tokenSecret))); |
959 | + |
960 | + return GenerateSignatureUsingHash(signatureBase, hmacsha1); |
961 | + case SignatureTypes.RSASHA1: |
962 | + throw new NotImplementedException(); |
963 | + default: |
964 | + throw new ArgumentException("Unknown signature type", "signatureType"); |
965 | + } |
966 | + } |
967 | + |
968 | + /// <summary> |
969 | + /// Returns a key value pair that contains a hedaer that can be used to authenticate a web requet. |
970 | + /// </summary> |
971 | + /// <param name="url">The uri with the web resource.</param> |
972 | + /// <param name="realm">The real that was used for the oauth.</param> |
973 | + /// <param name="consumerKey">The oauth consumer key.</param> |
974 | + /// <param name="consumerSecret">The oauth consumer secret.</param> |
975 | + /// <param name="token">The oauth token.</param> |
976 | + /// <param name="tokenSecret">The aoauth token secret.</param> |
977 | + /// <param name="httpMethod">The http method used for the request.</param> |
978 | + /// <param name="timeStamp">A time stamp.</param> |
979 | + /// <param name="nonce">A once</param> |
980 | + /// <param name="signatureType">Teht ype of signature that will be used.</param> |
981 | + /// <returns>A key value pair where the key is the name of the header and the value is the data of the header.</returns> |
982 | + public KeyValuePair<string, string> GenerateHeaderWithSignature(Uri url, string realm, string consumerKey, |
983 | + string consumerSecret, string token, string tokenSecret, string httpMethod, string timeStamp, |
984 | + string nonce, SignatureTypes signatureType, out string normUrl, out string normParams) |
985 | + { |
986 | + var signature = GenerateSignature(url, |
987 | + consumerKey, consumerSecret, token, tokenSecret, |
988 | + httpMethod, timeStamp, nonce, SignatureTypes.HMACSHA1, |
989 | + out normUrl, out normParams); |
990 | + |
991 | + // Construct the OAuth header |
992 | + var headerData = normParams + "&" + HttpUtility.UrlEncode("oauth_signature") + "=" + HttpUtility.UrlEncode(signature); |
993 | + headerData = headerData.Replace("&", @""","); |
994 | + headerData = headerData.Replace("=", @"="""); |
995 | + headerData += @""""; |
996 | + headerData = ((string.IsNullOrEmpty(realm)) ? "OAuth realm=\"\"," : |
997 | + string.Format("OAuth realm=\"{0}\",", realm)) + headerData; |
998 | + return new KeyValuePair<string, string>("Authorization", headerData); |
999 | + } |
1000 | + |
1001 | + /// <summary> |
1002 | + /// Generate the timestamp for the signature |
1003 | + /// </summary> |
1004 | + /// <returns></returns> |
1005 | + public virtual string GenerateTimeStamp() |
1006 | + { |
1007 | + // Default implementation of UNIX time of the current UTC time |
1008 | + TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0); |
1009 | + return Convert.ToInt64(ts.TotalSeconds).ToString(); |
1010 | + } |
1011 | + |
1012 | + /// <summary> |
1013 | + /// Generate a nonce |
1014 | + /// </summary> |
1015 | + /// <returns></returns> |
1016 | + public virtual string GenerateNonce() |
1017 | + { |
1018 | + // Just a simple implementation of a random number between 123400 and 9999999 |
1019 | + return Random.Next(123400, 9999999).ToString(); |
1020 | + } |
1021 | + |
1022 | + } |
1023 | +} |
1024 | \ No newline at end of file |
1025 | |
1026 | === removed file 'src/Canonical.Ubuntu.SSO/OAuthBase.cs' |
1027 | --- src/Canonical.Ubuntu.SSO/OAuthBase.cs 2010-10-05 09:58:34 +0000 |
1028 | +++ src/Canonical.Ubuntu.SSO/OAuthBase.cs 1970-01-01 00:00:00 +0000 |
1029 | @@ -1,358 +0,0 @@ |
1030 | -using System; |
1031 | -using System.Security.Cryptography; |
1032 | -using System.Collections.Generic; |
1033 | -using System.Text; |
1034 | -using System.Web; |
1035 | - |
1036 | -namespace OAuth |
1037 | -{ |
1038 | - public class OAuthBase |
1039 | - { |
1040 | - |
1041 | - /// <summary> |
1042 | - /// Provides a predefined set of algorithms that are supported officially by the protocol |
1043 | - /// </summary> |
1044 | - public enum SignatureTypes |
1045 | - { |
1046 | - HMACSHA1, |
1047 | - PLAINTEXT, |
1048 | - RSASHA1 |
1049 | - } |
1050 | - |
1051 | - /// <summary> |
1052 | - /// Provides an internal structure to sort the query parameter |
1053 | - /// </summary> |
1054 | - protected class QueryParameter |
1055 | - { |
1056 | - private readonly string _name = null; |
1057 | - private readonly string _value = null; |
1058 | - |
1059 | - public QueryParameter(string name, string value) |
1060 | - { |
1061 | - _name = name; |
1062 | - _value = value; |
1063 | - } |
1064 | - |
1065 | - public string Name |
1066 | - { |
1067 | - get { return _name; } |
1068 | - } |
1069 | - |
1070 | - public string Value |
1071 | - { |
1072 | - get { return _value; } |
1073 | - } |
1074 | - } |
1075 | - |
1076 | - /// <summary> |
1077 | - /// Comparer class used to perform the sorting of the query parameters |
1078 | - /// </summary> |
1079 | - protected class QueryParameterComparer : IComparer<QueryParameter> |
1080 | - { |
1081 | - |
1082 | - #region IComparer<QueryParameter> Members |
1083 | - |
1084 | - public int Compare(QueryParameter x, QueryParameter y) |
1085 | - { |
1086 | - return x.Name == y.Name ? string.Compare(x.Value, y.Value) |
1087 | - : string.Compare(x.Name, y.Name); |
1088 | - } |
1089 | - |
1090 | - #endregion |
1091 | - } |
1092 | - |
1093 | - protected const string OAuthVersion = "1.0"; |
1094 | - protected const string OAuthParameterPrefix = "oauth_"; |
1095 | - |
1096 | - // |
1097 | - // List of know and used oauth parameters' names |
1098 | - // |
1099 | - protected const string OAuthConsumerKeyKey = "oauth_consumer_key"; |
1100 | - protected const string OAuthCallbackKey = "oauth_callback"; |
1101 | - protected const string OAuthVersionKey = "oauth_version"; |
1102 | - protected const string OAuthSignatureMethodKey = "oauth_signature_method"; |
1103 | - protected const string OAuthSignatureKey = "oauth_signature"; |
1104 | - protected const string OAuthTimestampKey = "oauth_timestamp"; |
1105 | - protected const string OAuthNonceKey = "oauth_nonce"; |
1106 | - protected const string OAuthTokenKey = "oauth_token"; |
1107 | - protected const string OAuthTokenSecretKey = "oauth_token_secret"; |
1108 | - |
1109 | - protected const string HMACSHA1SignatureType = "HMAC-SHA1"; |
1110 | - protected const string PlainTextSignatureType = "PLAINTEXT"; |
1111 | - protected const string RSASHA1SignatureType = "RSA-SHA1"; |
1112 | - |
1113 | - protected Random Random = new Random(); |
1114 | - |
1115 | - protected string UnreservedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~"; |
1116 | - |
1117 | - /// <summary> |
1118 | - /// Helper function to compute a hash value |
1119 | - /// </summary> |
1120 | - /// <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> |
1121 | - /// <param name="data">The data to hash</param> |
1122 | - /// <returns>a Base64 string of the hash value</returns> |
1123 | - private static string ComputeHash(HashAlgorithm hashAlgorithm, string data) |
1124 | - { |
1125 | - if (hashAlgorithm == null) |
1126 | - { |
1127 | - throw new ArgumentNullException("hashAlgorithm"); |
1128 | - } |
1129 | - |
1130 | - if (string.IsNullOrEmpty(data)) |
1131 | - { |
1132 | - throw new ArgumentNullException("data"); |
1133 | - } |
1134 | - |
1135 | - var dataBuffer = Encoding.ASCII.GetBytes(data); |
1136 | - var hashBytes = hashAlgorithm.ComputeHash(dataBuffer); |
1137 | - |
1138 | - return Convert.ToBase64String(hashBytes); |
1139 | - } |
1140 | - |
1141 | - /// <summary> |
1142 | - /// Internal function to cut out all non oauth query string parameters (all parameters not begining with "oauth_") |
1143 | - /// </summary> |
1144 | - /// <param name="parameters">The query string part of the Url</param> |
1145 | - /// <returns>A list of QueryParameter each containing the parameter name and value</returns> |
1146 | - private static List<QueryParameter> GetQueryParameters(string parameters) |
1147 | - { |
1148 | - if (parameters.StartsWith("?")) |
1149 | - { |
1150 | - parameters = parameters.Remove(0, 1); |
1151 | - } |
1152 | - |
1153 | - var result = new List<QueryParameter>(); |
1154 | - |
1155 | - if (!string.IsNullOrEmpty(parameters)) |
1156 | - { |
1157 | - string[] p = parameters.Split('&'); |
1158 | - foreach (string s in p) |
1159 | - { |
1160 | - if (!string.IsNullOrEmpty(s) && !s.StartsWith(OAuthParameterPrefix)) |
1161 | - { |
1162 | - if (s.IndexOf('=') > -1) |
1163 | - { |
1164 | - string[] temp = s.Split('='); |
1165 | - result.Add(new QueryParameter(temp[0], temp[1])); |
1166 | - } |
1167 | - else |
1168 | - { |
1169 | - result.Add(new QueryParameter(s, string.Empty)); |
1170 | - } |
1171 | - } |
1172 | - } |
1173 | - } |
1174 | - |
1175 | - return result; |
1176 | - } |
1177 | - |
1178 | - /// <summary> |
1179 | - /// This is a different Url Encode implementation since the default .NET one outputs the percent encoding in lower case. |
1180 | - /// While this is not a problem with the percent encoding spec, it is used in upper case throughout OAuth |
1181 | - /// </summary> |
1182 | - /// <param name="value">The value to Url encode</param> |
1183 | - /// <returns>Returns a Url encoded string</returns> |
1184 | - protected string UrlEncode(string value) |
1185 | - { |
1186 | - var result = new StringBuilder(); |
1187 | - |
1188 | - foreach (char symbol in value) |
1189 | - { |
1190 | - if (UnreservedChars.IndexOf(symbol) != -1) |
1191 | - { |
1192 | - result.Append(symbol); |
1193 | - } |
1194 | - else |
1195 | - { |
1196 | - result.Append('%' + String.Format("{0:X2}", (int)symbol)); |
1197 | - } |
1198 | - } |
1199 | - |
1200 | - return result.ToString(); |
1201 | - } |
1202 | - |
1203 | - /// <summary> |
1204 | - /// Normalizes the request parameters according to the spec |
1205 | - /// </summary> |
1206 | - /// <param name="parameters">The list of parameters already sorted</param> |
1207 | - /// <returns>a string representing the normalized parameters</returns> |
1208 | - protected string NormalizeRequestParameters(IList<QueryParameter> parameters) |
1209 | - { |
1210 | - var sb = new StringBuilder(); |
1211 | - QueryParameter p; |
1212 | - for (var i = 0; i < parameters.Count; i++) |
1213 | - { |
1214 | - p = parameters[i]; |
1215 | - sb.AppendFormat("{0}={1}", p.Name, p.Value); |
1216 | - |
1217 | - if (i < parameters.Count - 1) |
1218 | - { |
1219 | - sb.Append("&"); |
1220 | - } |
1221 | - } |
1222 | - |
1223 | - return sb.ToString(); |
1224 | - } |
1225 | - |
1226 | - /// <summary> |
1227 | - /// Generate the signature base that is used to produce the signature |
1228 | - /// </summary> |
1229 | - /// <param name="url">The full url that needs to be signed including its non OAuth url parameters</param> |
1230 | - /// <param name="consumerKey">The consumer key</param> |
1231 | - /// <param name="token">The token, if available. If not available pass null or an empty string</param> |
1232 | - /// <param name="tokenSecret">The token secret, if available. If not available pass null or an empty string</param> |
1233 | - /// <param name="httpMethod">The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)</param> |
1234 | - /// <param name="nonce"></param> |
1235 | - /// <param name="signatureType">The signature type. To use the default values use <see cref="OAuthBase.SignatureTypes">OAuthBase.SignatureTypes</see>.</param> |
1236 | - /// <param name="timeStamp"></param> |
1237 | - /// <param name="normalizedUrl"></param> |
1238 | - /// <param name="normalizedRequestParameters"></param> |
1239 | - /// <returns>The signature base</returns> |
1240 | - 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) |
1241 | - { |
1242 | - if (token == null) |
1243 | - { |
1244 | - token = string.Empty; |
1245 | - } |
1246 | - |
1247 | - if (tokenSecret == null) |
1248 | - { |
1249 | - tokenSecret = string.Empty; |
1250 | - } |
1251 | - |
1252 | - if (string.IsNullOrEmpty(consumerKey)) |
1253 | - { |
1254 | - throw new ArgumentNullException("consumerKey"); |
1255 | - } |
1256 | - |
1257 | - if (string.IsNullOrEmpty(httpMethod)) |
1258 | - { |
1259 | - throw new ArgumentNullException("httpMethod"); |
1260 | - } |
1261 | - |
1262 | - if (string.IsNullOrEmpty(signatureType)) |
1263 | - { |
1264 | - throw new ArgumentNullException("signatureType"); |
1265 | - } |
1266 | - |
1267 | - List<QueryParameter> parameters = GetQueryParameters(url.Query); |
1268 | - parameters.Add(new QueryParameter(OAuthVersionKey, OAuthVersion)); |
1269 | - parameters.Add(new QueryParameter(OAuthNonceKey, nonce)); |
1270 | - parameters.Add(new QueryParameter(OAuthTimestampKey, timeStamp)); |
1271 | - parameters.Add(new QueryParameter(OAuthSignatureMethodKey, signatureType)); |
1272 | - parameters.Add(new QueryParameter(OAuthConsumerKeyKey, consumerKey)); |
1273 | - |
1274 | - if (!string.IsNullOrEmpty(token)) |
1275 | - { |
1276 | - parameters.Add(new QueryParameter(OAuthTokenKey, token)); |
1277 | - } |
1278 | - |
1279 | - parameters.Sort(new QueryParameterComparer()); |
1280 | - |
1281 | - normalizedUrl = string.Format("{0}://{1}", url.Scheme, url.Host); |
1282 | - if (!((url.Scheme == "http" && url.Port == 80) || (url.Scheme == "https" && url.Port == 443))) |
1283 | - { |
1284 | - normalizedUrl += ":" + url.Port; |
1285 | - } |
1286 | - normalizedUrl += url.AbsolutePath; |
1287 | - normalizedRequestParameters = NormalizeRequestParameters(parameters); |
1288 | - |
1289 | - var signatureBase = new StringBuilder(); |
1290 | - signatureBase.AppendFormat("{0}&", httpMethod.ToUpper()); |
1291 | - signatureBase.AppendFormat("{0}&", UrlEncode(normalizedUrl)); |
1292 | - signatureBase.AppendFormat("{0}", UrlEncode(normalizedRequestParameters)); |
1293 | - |
1294 | - return signatureBase.ToString(); |
1295 | - } |
1296 | - |
1297 | - /// <summary> |
1298 | - /// Generate the signature value based on the given signature base and hash algorithm |
1299 | - /// </summary> |
1300 | - /// <param name="signatureBase">The signature based as produced by the GenerateSignatureBase method or by any other means</param> |
1301 | - /// <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> |
1302 | - /// <returns>A base64 string of the hash value</returns> |
1303 | - public string GenerateSignatureUsingHash(string signatureBase, HashAlgorithm hash) |
1304 | - { |
1305 | - return ComputeHash(hash, signatureBase); |
1306 | - } |
1307 | - |
1308 | - /// <summary> |
1309 | - /// Generates a signature using the HMAC-SHA1 algorithm |
1310 | - /// </summary> |
1311 | - /// <param name="url">The full url that needs to be signed including its non OAuth url parameters</param> |
1312 | - /// <param name="consumerKey">The consumer key</param> |
1313 | - /// <param name="consumerSecret">The consumer seceret</param> |
1314 | - /// <param name="token">The token, if available. If not available pass null or an empty string</param> |
1315 | - /// <param name="tokenSecret">The token secret, if available. If not available pass null or an empty string</param> |
1316 | - /// <param name="httpMethod">The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)</param> |
1317 | - /// <param name="timeStamp"></param> |
1318 | - /// <param name="nonce"></param> |
1319 | - /// <param name="normalizedUrl"></param> |
1320 | - /// <param name="normalizedRequestParameters"></param> |
1321 | - /// <returns>A base64 string of the hash value</returns> |
1322 | - 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) |
1323 | - { |
1324 | - return GenerateSignature(url, consumerKey, consumerSecret, token, tokenSecret, httpMethod, timeStamp, nonce, SignatureTypes.HMACSHA1, out normalizedUrl, out normalizedRequestParameters); |
1325 | - } |
1326 | - |
1327 | - /// <summary> |
1328 | - /// Generates a signature using the specified signatureType |
1329 | - /// </summary> |
1330 | - /// <param name="url">The full url that needs to be signed including its non OAuth url parameters</param> |
1331 | - /// <param name="consumerKey">The consumer key</param> |
1332 | - /// <param name="consumerSecret">The consumer seceret</param> |
1333 | - /// <param name="token">The token, if available. If not available pass null or an empty string</param> |
1334 | - /// <param name="tokenSecret">The token secret, if available. If not available pass null or an empty string</param> |
1335 | - /// <param name="httpMethod">The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)</param> |
1336 | - /// <param name="nonce"></param> |
1337 | - /// <param name="signatureType">The type of signature to use</param> |
1338 | - /// <param name="timeStamp"></param> |
1339 | - /// <param name="normalizedUrl"></param> |
1340 | - /// <param name="normalizedRequestParameters"></param> |
1341 | - /// <returns>A base64 string of the hash value</returns> |
1342 | - 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) |
1343 | - { |
1344 | - normalizedUrl = null; |
1345 | - normalizedRequestParameters = null; |
1346 | - |
1347 | - switch (signatureType) |
1348 | - { |
1349 | - case SignatureTypes.PLAINTEXT: |
1350 | - return HttpUtility.UrlEncode(string.Format("{0}&{1}", consumerSecret, tokenSecret)); |
1351 | - case SignatureTypes.HMACSHA1: |
1352 | - var signatureBase = GenerateSignatureBase(url, consumerKey, token, tokenSecret, httpMethod, timeStamp, nonce, HMACSHA1SignatureType, out normalizedUrl, out normalizedRequestParameters); |
1353 | - |
1354 | - var hmacsha1 = new HMACSHA1(); |
1355 | - hmacsha1.Key = Encoding.ASCII.GetBytes(string.Format("{0}&{1}", UrlEncode(consumerSecret), string.IsNullOrEmpty(tokenSecret) ? "" : UrlEncode(tokenSecret))); |
1356 | - |
1357 | - return GenerateSignatureUsingHash(signatureBase, hmacsha1); |
1358 | - case SignatureTypes.RSASHA1: |
1359 | - throw new NotImplementedException(); |
1360 | - default: |
1361 | - throw new ArgumentException("Unknown signature type", "signatureType"); |
1362 | - } |
1363 | - } |
1364 | - |
1365 | - /// <summary> |
1366 | - /// Generate the timestamp for the signature |
1367 | - /// </summary> |
1368 | - /// <returns></returns> |
1369 | - public virtual string GenerateTimeStamp() |
1370 | - { |
1371 | - // Default implementation of UNIX time of the current UTC time |
1372 | - TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0); |
1373 | - return Convert.ToInt64(ts.TotalSeconds).ToString(); |
1374 | - } |
1375 | - |
1376 | - /// <summary> |
1377 | - /// Generate a nonce |
1378 | - /// </summary> |
1379 | - /// <returns></returns> |
1380 | - public virtual string GenerateNonce() |
1381 | - { |
1382 | - // Just a simple implementation of a random number between 123400 and 9999999 |
1383 | - return Random.Next(123400, 9999999).ToString(); |
1384 | - } |
1385 | - |
1386 | - } |
1387 | -} |
1388 | \ No newline at end of file |
1389 | |
1390 | === added file 'src/Canonical.Ubuntu.SSO/SSOException.cs' |
1391 | --- src/Canonical.Ubuntu.SSO/SSOException.cs 1970-01-01 00:00:00 +0000 |
1392 | +++ src/Canonical.Ubuntu.SSO/SSOException.cs 2010-10-05 09:58:35 +0000 |
1393 | @@ -0,0 +1,57 @@ |
1394 | +/* Copyright 2010 Canonical Ltd. |
1395 | + * |
1396 | + * This file is part of UbuntuOne on Windows. |
1397 | + * |
1398 | + * UbuntuOne on Windows is free software: you can redistribute it and/or modify |
1399 | + * it under the terms of the GNU Lesser General Public License version |
1400 | + * as published by the Free Software Foundation. |
1401 | + * |
1402 | + * Ubuntu One on Windows is distributed in the hope that it will be useful, |
1403 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1404 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1405 | + * GNU Lesser General Public License for more details. |
1406 | + * |
1407 | + * You should have received a copy of the GNU Lesser General Public License |
1408 | + * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>. |
1409 | + * |
1410 | + * Authors: Manuel de la Peña <manuel.delapena@canonical.com> |
1411 | + */ |
1412 | +using System; |
1413 | + |
1414 | +namespace Canonical.Ubuntu.SSO |
1415 | +{ |
1416 | + /// <summary> |
1417 | + /// Root exception class for all those SSO problems. |
1418 | + /// </summary> |
1419 | + public class SSOException : Exception |
1420 | + { |
1421 | + /// <summary> |
1422 | + /// Creates a new instance of the class with no message or inner exception. |
1423 | + /// </summary> |
1424 | + public SSOException() |
1425 | + { |
1426 | + |
1427 | + } |
1428 | + |
1429 | + /// <summary> |
1430 | + /// Creates a new instance of the class with the given message. |
1431 | + /// </summary> |
1432 | + /// <param name="message">The message to be carried by the exception.</param> |
1433 | + public SSOException(string message) |
1434 | + : base(message) |
1435 | + { |
1436 | + |
1437 | + } |
1438 | + |
1439 | + /// <summary> |
1440 | + /// Creates a new instance of the class with the given message and inner exception. |
1441 | + /// </summary> |
1442 | + /// <param name="message">The message to be carried by the exception.</param> |
1443 | + /// <param name="e">The inner exception.</param> |
1444 | + public SSOException(string message, Exception e) |
1445 | + : base(message, e) |
1446 | + { |
1447 | + |
1448 | + } |
1449 | + } |
1450 | +} |
1451 | |
1452 | === added file 'src/Canonical.Ubuntu.SSO/SSOLoginException.cs' |
1453 | --- src/Canonical.Ubuntu.SSO/SSOLoginException.cs 1970-01-01 00:00:00 +0000 |
1454 | +++ src/Canonical.Ubuntu.SSO/SSOLoginException.cs 2010-10-05 09:58:35 +0000 |
1455 | @@ -0,0 +1,57 @@ |
1456 | +/* Copyright 2010 Canonical Ltd. |
1457 | + * |
1458 | + * This file is part of UbuntuOne on Windows. |
1459 | + * |
1460 | + * UbuntuOne on Windows is free software: you can redistribute it and/or modify |
1461 | + * it under the terms of the GNU Lesser General Public License version |
1462 | + * as published by the Free Software Foundation. |
1463 | + * |
1464 | + * Ubuntu One on Windows is distributed in the hope that it will be useful, |
1465 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1466 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1467 | + * GNU Lesser General Public License for more details. |
1468 | + * |
1469 | + * You should have received a copy of the GNU Lesser General Public License |
1470 | + * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>. |
1471 | + * |
1472 | + * Authors: Manuel de la Peña <manuel.delapena@canonical.com> |
1473 | + */ |
1474 | +using System; |
1475 | + |
1476 | +namespace Canonical.Ubuntu.SSO |
1477 | +{ |
1478 | + /// <summary> |
1479 | + /// Exception thrown when there are errors during a login. |
1480 | + /// </summary> |
1481 | + public class SSOLoginException : SSOException |
1482 | + { |
1483 | + /// <summary> |
1484 | + /// Creates a new instance of the class with no message or inner exception. |
1485 | + /// </summary> |
1486 | + public SSOLoginException() |
1487 | + { |
1488 | + |
1489 | + } |
1490 | + |
1491 | + /// <summary> |
1492 | + /// Creates a new instance of the class with the given message. |
1493 | + /// </summary> |
1494 | + /// <param name="message">The message to be carried by the exception.</param> |
1495 | + public SSOLoginException(string message) |
1496 | + : base(message) |
1497 | + { |
1498 | + |
1499 | + } |
1500 | + |
1501 | + /// <summary> |
1502 | + /// Creates a new instance of the class with the given message and inner exception. |
1503 | + /// </summary> |
1504 | + /// <param name="message">The message to be carried by the exception.</param> |
1505 | + /// <param name="e">The inner exception.</param> |
1506 | + public SSOLoginException(string message, Exception e) |
1507 | + : base(message, e) |
1508 | + { |
1509 | + |
1510 | + } |
1511 | + } |
1512 | +} |
1513 | |
1514 | === modified file 'src/Canonical.Ubuntu.SSO/SSOLoginProcessor.cs' |
1515 | --- src/Canonical.Ubuntu.SSO/SSOLoginProcessor.cs 2010-09-20 11:21:19 +0000 |
1516 | +++ src/Canonical.Ubuntu.SSO/SSOLoginProcessor.cs 2010-10-05 09:58:35 +0000 |
1517 | @@ -18,6 +18,10 @@ |
1518 | * Authors: Manuel de la Peña <manuel.delapena@canonical.com> |
1519 | */ |
1520 | using System; |
1521 | +using System.Net; |
1522 | +using Canonical.Ubuntu.SSO.Service; |
1523 | +using Canonical.UbuntuOne.Common.Net; |
1524 | +using Newtonsoft.Json.Linq; |
1525 | |
1526 | namespace Canonical.Ubuntu.SSO |
1527 | { |
1528 | @@ -27,6 +31,126 @@ |
1529 | /// </summary> |
1530 | public class SSOLoginProcessor : ISSOLoginProcessor |
1531 | { |
1532 | + private const string ApplicationTokenName = "Ubuntu One @ {0} (Windows)"; |
1533 | + internal const string KeyringName = "Default"; |
1534 | + internal const string ApplicationName = "UbuntuOne"; |
1535 | + |
1536 | + #region DI properties |
1537 | + |
1538 | + /// <summary> |
1539 | + /// Gets and sets the Authentications rest service that is used to authenticate the user. |
1540 | + /// </summary> |
1541 | + public Authentications Authentications { get; set; } |
1542 | + |
1543 | + /// <summary> |
1544 | + /// Gets and sets the keyring that will be used to store the secrets. |
1545 | + /// </summary> |
1546 | + public IKeyring Keyring { get; set; } |
1547 | + |
1548 | + /// <summary> |
1549 | + /// Gets and sets the credential encoder that will be used to encode the oauth credentials |
1550 | + /// before they are saved in the keyring. |
1551 | + /// </summary> |
1552 | + public ISSOCredentialsEncoder SSOCredentialsEncoder { get; set; } |
1553 | + |
1554 | + /// <summary> |
1555 | + /// Gets and sets the object that will take care of the oauth operations. |
1556 | + /// </summary> |
1557 | + public IOAuth OAuth { get; set; } |
1558 | + |
1559 | + public IHttpWebRequestFactory HttpWebRequestFactory { get; set; } |
1560 | + |
1561 | + #endregion |
1562 | + |
1563 | + #region Helper methods} |
1564 | + |
1565 | + /// <summary> |
1566 | + /// Creates an oauth request that can access a protected web resource. |
1567 | + /// </summary> |
1568 | + /// <param name="uri">The uri where the resource is found.</param> |
1569 | + /// <param name="httpMethod">The request berb to be used.</param> |
1570 | + /// <param name="consumerKey">Consumer key from oauth.</param> |
1571 | + /// <param name="consumerSecret">Consumer secret from oauth.</param> |
1572 | + /// <param name="token">Token from oauth.</param> |
1573 | + /// <param name="tokenSecret">Token secret from oauth.</param> |
1574 | + /// <returns>A webrequest that can be used to access the resource.</returns> |
1575 | + public IHttpWebRequest MakeRequest(string uri, string httpMethod, string consumerKey, string consumerSecret, string token, string tokenSecret) |
1576 | + { |
1577 | + // Form the full REST request url |
1578 | + var url = new Uri(uri); |
1579 | + string normUrl; |
1580 | + string normParams; |
1581 | + |
1582 | + // get oauth header |
1583 | + var authHeader = OAuth.GenerateHeaderWithSignature(url, string.Empty, consumerKey, consumerSecret, |
1584 | + token, tokenSecret, httpMethod, OAuth.GenerateTimeStamp(), OAuth.GenerateNonce(), SSO.OAuth.SignatureTypes.HMACSHA1, |
1585 | + out normUrl, out normParams); |
1586 | + |
1587 | + var request = HttpWebRequestFactory.Create(url); |
1588 | + request.Headers.Add(authHeader.Key, authHeader.Value); |
1589 | + return request; |
1590 | + } |
1591 | + |
1592 | + /// <summary> |
1593 | + /// Pings the Ubuntu One server so that the SSO tokens are added to them and they know how to identify the user. |
1594 | + /// </summary> |
1595 | + /// <param name="email">The email used by the user to register to u1.</param> |
1596 | + /// <param name="consumerKey">The oauth consumer key.</param> |
1597 | + /// <param name="consumerSecret">The oauth consumer secret.</param> |
1598 | + /// <param name="token">The oauth token.</param> |
1599 | + /// <param name="tokenSecret">The oauth secret.</param> |
1600 | + private void PingUbuntuOneServer(string email, string consumerKey, string consumerSecret, string token, string tokenSecret) |
1601 | + { |
1602 | + // ping the service to make it download the tokens |
1603 | + var pingRequest = MakeRequest(Constants.PingUrl + email, "GET", consumerKey, consumerSecret, |
1604 | + token, tokenSecret); |
1605 | + try |
1606 | + { |
1607 | + pingRequest.GetResponse(); |
1608 | + } |
1609 | + catch (Exception e) |
1610 | + { |
1611 | + throw new SSOException("Credentials could not be sent to Ubuntu One servers", e); |
1612 | + } |
1613 | + } |
1614 | + |
1615 | + /// <summary> |
1616 | + /// Allows to parse the json that is returned by the rest service to extract that credentials. |
1617 | + /// </summary> |
1618 | + /// <param name="credentialsJson">Json that contains the credentials info.</param> |
1619 | + /// <param name="consumerKey">Out var where the oauth consumer key will be returned.</param> |
1620 | + /// <param name="consumerSecret">Out var where the oauth consumer secret will be returned.</param> |
1621 | + /// <param name="token">Out var where the oauth token secret will be returned.</param> |
1622 | + /// <param name="tokenSecret">Out var where the oauth token secret will be returned.</param> |
1623 | + private static void ParseCredentials(string credentialsJson, out string consumerKey, out string consumerSecret, out string token, |
1624 | + out string tokenSecret) |
1625 | + { |
1626 | + var credentials = JObject.Parse(credentialsJson); |
1627 | + try |
1628 | + { |
1629 | + consumerKey = (string)credentials["consumer_key"]; |
1630 | + consumerSecret = (string)credentials["consumer_secret"]; |
1631 | + token = (string)credentials["token"]; |
1632 | + tokenSecret = (string)credentials["token_secret"]; |
1633 | + |
1634 | + } |
1635 | + catch (InvalidCastException e) |
1636 | + { |
1637 | + // could happen when the json is not formatted as we expected. |
1638 | + throw new SSOLoginException("Error when retrieving credentials.", e); |
1639 | + } |
1640 | + if (string.IsNullOrEmpty(consumerKey) |
1641 | + || string.IsNullOrEmpty(consumerSecret) |
1642 | + || string.IsNullOrEmpty(token) |
1643 | + || string.IsNullOrEmpty(tokenSecret)) |
1644 | + { |
1645 | + // none of them can be null or empty. |
1646 | + throw new SSOLoginException("Credentials have missing values.."); |
1647 | + } |
1648 | + |
1649 | + } |
1650 | + #endregion |
1651 | + |
1652 | #region Implementation of ISSOLoginProcessor |
1653 | |
1654 | /// <summary> |
1655 | @@ -61,7 +185,36 @@ |
1656 | /// <returns>A string with the sso credentials.</returns> |
1657 | public string Login(string email, string password, string tokenName) |
1658 | { |
1659 | - throw new NotImplementedException(); |
1660 | + var secret = Keyring.GetSecretByName(KeyringName, ApplicationName); |
1661 | + if (secret == null) |
1662 | + { |
1663 | + try |
1664 | + { |
1665 | + // credentials are not present in the keyring, therefore we will have to get them from the |
1666 | + // rest service |
1667 | + string token; |
1668 | + string tokenSecret; |
1669 | + string consumerKey; |
1670 | + string consumerSecret; |
1671 | + |
1672 | + // the rest server returns json, we need to parse it. |
1673 | + ParseCredentials(Authentications.Authenticate(email, password, tokenName), |
1674 | + out consumerKey, out consumerSecret, out token, out tokenSecret); |
1675 | + secret = SSOCredentialsEncoder.Encode(token, tokenSecret, consumerKey, consumerSecret); |
1676 | + // ping the service to make it download the tokens |
1677 | + PingUbuntuOneServer(email, consumerKey, consumerKey, token, tokenSecret); |
1678 | + Keyring.CreateSecret(KeyringName, ApplicationName, secret); |
1679 | + } |
1680 | + catch (WebException e) |
1681 | + { |
1682 | + throw new SSOLoginException("Unable to login", e); |
1683 | + } |
1684 | + catch (Exception e) |
1685 | + { |
1686 | + throw new SSOLoginException("Unable to login", e); |
1687 | + } |
1688 | + } |
1689 | + return secret; |
1690 | } |
1691 | |
1692 | /// <summary> |
1693 | |
1694 | === modified file 'src/Canonical.UbuntuOne.Client/Notification/NotificationIconPresenter.cs' |
1695 | --- src/Canonical.UbuntuOne.Client/Notification/NotificationIconPresenter.cs 2010-10-05 09:58:34 +0000 |
1696 | +++ src/Canonical.UbuntuOne.Client/Notification/NotificationIconPresenter.cs 2010-10-05 09:58:35 +0000 |
1697 | @@ -1,25 +1,25 @@ |
1698 | -// Copyright 2010 Canonical Ltd. |
1699 | -// |
1700 | -// This file is part of UbuntuOne on Windows. |
1701 | -// |
1702 | -// UbuntuOne on Windows is free software: you can redistribute it and/or modify |
1703 | -// it under the terms of the GNU Lesser General Public License version |
1704 | -// as published by the Free Software Foundation. |
1705 | -// |
1706 | -// Ubuntu One on Windows is distributed in the hope that it will be useful, |
1707 | -// but WITHOUT ANY WARRANTY; without even the implied warranty of |
1708 | -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1709 | -// GNU Lesser General Public License for more details. |
1710 | -// |
1711 | -// You should have received a copy of the GNU Lesser General Public License |
1712 | -// along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>. |
1713 | -// |
1714 | -// Authors: Manuel de la Peña <manuel.delapena@canonical.com> |
1715 | +/* Copyright 2010 Canonical Ltd. |
1716 | + * |
1717 | + * This file is part of UbuntuOne on Windows. |
1718 | + * |
1719 | + * UbuntuOne on Windows is free software: you can redistribute it and/or modify |
1720 | + * it under the terms of the GNU Lesser General Public License version |
1721 | + * as published by the Free Software Foundation. |
1722 | + * |
1723 | + * Ubuntu One on Windows is distributed in the hope that it will be useful, |
1724 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1725 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1726 | + * GNU Lesser General Public License for more details. |
1727 | + * |
1728 | + * You should have received a copy of the GNU Lesser General Public License |
1729 | + * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>. |
1730 | + * |
1731 | + * Authors: Manuel de la Peña <manuel.delapena@canonical.com> |
1732 | + */ |
1733 | using System; |
1734 | using System.Diagnostics; |
1735 | using System.IO; |
1736 | using System.Net; |
1737 | -using System.Web; |
1738 | using System.Windows; |
1739 | using Canonical.Ubuntu.SSO; |
1740 | using Canonical.Ubuntu.SSO.Service; |
1741 | @@ -29,7 +29,6 @@ |
1742 | using Canonical.UbuntuOne.Common.Utils; |
1743 | using log4net; |
1744 | using Newtonsoft.Json.Linq; |
1745 | -using OAuth; |
1746 | |
1747 | namespace Canonical.UbuntuOne.Client.Notification |
1748 | { |
1749 | @@ -148,33 +147,23 @@ |
1750 | |
1751 | #region Helper methods |
1752 | |
1753 | - public HttpWebRequest MakeRequest(string uri, string consumerKey, string consumerSecret, string toke, string tokenSecret) |
1754 | + public HttpWebRequest MakeRequest(string uri, string consumerKey, string consumerSecret, string token, string tokenSecret) |
1755 | { |
1756 | // Form the full REST request url |
1757 | Uri url = new Uri(uri); |
1758 | |
1759 | // Instantiate OAuthBase and declare variables |
1760 | - var oAuth = new OAuthBase(); |
1761 | - var nonce = oAuth.GenerateNonce(); |
1762 | - var timeStamp = oAuth.GenerateTimeStamp(); |
1763 | + var oAuth = new OAuth(); |
1764 | + |
1765 | var normUrl = string.Empty; |
1766 | var normParams = string.Empty; |
1767 | - var strRequest = string.Empty; |
1768 | |
1769 | - // Create an OAuth signature |
1770 | - string signature = oAuth.GenerateSignature(url, |
1771 | - consumerKey, consumerSecret, toke, tokenSecret, |
1772 | - "GET", timeStamp, nonce, OAuthBase.SignatureTypes.HMACSHA1, |
1773 | + var authHeader = oAuth.GenerateHeaderWithSignature(url, string.Empty, consumerKey, consumerSecret, |
1774 | + token, tokenSecret, "GET", oAuth.GenerateTimeStamp(), oAuth.GenerateNonce(), OAuth.SignatureTypes.HMACSHA1, |
1775 | out normUrl, out normParams); |
1776 | - |
1777 | - // Construct the OAuth authenticated REST url |
1778 | - strRequest = normParams + "&" + HttpUtility.UrlEncode("oauth_signature") + "=" + HttpUtility.UrlEncode(signature); |
1779 | - strRequest = strRequest.Replace("&", @""","); |
1780 | - strRequest = strRequest.Replace("=", @"="""); |
1781 | - strRequest += @""""; |
1782 | - strRequest = @"OAuth realm=""""," + strRequest; |
1783 | + |
1784 | var request = WebRequest.Create(normUrl) as HttpWebRequest; |
1785 | - request.Headers.Add("Authorization", strRequest); |
1786 | + request.Headers.Add(authHeader.Key, authHeader.Value); |
1787 | return request; |
1788 | } |
1789 | |
1790 | |
1791 | === modified file 'src/Canonical.UbuntuOne.Common/Canonical.UbuntuOne.Common.csproj' |
1792 | --- src/Canonical.UbuntuOne.Common/Canonical.UbuntuOne.Common.csproj 2010-08-30 17:30:31 +0000 |
1793 | +++ src/Canonical.UbuntuOne.Common/Canonical.UbuntuOne.Common.csproj 2010-10-05 09:58:35 +0000 |
1794 | @@ -57,6 +57,10 @@ |
1795 | <Compile Include="Container\ObjectsContainer.cs" /> |
1796 | <Compile Include="Container\SpringContainer.cs" /> |
1797 | <Compile Include="Container\UnsatisfiedDependencyException.cs" /> |
1798 | + <Compile Include="Net\HttpWebRequest.cs" /> |
1799 | + <Compile Include="Net\HttpWebRequestFactory.cs" /> |
1800 | + <Compile Include="Net\IHttpWebRequestFactory.cs" /> |
1801 | + <Compile Include="Net\IHttpWebRequest.cs" /> |
1802 | <Compile Include="OperationContracts\IEventNotifier.cs" /> |
1803 | <Compile Include="Security\IAuthentication.cs" /> |
1804 | <Compile Include="Threading\IDispatcher.cs" /> |
1805 | |
1806 | === added directory 'src/Canonical.UbuntuOne.Common/Net' |
1807 | === added file 'src/Canonical.UbuntuOne.Common/Net/HttpWebRequest.cs' |
1808 | --- src/Canonical.UbuntuOne.Common/Net/HttpWebRequest.cs 1970-01-01 00:00:00 +0000 |
1809 | +++ src/Canonical.UbuntuOne.Common/Net/HttpWebRequest.cs 2010-10-05 09:58:35 +0000 |
1810 | @@ -0,0 +1,505 @@ |
1811 | +/* |
1812 | + * Copyright 2010 Canonical Ltd. |
1813 | + * |
1814 | + * This file is part of UbuntuOne on Windows. |
1815 | + * |
1816 | + * UbuntuOne on Windows is free software: you can redistribute it and/or modify |
1817 | + * it under the terms of the GNU Lesser General Public License version |
1818 | + * as published by the Free Software Foundation. |
1819 | + * |
1820 | + * Ubuntu One on Windows is distributed in the hope that it will be useful, |
1821 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1822 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1823 | + * GNU Lesser General Public License for more details. |
1824 | + * |
1825 | + * You should have received a copy of the GNU Lesser General Public License |
1826 | + * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>. |
1827 | + * |
1828 | + * Authors: Manuel de la Peña <manuel.delapena@canonical.com> |
1829 | + */ |
1830 | +using System; |
1831 | +using System.IO; |
1832 | +using System.Net; |
1833 | +using System.Net.Cache; |
1834 | +using System.Net.Security; |
1835 | +using System.Security.Cryptography.X509Certificates; |
1836 | +using System.Security.Principal; |
1837 | +using RealHttpRequest = System.Net.HttpWebRequest; |
1838 | + |
1839 | +namespace Canonical.UbuntuOne.Common.Net |
1840 | +{ |
1841 | + /// <summary> |
1842 | + /// Wrapper around the System.Net.HttpWebRequest. |
1843 | + /// </summary> |
1844 | + internal class HttpWebRequest : IHttpWebRequest |
1845 | + { |
1846 | + #region Variables |
1847 | + |
1848 | + private RealHttpRequest _request; |
1849 | + |
1850 | + #endregion |
1851 | + |
1852 | + #region Constructors |
1853 | + |
1854 | + /// <summary> |
1855 | + /// Internal constructor that can only be used by a httpweb request factory. |
1856 | + /// </summary> |
1857 | + /// <param name="httpWebRequest"></param> |
1858 | + internal HttpWebRequest(RealHttpRequest httpWebRequest) |
1859 | + { |
1860 | + _request = httpWebRequest; |
1861 | + } |
1862 | + |
1863 | + #endregion |
1864 | + |
1865 | + #region Implementation of IHttpWebRequest |
1866 | + |
1867 | + /// <summary> |
1868 | + /// Gets and sets value of the Accept HTTP header. The default value is null. |
1869 | + /// </summary> |
1870 | + public string Accept |
1871 | + { |
1872 | + get { return _request.Accept; } |
1873 | + set { _request.Accept = value; } |
1874 | + } |
1875 | + |
1876 | + /// <summary> |
1877 | + /// Gets and sets the uri that responds to the request. |
1878 | + /// </summary> |
1879 | + public Uri Address |
1880 | + { |
1881 | + get { return _request.Address; } |
1882 | + } |
1883 | + |
1884 | + /// <summary> |
1885 | + /// Gets and sets if the request should automatically follow redirection responses |
1886 | + /// </summary> |
1887 | + public bool AllowAutoRedirect |
1888 | + { |
1889 | + get { return _request.AllowAutoRedirect; } |
1890 | + set { _request.AllowAutoRedirect = value; } |
1891 | + } |
1892 | + |
1893 | + /// <summary> |
1894 | + /// Enables buffering of the data sent to the Internet resource |
1895 | + /// </summary> |
1896 | + public bool AllowWriteStreamBuffering |
1897 | + { |
1898 | + get { return _request.AllowWriteStreamBuffering; } |
1899 | + set { _request.AllowWriteStreamBuffering = value; } |
1900 | + } |
1901 | + |
1902 | + /// <summary> |
1903 | + /// Gets and sets the auhentication lavel used. |
1904 | + /// </summary> |
1905 | + public AuthenticationLevel AuthenticationLevel |
1906 | + { |
1907 | + get { return _request.AuthenticationLevel; } |
1908 | + set { _request.AuthenticationLevel = value; } |
1909 | + } |
1910 | + |
1911 | + /// <summary> |
1912 | + /// Gets and sets the type of decompression that is used. |
1913 | + /// </summary> |
1914 | + public DecompressionMethods AutomaticDecompression |
1915 | + { |
1916 | + get { return _request.AutomaticDecompression; } |
1917 | + set { _request.AutomaticDecompression = value; } |
1918 | + } |
1919 | + |
1920 | + /// <summary> |
1921 | + /// Gets or sets the cache policy used by the request. |
1922 | + /// </summary> |
1923 | + public RequestCachePolicy CachePolicy |
1924 | + { |
1925 | + get { return _request.CachePolicy; } |
1926 | + set { _request.CachePolicy = value; } |
1927 | + } |
1928 | + |
1929 | + /// <summary> |
1930 | + /// Gets and sets the certificates used by the request. |
1931 | + /// </summary> |
1932 | + public X509CertificateCollection ClientCertificates |
1933 | + { |
1934 | + get { return _request.ClientCertificates; } |
1935 | + set { _request.ClientCertificates = value; } |
1936 | + } |
1937 | + |
1938 | + /// <summary> |
1939 | + /// Gets and sets the Connection HTTP header |
1940 | + /// </summary> |
1941 | + public string Connection |
1942 | + { |
1943 | + get { return _request.Connection; } |
1944 | + set { _request.Connection = value; } |
1945 | + } |
1946 | + |
1947 | + /// <summary> |
1948 | + /// Gets and sets the name of the connection group for this request |
1949 | + /// </summary> |
1950 | + public string ConnectionGroupName |
1951 | + { |
1952 | + get { return _request.ConnectionGroupName; } |
1953 | + set { _request.ConnectionGroupName = value; } |
1954 | + } |
1955 | + |
1956 | + /// <summary> |
1957 | + /// Gets and sets the number of bytes of data to send to the Internet resource. |
1958 | + /// </summary> |
1959 | + public long ContentLength |
1960 | + { |
1961 | + get { return _request.ContentLength; } |
1962 | + set { _request.ContentLength = value; } |
1963 | + } |
1964 | + |
1965 | + /// <summary> |
1966 | + /// Gets and sets the content type of the request. |
1967 | + /// </summary> |
1968 | + public string ContentType |
1969 | + { |
1970 | + get { return _request.ContentType; } |
1971 | + set { _request.ContentType = value; } |
1972 | + } |
1973 | + |
1974 | + /// <summary> |
1975 | + /// Gets and sets the delegate that implements the callback method that |
1976 | + /// executes when an HTTP Continue response is returned from the Internet resource. |
1977 | + /// </summary> |
1978 | + public HttpContinueDelegate ContinueDelegate |
1979 | + { |
1980 | + get { return _request.ContinueDelegate; } |
1981 | + set { _request.ContinueDelegate = value; } |
1982 | + } |
1983 | + |
1984 | + /// <summary> |
1985 | + /// Gets and sets cookies container associated with this request. |
1986 | + /// </summary> |
1987 | + public CookieContainer CookieContainer |
1988 | + { |
1989 | + get { return _request.CookieContainer; } |
1990 | + set { _request.CookieContainer = value; } |
1991 | + } |
1992 | + |
1993 | + /// <summary> |
1994 | + /// Gets and sets the credentials used with the request. |
1995 | + /// </summary> |
1996 | + public ICredentials Credentials |
1997 | + { |
1998 | + get { return _request.Credentials; } |
1999 | + set { _request.Credentials = value; } |
2000 | + } |
2001 | + |
2002 | + /// <summary> |
2003 | + /// Gets and sets the data header of the request. |
2004 | + /// </summary> |
2005 | + public DateTime Date |
2006 | + { |
2007 | + get { throw new NotImplementedException(); } |
2008 | + set { throw new NotImplementedException(); } |
2009 | + } |
2010 | + |
2011 | + /// <summary> |
2012 | + /// Gets and sets the Expect HTTP header. |
2013 | + /// </summary> |
2014 | + public string Expect |
2015 | + { |
2016 | + get { return _request.Expect; } |
2017 | + set { _request.Expect = value; } |
2018 | + } |
2019 | + |
2020 | + /// <summary> |
2021 | + /// Gets if a response has been received. |
2022 | + /// </summary> |
2023 | + public bool HaveResponse |
2024 | + { |
2025 | + get { return _request.HaveResponse; } |
2026 | + } |
2027 | + |
2028 | + /// <summary> |
2029 | + /// Gets and sets the headers of the request, |
2030 | + /// </summary> |
2031 | + public WebHeaderCollection Headers |
2032 | + { |
2033 | + get { return _request.Headers; } |
2034 | + set { _request.Headers = value; } |
2035 | + } |
2036 | + |
2037 | + /// <summary> |
2038 | + /// Gets and sets the Host header. |
2039 | + /// </summary> |
2040 | + public string Host |
2041 | + { |
2042 | + get { throw new NotImplementedException(); } |
2043 | + set { throw new NotImplementedException(); } |
2044 | + } |
2045 | + |
2046 | + /// <summary> |
2047 | + /// A DateTime that contains the contents of the If-Modified-Since HTTP header. |
2048 | + /// </summary> |
2049 | + public DateTime IfModifiedSince |
2050 | + { |
2051 | + get { return _request.IfModifiedSince; } |
2052 | + set { _request.IfModifiedSince = value; } |
2053 | + } |
2054 | + |
2055 | + /// <summary> |
2056 | + /// Gets and sets the the impersonation level. |
2057 | + /// </summary> |
2058 | + public TokenImpersonationLevel ImpersonationLevel |
2059 | + { |
2060 | + get { return _request.ImpersonationLevel; } |
2061 | + set { _request.ImpersonationLevel = value; } |
2062 | + } |
2063 | + |
2064 | + /// <summary> |
2065 | + /// Gets and sets if the request should have a Connection HTTP header. |
2066 | + /// </summary> |
2067 | + public bool KeepAlive |
2068 | + { |
2069 | + get { return _request.KeepAlive; } |
2070 | + set { _request.KeepAlive = value; } |
2071 | + } |
2072 | + |
2073 | + /// <summary> |
2074 | + /// Gets and sets the max number of redirections. |
2075 | + /// </summary> |
2076 | + public int MaximumAutomaticRedirections |
2077 | + { |
2078 | + get { return _request.MaximumAutomaticRedirections; } |
2079 | + set { _request.MaximumAutomaticRedirections = value; } |
2080 | + } |
2081 | + |
2082 | + /// <summary> |
2083 | + /// Gets and sets The length, in kilobytes (1024 bytes), of the response headers. |
2084 | + /// </summary> |
2085 | + public int MaximumResponseHeadersLength |
2086 | + { |
2087 | + get { return _request.MaximumResponseHeadersLength; } |
2088 | + set { _request.MaximumResponseHeadersLength = value; } |
2089 | + } |
2090 | + |
2091 | + /// <summary> |
2092 | + /// The media type of the request. |
2093 | + /// </summary> |
2094 | + public string MediaType |
2095 | + { |
2096 | + get { return _request.MediaType; } |
2097 | + set { _request.MediaType = value; } |
2098 | + } |
2099 | + |
2100 | + /// <summary> |
2101 | + /// Gets and sets the request method. |
2102 | + /// </summary> |
2103 | + public string Method |
2104 | + { |
2105 | + get { return _request.Method; } |
2106 | + set { _request.Method = value; } |
2107 | + } |
2108 | + |
2109 | + /// <summary> |
2110 | + /// Gets and sets if the request should be pipelined |
2111 | + /// </summary> |
2112 | + public bool Pipelined |
2113 | + { |
2114 | + get { return _request.Pipelined; } |
2115 | + set { _request.Pipelined = value; } |
2116 | + } |
2117 | + |
2118 | + /// <summary> |
2119 | + /// Gets and sets if an HTTP Authorization header with requests after authentication has taken place; |
2120 | + /// </summary> |
2121 | + public bool PreAuthenticate |
2122 | + { |
2123 | + get { return _request.PreAuthenticate; } |
2124 | + set { _request.PreAuthenticate = value; } |
2125 | + } |
2126 | + |
2127 | + /// <summary> |
2128 | + /// Gets and sets the protol version used. |
2129 | + /// </summary> |
2130 | + public Version ProtocolVersion |
2131 | + { |
2132 | + get { return _request.ProtocolVersion; } |
2133 | + set { _request.ProtocolVersion = value; } |
2134 | + } |
2135 | + |
2136 | + /// <summary> |
2137 | + /// Gets and sets the proxy information. |
2138 | + /// </summary> |
2139 | + public IWebProxy Proxy |
2140 | + { |
2141 | + get { return _request.Proxy; } |
2142 | + set { _request.Proxy = value; } |
2143 | + } |
2144 | + |
2145 | + /// <summary> |
2146 | + /// Gets and sets the number of milliseconds before the writing or reading times out.. |
2147 | + /// </summary> |
2148 | + public int ReadWriteTimeout |
2149 | + { |
2150 | + get { return _request.ReadWriteTimeout; } |
2151 | + set { _request.ReadWriteTimeout = value; } |
2152 | + } |
2153 | + |
2154 | + /// <summary> |
2155 | + /// Gets and sets the Referer HTTP header. |
2156 | + /// </summary> |
2157 | + public string Referer |
2158 | + { |
2159 | + get { return _request.Referer; } |
2160 | + set { _request.Referer = value; } |
2161 | + } |
2162 | + |
2163 | + /// <summary> |
2164 | + /// Gets the resource uri used by the request. |
2165 | + /// </summary> |
2166 | + public Uri RequestUri |
2167 | + { |
2168 | + get { return _request.RequestUri; } |
2169 | + } |
2170 | + |
2171 | + /// <summary> |
2172 | + /// Ges and sets if the request should be sent in chuckes. |
2173 | + /// </summary> |
2174 | + public bool SendChunked |
2175 | + { |
2176 | + get { return _request.SendChunked; } |
2177 | + set { _request.SendChunked = value; } |
2178 | + } |
2179 | + |
2180 | + /// <summary> |
2181 | + /// Gets the service point that represents the internet resource. |
2182 | + /// </summary> |
2183 | + public ServicePoint ServicePoint |
2184 | + { |
2185 | + get { return _request.ServicePoint; } |
2186 | + } |
2187 | + |
2188 | + /// <summary> |
2189 | + /// Gets and sets the number of milliseconds to wait before the request times out. |
2190 | + /// </summary> |
2191 | + public int Timeout |
2192 | + { |
2193 | + get { return _request.Timeout; } |
2194 | + set { _request.Timeout = value; } |
2195 | + } |
2196 | + |
2197 | + /// <summary> |
2198 | + /// Gets and sets the Transfer-encoding HTTP header. |
2199 | + /// </summary> |
2200 | + public string TransferEncoding |
2201 | + { |
2202 | + get { return _request.TransferEncoding; } |
2203 | + set { _request.TransferEncoding = value; } |
2204 | + } |
2205 | + |
2206 | + /// <summary> |
2207 | + /// Gets and sets if the authenticated connection is kept opened. |
2208 | + /// </summary> |
2209 | + public bool UnsafeAuthenticatedConnectionSharing |
2210 | + { |
2211 | + get { return _request.UnsafeAuthenticatedConnectionSharing; } |
2212 | + set { _request.UnsafeAuthenticatedConnectionSharing = value; } |
2213 | + } |
2214 | + |
2215 | + /// <summary> |
2216 | + /// Gets and sets if the default credentials are used. |
2217 | + /// </summary> |
2218 | + public bool UseDefaultCredentials |
2219 | + { |
2220 | + get { return _request.UseDefaultCredentials; } |
2221 | + set { _request.UseDefaultCredentials = value; } |
2222 | + } |
2223 | + |
2224 | + /// <summary> |
2225 | + /// Gets or sets the User-agent HTTP header; |
2226 | + /// </summary> |
2227 | + public string UserAgent |
2228 | + { |
2229 | + get { return _request.UserAgent; } |
2230 | + set { _request.UserAgent = value; } |
2231 | + } |
2232 | + |
2233 | + /// <summary> |
2234 | + /// Cancels a request to a resource |
2235 | + /// </summary> |
2236 | + public void Abort() |
2237 | + { |
2238 | + _request.Abort(); |
2239 | + } |
2240 | + |
2241 | + /// <summary> |
2242 | + /// Begins an asynchronous request for a Stream object to use to write data. |
2243 | + /// </summary> |
2244 | + /// <param name="callback">The delegate to execute.</param> |
2245 | + /// <param name="state">Teh state object of the request. </param> |
2246 | + /// <returns>An async result.</returns> |
2247 | + public IAsyncResult BeginGetRequestStream(AsyncCallback callback, object state) |
2248 | + { |
2249 | + return _request.BeginGetRequestStream(callback, state); |
2250 | + } |
2251 | + |
2252 | + /// <summary> |
2253 | + /// Begins an asynchronous request to an Internet resource. |
2254 | + /// </summary> |
2255 | + /// <param name="callback">Teh deleaget.</param> |
2256 | + /// <param name="state">Teh state object fo the response.</param> |
2257 | + /// <returns>an asyn result.</returns> |
2258 | + public IAsyncResult BeginGetResponse(AsyncCallback callback, object state) |
2259 | + { |
2260 | + return _request.BeginGetResponse(callback, state); |
2261 | + } |
2262 | + |
2263 | + /// <summary> |
2264 | + /// Ends an asynchronous request for a Stream object to use to write data. |
2265 | + /// </summary> |
2266 | + /// <param name="asyncResult">The result from the async request.</param> |
2267 | + /// <returns>Teh stream from teh request.</returns> |
2268 | + public Stream EndGetRequestStream(IAsyncResult asyncResult) |
2269 | + { |
2270 | + return EndGetRequestStream(asyncResult); |
2271 | + } |
2272 | + |
2273 | + /// <summary> |
2274 | + /// Ends an asynchronous request for a Stream object to use to write data and outputs |
2275 | + /// the TransportContext associated with the stream. |
2276 | + /// </summary> |
2277 | + /// <param name="asyncResult">The async result from the request stream.</param> |
2278 | + /// <param name="context">The context of the request.</param> |
2279 | + /// <returns>The request stream.</returns> |
2280 | + public Stream EndGetRequestStream(IAsyncResult asyncResult, out TransportContext context) |
2281 | + { |
2282 | + return _request.EndGetRequestStream(asyncResult, out context); |
2283 | + } |
2284 | + |
2285 | + /// <summary> |
2286 | + /// Ends an asynchronous request to an Internet resource. |
2287 | + /// </summary> |
2288 | + /// <param name="asyncResult">The async result from the asyn response.</param> |
2289 | + /// <returns>Teh response frm the internet resource.</returns> |
2290 | + public WebResponse EndGetResponse(IAsyncResult asyncResult) |
2291 | + { |
2292 | + return _request.EndGetResponse(asyncResult); |
2293 | + } |
2294 | + |
2295 | + /// <summary> |
2296 | + /// Gets a Stream object to use to write request data. |
2297 | + /// </summary> |
2298 | + /// <returns>Teh stream to which write the request.</returns> |
2299 | + public Stream GetRequestStream() |
2300 | + { |
2301 | + return _request.GetRequestStream(); |
2302 | + } |
2303 | + |
2304 | + /// <summary> |
2305 | + /// Returns a response from an Internet resource. |
2306 | + /// </summary> |
2307 | + /// <returns>Teh response from the resource.</returns> |
2308 | + public WebResponse GetResponse() |
2309 | + { |
2310 | + return _request.GetResponse(); |
2311 | + } |
2312 | + |
2313 | + #endregion |
2314 | + } |
2315 | +} |
2316 | |
2317 | === added file 'src/Canonical.UbuntuOne.Common/Net/HttpWebRequestFactory.cs' |
2318 | --- src/Canonical.UbuntuOne.Common/Net/HttpWebRequestFactory.cs 1970-01-01 00:00:00 +0000 |
2319 | +++ src/Canonical.UbuntuOne.Common/Net/HttpWebRequestFactory.cs 2010-10-05 09:58:35 +0000 |
2320 | @@ -0,0 +1,59 @@ |
2321 | +/* |
2322 | + * Copyright 2010 Canonical Ltd. |
2323 | + * |
2324 | + * This file is part of UbuntuOne on Windows. |
2325 | + * |
2326 | + * UbuntuOne on Windows is free software: you can redistribute it and/or modify |
2327 | + * it under the terms of the GNU Lesser General Public License version |
2328 | + * as published by the Free Software Foundation. |
2329 | + * |
2330 | + * Ubuntu One on Windows is distributed in the hope that it will be useful, |
2331 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2332 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2333 | + * GNU Lesser General Public License for more details. |
2334 | + * |
2335 | + * You should have received a copy of the GNU Lesser General Public License |
2336 | + * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>. |
2337 | + * |
2338 | + * Authors: Manuel de la Peña <manuel.delapena@canonical.com> |
2339 | + */ |
2340 | +using System; |
2341 | +using System.Net; |
2342 | +using RealHttpRequest = System.Net.HttpWebRequest; |
2343 | + |
2344 | +namespace Canonical.UbuntuOne.Common.Net |
2345 | +{ |
2346 | + /// <summary> |
2347 | + /// Class that creates IHttpWebRequest that can be used to request an internet resource. |
2348 | + /// </summary> |
2349 | + internal class HttpWebRequestFactory : IHttpWebRequestFactory |
2350 | + { |
2351 | + #region Implementation of IHttpWebRequestFactory |
2352 | + |
2353 | + /// <summary> |
2354 | + /// Creates a new webrequest that will be used to request an internet resource that is identified |
2355 | + /// by the given uri. |
2356 | + /// </summary> |
2357 | + /// <param name="uri">A string with the uri that identifies the internet resource.</param> |
2358 | + /// <returns>An IHttpWebRequest that can be used to request an internet resource.</returns> |
2359 | + public IHttpWebRequest Create(string uri) |
2360 | + { |
2361 | + var realRequest = WebRequest.Create(uri) as RealHttpRequest; |
2362 | + return new HttpWebRequest(realRequest); |
2363 | + } |
2364 | + |
2365 | + /// <summary> |
2366 | + /// Creates a webrequest that will be used to request an internet resource that is identified by |
2367 | + /// the given uri. |
2368 | + /// </summary> |
2369 | + /// <param name="uri">An object that identifies the web request.</param> |
2370 | + /// <returns>An HttpWebRequest that can be used to request an internet resource.</returns> |
2371 | + public IHttpWebRequest Create(Uri uri) |
2372 | + { |
2373 | + var realRequest = WebRequest.Create(uri) as RealHttpRequest; |
2374 | + return new HttpWebRequest(realRequest); |
2375 | + } |
2376 | + |
2377 | + #endregion |
2378 | + } |
2379 | +} |
2380 | |
2381 | === added file 'src/Canonical.UbuntuOne.Common/Net/IHttpWebRequest.cs' |
2382 | --- src/Canonical.UbuntuOne.Common/Net/IHttpWebRequest.cs 1970-01-01 00:00:00 +0000 |
2383 | +++ src/Canonical.UbuntuOne.Common/Net/IHttpWebRequest.cs 2010-10-05 09:58:35 +0000 |
2384 | @@ -0,0 +1,297 @@ |
2385 | +/* |
2386 | + * Copyright 2010 Canonical Ltd. |
2387 | + * |
2388 | + * This file is part of UbuntuOne on Windows. |
2389 | + * |
2390 | + * UbuntuOne on Windows is free software: you can redistribute it and/or modify |
2391 | + * it under the terms of the GNU Lesser General Public License version |
2392 | + * as published by the Free Software Foundation. |
2393 | + * |
2394 | + * Ubuntu One on Windows is distributed in the hope that it will be useful, |
2395 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2396 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2397 | + * GNU Lesser General Public License for more details. |
2398 | + * |
2399 | + * You should have received a copy of the GNU Lesser General Public License |
2400 | + * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>. |
2401 | + * |
2402 | + * Authors: Manuel de la Peña <manuel.delapena@canonical.com> |
2403 | + */ |
2404 | +using System; |
2405 | +using System.IO; |
2406 | +using System.Net; |
2407 | +using System.Net.Cache; |
2408 | +using System.Net.Security; |
2409 | +using System.Security.Cryptography.X509Certificates; |
2410 | +using System.Security.Principal; |
2411 | + |
2412 | +namespace Canonical.UbuntuOne.Common.Net |
2413 | +{ |
2414 | + /// <summary> |
2415 | + /// Helper interface that wrapps the HttpWebRequest class from System.Net |
2416 | + /// </summary> |
2417 | + public interface IHttpWebRequest |
2418 | + { |
2419 | + /// <summary> |
2420 | + /// Gets and sets value of the Accept HTTP header. The default value is null. |
2421 | + /// </summary> |
2422 | + string Accept { get; set; } |
2423 | + |
2424 | + /// <summary> |
2425 | + /// Gets and sets the uri that responds to the request. |
2426 | + /// </summary> |
2427 | + Uri Address { get; } |
2428 | + |
2429 | + /// <summary> |
2430 | + /// Gets and sets if the request should automatically follow redirection responses |
2431 | + /// </summary> |
2432 | + bool AllowAutoRedirect { get; set; } |
2433 | + |
2434 | + /// <summary> |
2435 | + /// Enables buffering of the data sent to the Internet resource |
2436 | + /// </summary> |
2437 | + bool AllowWriteStreamBuffering { get; set; } |
2438 | + |
2439 | + /// <summary> |
2440 | + /// Gets and sets the auhentication lavel used. |
2441 | + /// </summary> |
2442 | + AuthenticationLevel AuthenticationLevel { get; set; } |
2443 | + |
2444 | + /// <summary> |
2445 | + /// Gets and sets the type of decompression that is used. |
2446 | + /// </summary> |
2447 | + DecompressionMethods AutomaticDecompression { get; set; } |
2448 | + |
2449 | + /// <summary> |
2450 | + /// Gets or sets the cache policy used by the request. |
2451 | + /// </summary> |
2452 | + RequestCachePolicy CachePolicy { get; set; } |
2453 | + |
2454 | + /// <summary> |
2455 | + /// Gets and sets the certificates used by the request. |
2456 | + /// </summary> |
2457 | + X509CertificateCollection ClientCertificates { get; set; } |
2458 | + |
2459 | + /// <summary> |
2460 | + /// Gets and sets the Connection HTTP header |
2461 | + /// </summary> |
2462 | + string Connection { get; set; } |
2463 | + |
2464 | + /// <summary> |
2465 | + /// Gets and sets the name of the connection group for this request |
2466 | + /// </summary> |
2467 | + string ConnectionGroupName { get; set; } |
2468 | + |
2469 | + /// <summary> |
2470 | + /// Gets and sets the number of bytes of data to send to the Internet resource. |
2471 | + /// </summary> |
2472 | + long ContentLength { get; set; } |
2473 | + |
2474 | + /// <summary> |
2475 | + /// Gets and sets the content type of the request. |
2476 | + /// </summary> |
2477 | + string ContentType { get; set; } |
2478 | + |
2479 | + /// <summary> |
2480 | + /// Gets and sets the delegate that implements the callback method that |
2481 | + /// executes when an HTTP Continue response is returned from the Internet resource. |
2482 | + /// </summary> |
2483 | + HttpContinueDelegate ContinueDelegate { get; set; } |
2484 | + |
2485 | + /// <summary> |
2486 | + /// Gets and sets cookies container associated with this request. |
2487 | + /// </summary> |
2488 | + CookieContainer CookieContainer { get; set; } |
2489 | + |
2490 | + /// <summary> |
2491 | + /// Gets and sets the credentials used with the request. |
2492 | + /// </summary> |
2493 | + ICredentials Credentials { get; set; } |
2494 | + |
2495 | + /// <summary> |
2496 | + /// Gets and sets the data header of the request. |
2497 | + /// </summary> |
2498 | + DateTime Date { get; set; } |
2499 | + |
2500 | + /// <summary> |
2501 | + /// Gets and sets the Expect HTTP header. |
2502 | + /// </summary> |
2503 | + string Expect { get; set; } |
2504 | + |
2505 | + /// <summary> |
2506 | + /// Gets if a response has been received. |
2507 | + /// </summary> |
2508 | + bool HaveResponse { get; } |
2509 | + |
2510 | + /// <summary> |
2511 | + /// Gets and sets the headers of the request, |
2512 | + /// </summary> |
2513 | + WebHeaderCollection Headers { get; set; } |
2514 | + |
2515 | + /// <summary> |
2516 | + /// Gets and sets the Host header. |
2517 | + /// </summary> |
2518 | + string Host { get; set; } |
2519 | + |
2520 | + /// <summary> |
2521 | + /// A DateTime that contains the contents of the If-Modified-Since HTTP header. |
2522 | + /// </summary> |
2523 | + DateTime IfModifiedSince { get; set; } |
2524 | + |
2525 | + /// <summary> |
2526 | + /// Gets and sets the the impersonation level. |
2527 | + /// </summary> |
2528 | + TokenImpersonationLevel ImpersonationLevel { get; set; } |
2529 | + |
2530 | + /// <summary> |
2531 | + /// Gets and sets if the request should have a Connection HTTP header. |
2532 | + /// </summary> |
2533 | + bool KeepAlive { get; set; } |
2534 | + |
2535 | + /// <summary> |
2536 | + /// Gets and sets the max number of redirections. |
2537 | + /// </summary> |
2538 | + int MaximumAutomaticRedirections { get; set; } |
2539 | + |
2540 | + /// <summary> |
2541 | + /// Gets and sets The length, in kilobytes (1024 bytes), of the response headers. |
2542 | + /// </summary> |
2543 | + int MaximumResponseHeadersLength { get; set; } |
2544 | + |
2545 | + /// <summary> |
2546 | + /// The media type of the request. |
2547 | + /// </summary> |
2548 | + string MediaType { get; set; } |
2549 | + |
2550 | + /// <summary> |
2551 | + /// Gets and sets the request method. |
2552 | + /// </summary> |
2553 | + string Method { get; set; } |
2554 | + |
2555 | + /// <summary> |
2556 | + /// Gets and sets if the request should be pipelined |
2557 | + /// </summary> |
2558 | + bool Pipelined { get; set; } |
2559 | + |
2560 | + /// <summary> |
2561 | + /// Gets and sets if an HTTP Authorization header with requests after authentication has taken place; |
2562 | + /// </summary> |
2563 | + bool PreAuthenticate { get; set; } |
2564 | + |
2565 | + /// <summary> |
2566 | + /// Gets and sets the protol version used. |
2567 | + /// </summary> |
2568 | + Version ProtocolVersion { get; set; } |
2569 | + |
2570 | + /// <summary> |
2571 | + /// Gets and sets the proxy information. |
2572 | + /// </summary> |
2573 | + IWebProxy Proxy { get; set; } |
2574 | + |
2575 | + /// <summary> |
2576 | + /// Gets and sets the number of milliseconds before the writing or reading times out.. |
2577 | + /// </summary> |
2578 | + int ReadWriteTimeout { get; set; } |
2579 | + |
2580 | + /// <summary> |
2581 | + /// Gets and sets the Referer HTTP header. |
2582 | + /// </summary> |
2583 | + string Referer { get; set; } |
2584 | + |
2585 | + /// <summary> |
2586 | + /// Gets the resource uri used by the request. |
2587 | + /// </summary> |
2588 | + Uri RequestUri { get; } |
2589 | + |
2590 | + /// <summary> |
2591 | + /// Ges and sets if the request should be sent in chuckes. |
2592 | + /// </summary> |
2593 | + bool SendChunked { get; set; } |
2594 | + |
2595 | + /// <summary> |
2596 | + /// Gets the service point that represents the internet resource. |
2597 | + /// </summary> |
2598 | + ServicePoint ServicePoint { get; } |
2599 | + |
2600 | + /// <summary> |
2601 | + /// Gets and sets the number of milliseconds to wait before the request times out. |
2602 | + /// </summary> |
2603 | + int Timeout { get; set; } |
2604 | + |
2605 | + /// <summary> |
2606 | + /// Gets and sets the Transfer-encoding HTTP header. |
2607 | + /// </summary> |
2608 | + string TransferEncoding { get; set; } |
2609 | + |
2610 | + /// <summary> |
2611 | + /// Gets and sets if the authenticated connection is kept opened. |
2612 | + /// </summary> |
2613 | + bool UnsafeAuthenticatedConnectionSharing { get; set; } |
2614 | + |
2615 | + /// <summary> |
2616 | + /// Gets and sets if the default credentials are used. |
2617 | + /// </summary> |
2618 | + bool UseDefaultCredentials { get; set; } |
2619 | + |
2620 | + /// <summary> |
2621 | + /// Gets or sets the User-agent HTTP header; |
2622 | + /// </summary> |
2623 | + string UserAgent { get; set; } |
2624 | + |
2625 | + /// <summary> |
2626 | + /// Cancels a request to a resource |
2627 | + /// </summary> |
2628 | + void Abort(); |
2629 | + |
2630 | + /// <summary> |
2631 | + /// Begins an asynchronous request for a Stream object to use to write data. |
2632 | + /// </summary> |
2633 | + /// <param name="callback">The delegate to execute.</param> |
2634 | + /// <param name="state">Teh state object of the request. </param> |
2635 | + /// <returns>An async result.</returns> |
2636 | + IAsyncResult BeginGetRequestStream(AsyncCallback callback,Object state); |
2637 | + |
2638 | + /// <summary> |
2639 | + /// Begins an asynchronous request to an Internet resource. |
2640 | + /// </summary> |
2641 | + /// <param name="callback">Teh deleaget.</param> |
2642 | + /// <param name="state">Teh state object fo the response.</param> |
2643 | + /// <returns>an asyn result.</returns> |
2644 | + IAsyncResult BeginGetResponse(AsyncCallback callback,Object state); |
2645 | + |
2646 | + /// <summary> |
2647 | + /// Ends an asynchronous request for a Stream object to use to write data. |
2648 | + /// </summary> |
2649 | + /// <param name="asyncResult">The result from the async request.</param> |
2650 | + /// <returns>Teh stream from teh request.</returns> |
2651 | + Stream EndGetRequestStream(IAsyncResult asyncResult); |
2652 | + |
2653 | + /// <summary> |
2654 | + /// Ends an asynchronous request for a Stream object to use to write data and outputs |
2655 | + /// the TransportContext associated with the stream. |
2656 | + /// </summary> |
2657 | + /// <param name="asyncResult">The async result from the request stream.</param> |
2658 | + /// <param name="context">The context of the request.</param> |
2659 | + /// <returns>The request stream.</returns> |
2660 | + Stream EndGetRequestStream(IAsyncResult asyncResult,out TransportContext context); |
2661 | + |
2662 | + /// <summary> |
2663 | + /// Ends an asynchronous request to an Internet resource. |
2664 | + /// </summary> |
2665 | + /// <param name="asyncResult">The async result from the asyn response.</param> |
2666 | + /// <returns>Teh response frm the internet resource.</returns> |
2667 | + WebResponse EndGetResponse(IAsyncResult asyncResult); |
2668 | + |
2669 | + /// <summary> |
2670 | + /// Gets a Stream object to use to write request data. |
2671 | + /// </summary> |
2672 | + /// <returns>Teh stream to which write the request.</returns> |
2673 | + Stream GetRequestStream(); |
2674 | + |
2675 | + /// <summary> |
2676 | + /// Returns a response from an Internet resource. |
2677 | + /// </summary> |
2678 | + /// <returns>Teh response from the resource.</returns> |
2679 | + WebResponse GetResponse(); |
2680 | + } |
2681 | +} |
2682 | |
2683 | === added file 'src/Canonical.UbuntuOne.Common/Net/IHttpWebRequestFactory.cs' |
2684 | --- src/Canonical.UbuntuOne.Common/Net/IHttpWebRequestFactory.cs 1970-01-01 00:00:00 +0000 |
2685 | +++ src/Canonical.UbuntuOne.Common/Net/IHttpWebRequestFactory.cs 2010-10-05 09:58:35 +0000 |
2686 | @@ -0,0 +1,45 @@ |
2687 | +/* |
2688 | + * Copyright 2010 Canonical Ltd. |
2689 | + * |
2690 | + * This file is part of UbuntuOne on Windows. |
2691 | + * |
2692 | + * UbuntuOne on Windows is free software: you can redistribute it and/or modify |
2693 | + * it under the terms of the GNU Lesser General Public License version |
2694 | + * as published by the Free Software Foundation. |
2695 | + * |
2696 | + * Ubuntu One on Windows is distributed in the hope that it will be useful, |
2697 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2698 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2699 | + * GNU Lesser General Public License for more details. |
2700 | + * |
2701 | + * You should have received a copy of the GNU Lesser General Public License |
2702 | + * along with UbuntuOne for Windows. If not, see <http://www.gnu.org/licenses/>. |
2703 | + * |
2704 | + * Authors: Manuel de la Peña <manuel.delapena@canonical.com> |
2705 | + */ |
2706 | +using System; |
2707 | + |
2708 | +namespace Canonical.UbuntuOne.Common.Net |
2709 | +{ |
2710 | + /// <summary> |
2711 | + /// Simple interface to be implemented by those objects that are able to create web requests. |
2712 | + /// </summary> |
2713 | + public interface IHttpWebRequestFactory |
2714 | + { |
2715 | + /// <summary> |
2716 | + /// Creates a new webrequest that will be used to request an internet resource that is identified |
2717 | + /// by the given uri. |
2718 | + /// </summary> |
2719 | + /// <param name="uri">A string with the uri that identifies the internet resource.</param> |
2720 | + /// <returns>An IHttpWebRequest that can be used to request an internet resource.</returns> |
2721 | + IHttpWebRequest Create(string uri); |
2722 | + |
2723 | + /// <summary> |
2724 | + /// Creates a webrequest that will be used to request an internet resource that is identified by |
2725 | + /// the given uri. |
2726 | + /// </summary> |
2727 | + /// <param name="uri">An object that identifies the web request.</param> |
2728 | + /// <returns>An HttpWebRequest that can be used to request an internet resource.</returns> |
2729 | + IHttpWebRequest Create(Uri uri); |
2730 | + } |
2731 | +} |