google-authsub 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. data/.gitignore +1 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README +98 -0
  4. data/Rakefile +19 -0
  5. data/VERSION +1 -0
  6. data/coverage/-Library-Ruby-Gems-1_8-gems-FakeWeb-1_1_2-lib-fake_net_http_rb.html +679 -0
  7. data/coverage/-Library-Ruby-Gems-1_8-gems-FakeWeb-1_1_2-lib-fake_web_rb.html +843 -0
  8. data/coverage/-Library-Ruby-Gems-1_8-gems-rcov-0_8_1_2_0-lib-rcov_rb.html +1598 -0
  9. data/coverage/index.html +360 -0
  10. data/coverage/lib-googleauthsub_rb.html +877 -0
  11. data/coverage/spec-googleauthsub_spec_rb.html +950 -0
  12. data/coverage/spec-spec_helper_rb.html +640 -0
  13. data/doc/classes/AuthEchoServlet.html +152 -0
  14. data/doc/classes/AuthEchoServlet.src/M000001.html +20 -0
  15. data/doc/classes/AuthEchoServlet.src/M000002.html +18 -0
  16. data/doc/classes/GData/AuthSubError.html +139 -0
  17. data/doc/classes/GData/AuthSubError.src/M000019.html +18 -0
  18. data/doc/classes/GData/Error.html +111 -0
  19. data/doc/classes/GData/GoogleAuthSub.html +521 -0
  20. data/doc/classes/GData/GoogleAuthSub.src/M000001.html +29 -0
  21. data/doc/classes/GData/GoogleAuthSub.src/M000002.html +22 -0
  22. data/doc/classes/GData/GoogleAuthSub.src/M000003.html +29 -0
  23. data/doc/classes/GData/GoogleAuthSub.src/M000004.html +22 -0
  24. data/doc/classes/GData/GoogleAuthSub.src/M000005.html +24 -0
  25. data/doc/classes/GData/GoogleAuthSub.src/M000006.html +19 -0
  26. data/doc/classes/GData/GoogleAuthSub.src/M000007.html +18 -0
  27. data/doc/classes/GData/GoogleAuthSub.src/M000008.html +18 -0
  28. data/doc/classes/GData/GoogleAuthSub.src/M000009.html +24 -0
  29. data/doc/classes/GData/GoogleAuthSub.src/M000010.html +25 -0
  30. data/doc/classes/GData/GoogleAuthSub.src/M000011.html +30 -0
  31. data/doc/classes/GData/GoogleAuthSub.src/M000012.html +18 -0
  32. data/doc/classes/GData/GoogleAuthSub.src/M000013.html +18 -0
  33. data/doc/classes/GData/GoogleAuthSub.src/M000014.html +18 -0
  34. data/doc/classes/GData/GoogleAuthSub.src/M000015.html +18 -0
  35. data/doc/classes/GData/GoogleAuthSub.src/M000016.html +20 -0
  36. data/doc/classes/GData/GoogleAuthSub.src/M000017.html +20 -0
  37. data/doc/classes/GData/GoogleAuthSub.src/M000018.html +19 -0
  38. data/doc/classes/GData.html +162 -0
  39. data/doc/created.rid +1 -0
  40. data/doc/files/googleauthsub_rb.html +140 -0
  41. data/doc/files/lib/googleauthsub_rb.html +140 -0
  42. data/doc/files/spec/googleauthsub_spec_rb.html +146 -0
  43. data/doc/files/spec/googleresponder_rb.html +121 -0
  44. data/doc/files/spec/spec_helper_rb.html +149 -0
  45. data/doc/fr_class_index.html +31 -0
  46. data/doc/fr_file_index.html +30 -0
  47. data/doc/fr_method_index.html +45 -0
  48. data/doc/index.html +24 -0
  49. data/doc/rdoc-style.css +208 -0
  50. data/google-authsub-0.0.2.gem +0 -0
  51. data/google-authsub-0.0.3.gem +0 -0
  52. data/google-authsub.gemspec +109 -0
  53. data/lib/googleauthsub.rb +271 -0
  54. data/live test/authsub_test.html +40 -0
  55. data/live test/gastest.rb +90 -0
  56. data/spec/googleauthsub_spec.rb +350 -0
  57. data/spec/googleresponder.rb +26 -0
  58. data/spec/mock responses/bad_token_info.txt +11 -0
  59. data/spec/mock responses/calendar.txt +11 -0
  60. data/spec/mock responses/revoke_token.txt +7 -0
  61. data/spec/mock responses/revoked_token.txt +17 -0
  62. data/spec/mock responses/session_token.txt +9 -0
  63. data/spec/mock responses/token_info.txt +11 -0
  64. data/spec/mock responses/unauthorized.txt +18 -0
  65. data/spec/mock_certs/test_private_key.pem +15 -0
  66. data/spec/mock_certs/test_public_key.pem +6 -0
  67. data/spec/spec_helper.rb +30 -0
  68. data/spec/spec_opts +7 -0
  69. metadata +125 -0
@@ -0,0 +1,360 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+ <html lang='en' xml:lang='en' xmlns='http://www.w3.org/1999/xhtml'><head><title>C0 code coverage information</title>
3
+ <style type='text/css'>body { background-color: rgb(240, 240, 245); }</style>
4
+ <style type='text/css'>span.cross-ref-title {
5
+ font-size: 140%;
6
+ }
7
+ span.cross-ref a {
8
+ text-decoration: none;
9
+ }
10
+ span.cross-ref {
11
+ background-color:#f3f7fa;
12
+ border: 1px dashed #333;
13
+ margin: 1em;
14
+ padding: 0.5em;
15
+ overflow: hidden;
16
+ }
17
+ a.crossref-toggle {
18
+ text-decoration: none;
19
+ }
20
+ span.marked0 {
21
+ background-color: rgb(185, 210, 200);
22
+ display: block;
23
+ }
24
+ span.marked1 {
25
+ background-color: rgb(190, 215, 205);
26
+ display: block;
27
+ }
28
+ span.inferred0 {
29
+ background-color: rgb(175, 200, 200);
30
+ display: block;
31
+ }
32
+ span.inferred1 {
33
+ background-color: rgb(180, 205, 205);
34
+ display: block;
35
+ }
36
+ span.uncovered0 {
37
+ background-color: rgb(225, 110, 110);
38
+ display: block;
39
+ }
40
+ span.uncovered1 {
41
+ background-color: rgb(235, 120, 120);
42
+ display: block;
43
+ }
44
+ span.overview {
45
+ border-bottom: 8px solid black;
46
+ }
47
+ div.overview {
48
+ border-bottom: 8px solid black;
49
+ }
50
+ body {
51
+ font-family: verdana, arial, helvetica;
52
+ }
53
+ div.footer {
54
+ font-size: 68%;
55
+ margin-top: 1.5em;
56
+ }
57
+ h1, h2, h3, h4, h5, h6 {
58
+ margin-bottom: 0.5em;
59
+ }
60
+ h5 {
61
+ margin-top: 0.5em;
62
+ }
63
+ .hidden {
64
+ display: none;
65
+ }
66
+ div.separator {
67
+ height: 10px;
68
+ }
69
+ /* Commented out for better readability, esp. on IE */
70
+ /*
71
+ table tr td, table tr th {
72
+ font-size: 68%;
73
+ }
74
+ td.value table tr td {
75
+ font-size: 11px;
76
+ }
77
+ */
78
+ table.percent_graph {
79
+ height: 12px;
80
+ border: #808080 1px solid;
81
+ empty-cells: show;
82
+ }
83
+ table.percent_graph td.covered {
84
+ height: 10px;
85
+ background: #00f000;
86
+ }
87
+ table.percent_graph td.uncovered {
88
+ height: 10px;
89
+ background: #e00000;
90
+ }
91
+ table.percent_graph td.NA {
92
+ height: 10px;
93
+ background: #eaeaea;
94
+ }
95
+ table.report {
96
+ border-collapse: collapse;
97
+ width: 100%;
98
+ }
99
+ table.report td.heading {
100
+ background: #dcecff;
101
+ border: #d0d0d0 1px solid;
102
+ font-weight: bold;
103
+ text-align: center;
104
+ }
105
+ table.report td.heading:hover {
106
+ background: #c0ffc0;
107
+ }
108
+ table.report td.text {
109
+ border: #d0d0d0 1px solid;
110
+ }
111
+ table.report td.value,
112
+ table.report td.lines_total,
113
+ table.report td.lines_code {
114
+ text-align: right;
115
+ border: #d0d0d0 1px solid;
116
+ }
117
+ table.report tr.light {
118
+ background-color: rgb(240, 240, 245);
119
+ }
120
+ table.report tr.dark {
121
+ background-color: rgb(230, 230, 235);
122
+ }
123
+ </style>
124
+ <script type='text/javascript'>
125
+ // <![CDATA[
126
+ function toggleCode( id ) {
127
+ if ( document.getElementById )
128
+ elem = document.getElementById( id );
129
+ else if ( document.all )
130
+ elem = eval( "document.all." + id );
131
+ else
132
+ return false;
133
+
134
+ elemStyle = elem.style;
135
+
136
+ if ( elemStyle.display != "block" ) {
137
+ elemStyle.display = "block"
138
+ } else {
139
+ elemStyle.display = "none"
140
+ }
141
+
142
+ return true;
143
+ }
144
+
145
+ // Make cross-references hidden by default
146
+ document.writeln( "<style type=\"text/css\">span.cross-ref { display: none }</style>" )
147
+ // ]]>
148
+ </script>
149
+ </head>
150
+ <body><h3>C0 code coverage information</h3>
151
+ <p>Generated on Sat Jun 07 16:45:05 +1000 2008 with <a href='http://eigenclass.org/hiki/rcov'>rcov 0.8.1.2</a>
152
+ </p>
153
+ <hr/>
154
+ <table class='report'><thead><tr><td class='heading'>Name</td>
155
+ <td class='heading'>Total lines</td>
156
+ <td class='heading'>Lines of code</td>
157
+ <td class='heading'>Total coverage</td>
158
+ <td class='heading'>Code coverage</td>
159
+ </tr>
160
+ </thead>
161
+ <tbody><tr class='light'><td>TOTAL</td>
162
+ <td class='lines_total'><tt>1927</tt>
163
+ </td>
164
+ <td class='lines_code'><tt>1201</tt>
165
+ </td>
166
+ <td><table cellspacing='0' cellpadding='0' align='right'><tr><td><tt class='coverage_total'>21.2%</tt>
167
+ &nbsp;</td>
168
+ <td><table cellspacing='0' class='percent_graph' cellpadding='0' width='100'><tr><td class='covered' width='21'/>
169
+ <td class='uncovered' width='79'/>
170
+ </tr>
171
+ </table>
172
+ </td>
173
+ </tr>
174
+ </table>
175
+ </td>
176
+ <td><table cellspacing='0' cellpadding='0' align='right'><tr><td><tt class='coverage_code'>11.0%</tt>
177
+ &nbsp;</td>
178
+ <td><table cellspacing='0' class='percent_graph' cellpadding='0' width='100'><tr><td class='covered' width='11'/>
179
+ <td class='uncovered' width='89'/>
180
+ </tr>
181
+ </table>
182
+ </td>
183
+ </tr>
184
+ </table>
185
+ </td>
186
+ </tr>
187
+ <tr class='dark'><td><a href='-Library-Ruby-Gems-1_8-gems-FakeWeb-1_1_2-lib-fake_net_http_rb.html'>/Library/Ruby/Gems/1.8/gems/FakeWeb-1.1.2/lib/fake_net_http.rb</a>
188
+ </td>
189
+ <td class='lines_total'><tt>69</tt>
190
+ </td>
191
+ <td class='lines_code'><tt>43</tt>
192
+ </td>
193
+ <td><table cellspacing='0' cellpadding='0' align='right'><tr><td><tt class='coverage_total'>62.3%</tt>
194
+ &nbsp;</td>
195
+ <td><table cellspacing='0' class='percent_graph' cellpadding='0' width='100'><tr><td class='covered' width='62'/>
196
+ <td class='uncovered' width='38'/>
197
+ </tr>
198
+ </table>
199
+ </td>
200
+ </tr>
201
+ </table>
202
+ </td>
203
+ <td><table cellspacing='0' cellpadding='0' align='right'><tr><td><tt class='coverage_code'>39.5%</tt>
204
+ &nbsp;</td>
205
+ <td><table cellspacing='0' class='percent_graph' cellpadding='0' width='100'><tr><td class='covered' width='40'/>
206
+ <td class='uncovered' width='60'/>
207
+ </tr>
208
+ </table>
209
+ </td>
210
+ </tr>
211
+ </table>
212
+ </td>
213
+ </tr>
214
+ <tr class='light'><td><a href='-Library-Ruby-Gems-1_8-gems-FakeWeb-1_1_2-lib-fake_web_rb.html'>/Library/Ruby/Gems/1.8/gems/FakeWeb-1.1.2/lib/fake_web.rb</a>
215
+ </td>
216
+ <td class='lines_total'><tt>233</tt>
217
+ </td>
218
+ <td class='lines_code'><tt>129</tt>
219
+ </td>
220
+ <td><table cellspacing='0' cellpadding='0' align='right'><tr><td><tt class='coverage_total'>61.4%</tt>
221
+ &nbsp;</td>
222
+ <td><table cellspacing='0' class='percent_graph' cellpadding='0' width='100'><tr><td class='covered' width='61'/>
223
+ <td class='uncovered' width='39'/>
224
+ </tr>
225
+ </table>
226
+ </td>
227
+ </tr>
228
+ </table>
229
+ </td>
230
+ <td><table cellspacing='0' cellpadding='0' align='right'><tr><td><tt class='coverage_code'>33.3%</tt>
231
+ &nbsp;</td>
232
+ <td><table cellspacing='0' class='percent_graph' cellpadding='0' width='100'><tr><td class='covered' width='33'/>
233
+ <td class='uncovered' width='67'/>
234
+ </tr>
235
+ </table>
236
+ </td>
237
+ </tr>
238
+ </table>
239
+ </td>
240
+ </tr>
241
+ <tr class='dark'><td><a href='-Library-Ruby-Gems-1_8-gems-rcov-0_8_1_2_0-lib-rcov_rb.html'>/Library/Ruby/Gems/1.8/gems/rcov-0.8.1.2.0/lib/rcov.rb</a>
242
+ </td>
243
+ <td class='lines_total'><tt>988</tt>
244
+ </td>
245
+ <td class='lines_code'><tt>602</tt>
246
+ </td>
247
+ <td><table cellspacing='0' cellpadding='0' align='right'><tr><td><tt class='coverage_total'>3.3%</tt>
248
+ &nbsp;</td>
249
+ <td><table cellspacing='0' class='percent_graph' cellpadding='0' width='100'><tr><td class='covered' width='3'/>
250
+ <td class='uncovered' width='97'/>
251
+ </tr>
252
+ </table>
253
+ </td>
254
+ </tr>
255
+ </table>
256
+ </td>
257
+ <td><table cellspacing='0' cellpadding='0' align='right'><tr><td><tt class='coverage_code'>2.8%</tt>
258
+ &nbsp;</td>
259
+ <td><table cellspacing='0' class='percent_graph' cellpadding='0' width='100'><tr><td class='covered' width='3'/>
260
+ <td class='uncovered' width='97'/>
261
+ </tr>
262
+ </table>
263
+ </td>
264
+ </tr>
265
+ </table>
266
+ </td>
267
+ </tr>
268
+ <tr class='light'><td><a href='lib-googleauthsub_rb.html'>lib/googleauthsub.rb</a>
269
+ </td>
270
+ <td class='lines_total'><tt>267</tt>
271
+ </td>
272
+ <td class='lines_code'><tt>157</tt>
273
+ </td>
274
+ <td><table cellspacing='0' cellpadding='0' align='right'><tr><td><tt class='coverage_total'>50.6%</tt>
275
+ &nbsp;</td>
276
+ <td><table cellspacing='0' class='percent_graph' cellpadding='0' width='100'><tr><td class='covered' width='51'/>
277
+ <td class='uncovered' width='49'/>
278
+ </tr>
279
+ </table>
280
+ </td>
281
+ </tr>
282
+ </table>
283
+ </td>
284
+ <td><table cellspacing='0' cellpadding='0' align='right'><tr><td><tt class='coverage_code'>21.7%</tt>
285
+ &nbsp;</td>
286
+ <td><table cellspacing='0' class='percent_graph' cellpadding='0' width='100'><tr><td class='covered' width='22'/>
287
+ <td class='uncovered' width='78'/>
288
+ </tr>
289
+ </table>
290
+ </td>
291
+ </tr>
292
+ </table>
293
+ </td>
294
+ </tr>
295
+ <tr class='dark'><td><a href='spec-googleauthsub_spec_rb.html'>spec/googleauthsub_spec.rb</a>
296
+ </td>
297
+ <td class='lines_total'><tt>340</tt>
298
+ </td>
299
+ <td class='lines_code'><tt>248</tt>
300
+ </td>
301
+ <td><table cellspacing='0' cellpadding='0' align='right'><tr><td><tt class='coverage_total'>9.1%</tt>
302
+ &nbsp;</td>
303
+ <td><table cellspacing='0' class='percent_graph' cellpadding='0' width='100'><tr><td class='covered' width='9'/>
304
+ <td class='uncovered' width='91'/>
305
+ </tr>
306
+ </table>
307
+ </td>
308
+ </tr>
309
+ </table>
310
+ </td>
311
+ <td><table cellspacing='0' cellpadding='0' align='right'><tr><td><tt class='coverage_code'>2.4%</tt>
312
+ &nbsp;</td>
313
+ <td><table cellspacing='0' class='percent_graph' cellpadding='0' width='100'><tr><td class='covered' width='2'/>
314
+ <td class='uncovered' width='98'/>
315
+ </tr>
316
+ </table>
317
+ </td>
318
+ </tr>
319
+ </table>
320
+ </td>
321
+ </tr>
322
+ <tr class='light'><td><a href='spec-spec_helper_rb.html'>spec/spec_helper.rb</a>
323
+ </td>
324
+ <td class='lines_total'><tt>30</tt>
325
+ </td>
326
+ <td class='lines_code'><tt>22</tt>
327
+ </td>
328
+ <td><table cellspacing='0' cellpadding='0' align='right'><tr><td><tt class='coverage_total'>76.7%</tt>
329
+ &nbsp;</td>
330
+ <td><table cellspacing='0' class='percent_graph' cellpadding='0' width='100'><tr><td class='covered' width='77'/>
331
+ <td class='uncovered' width='23'/>
332
+ </tr>
333
+ </table>
334
+ </td>
335
+ </tr>
336
+ </table>
337
+ </td>
338
+ <td><table cellspacing='0' cellpadding='0' align='right'><tr><td><tt class='coverage_code'>68.2%</tt>
339
+ &nbsp;</td>
340
+ <td><table cellspacing='0' class='percent_graph' cellpadding='0' width='100'><tr><td class='covered' width='68'/>
341
+ <td class='uncovered' width='32'/>
342
+ </tr>
343
+ </table>
344
+ </td>
345
+ </tr>
346
+ </table>
347
+ </td>
348
+ </tr>
349
+ </tbody>
350
+ </table>
351
+ <hr/>
352
+ <p>Generated using the <a href='http://eigenclass.org/hiki.rb?rcov'>rcov code coverage analysis tool for Ruby</a>
353
+ version 0.8.1.2.</p>
354
+ <p><a href='http://validator.w3.org/check/referer'><img src='http://www.w3.org/Icons/valid-xhtml11' height='31' alt='Valid XHTML 1.1!' width='88'/>
355
+ </a>
356
+ <a href='http://jigsaw.w3.org/css-validator/check/referer'><img src='http://jigsaw.w3.org/css-validator/images/vcss' alt='Valid CSS!' style='border:0;width:88px;height:31px'/>
357
+ </a>
358
+ </p>
359
+ </body>
360
+ </html>
@@ -0,0 +1,877 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+ <html lang='en' xml:lang='en' xmlns='http://www.w3.org/1999/xhtml'><head><title>lib/googleauthsub.rb - C0 code coverage information</title>
3
+ <style type='text/css'>body { background-color: rgb(240, 240, 245); }</style>
4
+ <style type='text/css'>span.cross-ref-title {
5
+ font-size: 140%;
6
+ }
7
+ span.cross-ref a {
8
+ text-decoration: none;
9
+ }
10
+ span.cross-ref {
11
+ background-color:#f3f7fa;
12
+ border: 1px dashed #333;
13
+ margin: 1em;
14
+ padding: 0.5em;
15
+ overflow: hidden;
16
+ }
17
+ a.crossref-toggle {
18
+ text-decoration: none;
19
+ }
20
+ span.marked0 {
21
+ background-color: rgb(185, 210, 200);
22
+ display: block;
23
+ }
24
+ span.marked1 {
25
+ background-color: rgb(190, 215, 205);
26
+ display: block;
27
+ }
28
+ span.inferred0 {
29
+ background-color: rgb(175, 200, 200);
30
+ display: block;
31
+ }
32
+ span.inferred1 {
33
+ background-color: rgb(180, 205, 205);
34
+ display: block;
35
+ }
36
+ span.uncovered0 {
37
+ background-color: rgb(225, 110, 110);
38
+ display: block;
39
+ }
40
+ span.uncovered1 {
41
+ background-color: rgb(235, 120, 120);
42
+ display: block;
43
+ }
44
+ span.overview {
45
+ border-bottom: 8px solid black;
46
+ }
47
+ div.overview {
48
+ border-bottom: 8px solid black;
49
+ }
50
+ body {
51
+ font-family: verdana, arial, helvetica;
52
+ }
53
+ div.footer {
54
+ font-size: 68%;
55
+ margin-top: 1.5em;
56
+ }
57
+ h1, h2, h3, h4, h5, h6 {
58
+ margin-bottom: 0.5em;
59
+ }
60
+ h5 {
61
+ margin-top: 0.5em;
62
+ }
63
+ .hidden {
64
+ display: none;
65
+ }
66
+ div.separator {
67
+ height: 10px;
68
+ }
69
+ /* Commented out for better readability, esp. on IE */
70
+ /*
71
+ table tr td, table tr th {
72
+ font-size: 68%;
73
+ }
74
+ td.value table tr td {
75
+ font-size: 11px;
76
+ }
77
+ */
78
+ table.percent_graph {
79
+ height: 12px;
80
+ border: #808080 1px solid;
81
+ empty-cells: show;
82
+ }
83
+ table.percent_graph td.covered {
84
+ height: 10px;
85
+ background: #00f000;
86
+ }
87
+ table.percent_graph td.uncovered {
88
+ height: 10px;
89
+ background: #e00000;
90
+ }
91
+ table.percent_graph td.NA {
92
+ height: 10px;
93
+ background: #eaeaea;
94
+ }
95
+ table.report {
96
+ border-collapse: collapse;
97
+ width: 100%;
98
+ }
99
+ table.report td.heading {
100
+ background: #dcecff;
101
+ border: #d0d0d0 1px solid;
102
+ font-weight: bold;
103
+ text-align: center;
104
+ }
105
+ table.report td.heading:hover {
106
+ background: #c0ffc0;
107
+ }
108
+ table.report td.text {
109
+ border: #d0d0d0 1px solid;
110
+ }
111
+ table.report td.value,
112
+ table.report td.lines_total,
113
+ table.report td.lines_code {
114
+ text-align: right;
115
+ border: #d0d0d0 1px solid;
116
+ }
117
+ table.report tr.light {
118
+ background-color: rgb(240, 240, 245);
119
+ }
120
+ table.report tr.dark {
121
+ background-color: rgb(230, 230, 235);
122
+ }
123
+ </style>
124
+ <script type='text/javascript'>
125
+ // <![CDATA[
126
+ function toggleCode( id ) {
127
+ if ( document.getElementById )
128
+ elem = document.getElementById( id );
129
+ else if ( document.all )
130
+ elem = eval( "document.all." + id );
131
+ else
132
+ return false;
133
+
134
+ elemStyle = elem.style;
135
+
136
+ if ( elemStyle.display != "block" ) {
137
+ elemStyle.display = "block"
138
+ } else {
139
+ elemStyle.display = "none"
140
+ }
141
+
142
+ return true;
143
+ }
144
+
145
+ // Make cross-references hidden by default
146
+ document.writeln( "<style type=\"text/css\">span.cross-ref { display: none }</style>" )
147
+ // ]]>
148
+ </script>
149
+ <style type='text/css'>span.run0 {
150
+ background-color: rgb(178, 204, 255);
151
+ display: block;
152
+ }
153
+ span.run1 {
154
+ background-color: rgb(178, 206, 255);
155
+ display: block;
156
+ }
157
+ span.run2 {
158
+ background-color: rgb(178, 209, 255);
159
+ display: block;
160
+ }
161
+ span.run3 {
162
+ background-color: rgb(178, 211, 255);
163
+ display: block;
164
+ }
165
+ span.run4 {
166
+ background-color: rgb(178, 214, 255);
167
+ display: block;
168
+ }
169
+ span.run5 {
170
+ background-color: rgb(178, 218, 255);
171
+ display: block;
172
+ }
173
+ span.run6 {
174
+ background-color: rgb(178, 220, 255);
175
+ display: block;
176
+ }
177
+ span.run7 {
178
+ background-color: rgb(178, 223, 255);
179
+ display: block;
180
+ }
181
+ span.run8 {
182
+ background-color: rgb(178, 225, 255);
183
+ display: block;
184
+ }
185
+ span.run9 {
186
+ background-color: rgb(178, 228, 255);
187
+ display: block;
188
+ }
189
+ span.run10 {
190
+ background-color: rgb(178, 232, 255);
191
+ display: block;
192
+ }
193
+ span.run11 {
194
+ background-color: rgb(178, 234, 255);
195
+ display: block;
196
+ }
197
+ span.run12 {
198
+ background-color: rgb(178, 237, 255);
199
+ display: block;
200
+ }
201
+ span.run13 {
202
+ background-color: rgb(178, 239, 255);
203
+ display: block;
204
+ }
205
+ span.run14 {
206
+ background-color: rgb(178, 242, 255);
207
+ display: block;
208
+ }
209
+ span.run15 {
210
+ background-color: rgb(178, 246, 255);
211
+ display: block;
212
+ }
213
+ span.run16 {
214
+ background-color: rgb(178, 248, 255);
215
+ display: block;
216
+ }
217
+ span.run17 {
218
+ background-color: rgb(178, 251, 255);
219
+ display: block;
220
+ }
221
+ span.run18 {
222
+ background-color: rgb(178, 253, 255);
223
+ display: block;
224
+ }
225
+ span.run19 {
226
+ background-color: rgb(178, 255, 253);
227
+ display: block;
228
+ }
229
+ span.run20 {
230
+ background-color: rgb(178, 255, 249);
231
+ display: block;
232
+ }
233
+ span.run21 {
234
+ background-color: rgb(178, 255, 247);
235
+ display: block;
236
+ }
237
+ span.run22 {
238
+ background-color: rgb(178, 255, 244);
239
+ display: block;
240
+ }
241
+ span.run23 {
242
+ background-color: rgb(178, 255, 242);
243
+ display: block;
244
+ }
245
+ span.run24 {
246
+ background-color: rgb(178, 255, 239);
247
+ display: block;
248
+ }
249
+ span.run25 {
250
+ background-color: rgb(178, 255, 235);
251
+ display: block;
252
+ }
253
+ span.run26 {
254
+ background-color: rgb(178, 255, 233);
255
+ display: block;
256
+ }
257
+ span.run27 {
258
+ background-color: rgb(178, 255, 230);
259
+ display: block;
260
+ }
261
+ span.run28 {
262
+ background-color: rgb(178, 255, 228);
263
+ display: block;
264
+ }
265
+ span.run29 {
266
+ background-color: rgb(178, 255, 225);
267
+ display: block;
268
+ }
269
+ span.run30 {
270
+ background-color: rgb(178, 255, 221);
271
+ display: block;
272
+ }
273
+ span.run31 {
274
+ background-color: rgb(178, 255, 219);
275
+ display: block;
276
+ }
277
+ span.run32 {
278
+ background-color: rgb(178, 255, 216);
279
+ display: block;
280
+ }
281
+ span.run33 {
282
+ background-color: rgb(178, 255, 214);
283
+ display: block;
284
+ }
285
+ span.run34 {
286
+ background-color: rgb(178, 255, 211);
287
+ display: block;
288
+ }
289
+ span.run35 {
290
+ background-color: rgb(178, 255, 207);
291
+ display: block;
292
+ }
293
+ span.run36 {
294
+ background-color: rgb(178, 255, 205);
295
+ display: block;
296
+ }
297
+ span.run37 {
298
+ background-color: rgb(178, 255, 202);
299
+ display: block;
300
+ }
301
+ span.run38 {
302
+ background-color: rgb(178, 255, 200);
303
+ display: block;
304
+ }
305
+ span.run39 {
306
+ background-color: rgb(178, 255, 197);
307
+ display: block;
308
+ }
309
+ span.run40 {
310
+ background-color: rgb(178, 255, 193);
311
+ display: block;
312
+ }
313
+ span.run41 {
314
+ background-color: rgb(178, 255, 191);
315
+ display: block;
316
+ }
317
+ span.run42 {
318
+ background-color: rgb(178, 255, 188);
319
+ display: block;
320
+ }
321
+ span.run43 {
322
+ background-color: rgb(178, 255, 186);
323
+ display: block;
324
+ }
325
+ span.run44 {
326
+ background-color: rgb(178, 255, 183);
327
+ display: block;
328
+ }
329
+ span.run45 {
330
+ background-color: rgb(178, 255, 179);
331
+ display: block;
332
+ }
333
+ span.run46 {
334
+ background-color: rgb(179, 255, 178);
335
+ display: block;
336
+ }
337
+ span.run47 {
338
+ background-color: rgb(182, 255, 178);
339
+ display: block;
340
+ }
341
+ span.run48 {
342
+ background-color: rgb(184, 255, 178);
343
+ display: block;
344
+ }
345
+ span.run49 {
346
+ background-color: rgb(187, 255, 178);
347
+ display: block;
348
+ }
349
+ span.run50 {
350
+ background-color: rgb(191, 255, 178);
351
+ display: block;
352
+ }
353
+ span.run51 {
354
+ background-color: rgb(193, 255, 178);
355
+ display: block;
356
+ }
357
+ span.run52 {
358
+ background-color: rgb(196, 255, 178);
359
+ display: block;
360
+ }
361
+ span.run53 {
362
+ background-color: rgb(198, 255, 178);
363
+ display: block;
364
+ }
365
+ span.run54 {
366
+ background-color: rgb(201, 255, 178);
367
+ display: block;
368
+ }
369
+ span.run55 {
370
+ background-color: rgb(205, 255, 178);
371
+ display: block;
372
+ }
373
+ span.run56 {
374
+ background-color: rgb(207, 255, 178);
375
+ display: block;
376
+ }
377
+ span.run57 {
378
+ background-color: rgb(210, 255, 178);
379
+ display: block;
380
+ }
381
+ span.run58 {
382
+ background-color: rgb(212, 255, 178);
383
+ display: block;
384
+ }
385
+ span.run59 {
386
+ background-color: rgb(215, 255, 178);
387
+ display: block;
388
+ }
389
+ span.run60 {
390
+ background-color: rgb(219, 255, 178);
391
+ display: block;
392
+ }
393
+ span.run61 {
394
+ background-color: rgb(221, 255, 178);
395
+ display: block;
396
+ }
397
+ span.run62 {
398
+ background-color: rgb(224, 255, 178);
399
+ display: block;
400
+ }
401
+ span.run63 {
402
+ background-color: rgb(226, 255, 178);
403
+ display: block;
404
+ }
405
+ span.run64 {
406
+ background-color: rgb(229, 255, 178);
407
+ display: block;
408
+ }
409
+ span.run65 {
410
+ background-color: rgb(233, 255, 178);
411
+ display: block;
412
+ }
413
+ span.run66 {
414
+ background-color: rgb(235, 255, 178);
415
+ display: block;
416
+ }
417
+ span.run67 {
418
+ background-color: rgb(238, 255, 178);
419
+ display: block;
420
+ }
421
+ span.run68 {
422
+ background-color: rgb(240, 255, 178);
423
+ display: block;
424
+ }
425
+ span.run69 {
426
+ background-color: rgb(243, 255, 178);
427
+ display: block;
428
+ }
429
+ span.run70 {
430
+ background-color: rgb(247, 255, 178);
431
+ display: block;
432
+ }
433
+ span.run71 {
434
+ background-color: rgb(249, 255, 178);
435
+ display: block;
436
+ }
437
+ span.run72 {
438
+ background-color: rgb(252, 255, 178);
439
+ display: block;
440
+ }
441
+ span.run73 {
442
+ background-color: rgb(255, 255, 178);
443
+ display: block;
444
+ }
445
+ span.run74 {
446
+ background-color: rgb(255, 252, 178);
447
+ display: block;
448
+ }
449
+ span.run75 {
450
+ background-color: rgb(255, 248, 178);
451
+ display: block;
452
+ }
453
+ span.run76 {
454
+ background-color: rgb(255, 246, 178);
455
+ display: block;
456
+ }
457
+ span.run77 {
458
+ background-color: rgb(255, 243, 178);
459
+ display: block;
460
+ }
461
+ span.run78 {
462
+ background-color: rgb(255, 240, 178);
463
+ display: block;
464
+ }
465
+ span.run79 {
466
+ background-color: rgb(255, 238, 178);
467
+ display: block;
468
+ }
469
+ span.run80 {
470
+ background-color: rgb(255, 234, 178);
471
+ display: block;
472
+ }
473
+ span.run81 {
474
+ background-color: rgb(255, 232, 178);
475
+ display: block;
476
+ }
477
+ span.run82 {
478
+ background-color: rgb(255, 229, 178);
479
+ display: block;
480
+ }
481
+ span.run83 {
482
+ background-color: rgb(255, 226, 178);
483
+ display: block;
484
+ }
485
+ span.run84 {
486
+ background-color: rgb(255, 224, 178);
487
+ display: block;
488
+ }
489
+ span.run85 {
490
+ background-color: rgb(255, 220, 178);
491
+ display: block;
492
+ }
493
+ span.run86 {
494
+ background-color: rgb(255, 218, 178);
495
+ display: block;
496
+ }
497
+ span.run87 {
498
+ background-color: rgb(255, 215, 178);
499
+ display: block;
500
+ }
501
+ span.run88 {
502
+ background-color: rgb(255, 212, 178);
503
+ display: block;
504
+ }
505
+ span.run89 {
506
+ background-color: rgb(255, 210, 178);
507
+ display: block;
508
+ }
509
+ span.run90 {
510
+ background-color: rgb(255, 206, 178);
511
+ display: block;
512
+ }
513
+ span.run91 {
514
+ background-color: rgb(255, 204, 178);
515
+ display: block;
516
+ }
517
+ span.run92 {
518
+ background-color: rgb(255, 201, 178);
519
+ display: block;
520
+ }
521
+ span.run93 {
522
+ background-color: rgb(255, 198, 178);
523
+ display: block;
524
+ }
525
+ span.run94 {
526
+ background-color: rgb(255, 196, 178);
527
+ display: block;
528
+ }
529
+ span.run95 {
530
+ background-color: rgb(255, 192, 178);
531
+ display: block;
532
+ }
533
+ span.run96 {
534
+ background-color: rgb(255, 189, 178);
535
+ display: block;
536
+ }
537
+ span.run97 {
538
+ background-color: rgb(255, 187, 178);
539
+ display: block;
540
+ }
541
+ span.run98 {
542
+ background-color: rgb(255, 184, 178);
543
+ display: block;
544
+ }
545
+ span.run99 {
546
+ background-color: rgb(255, 182, 178);
547
+ display: block;
548
+ }
549
+ span.run100 {
550
+ background-color: rgb(255, 178, 178);
551
+ display: block;
552
+ }
553
+ </style>
554
+ </head>
555
+ <body><h3>C0 code coverage information</h3>
556
+ <p>Generated on Sat Jun 07 16:45:06 +1000 2008 with <a href='http://eigenclass.org/hiki/rcov'>rcov 0.8.1.2</a>
557
+ </p>
558
+ <hr/>
559
+ <pre><span class='marked0'>Code reported as executed by Ruby looks like this...
560
+ </span><span class='marked1'>and this: this line is also marked as covered.
561
+ </span><span class='inferred0'>Lines considered as run by rcov, but not reported by Ruby, look like this,
562
+ </span><span class='inferred1'>and this: these lines were inferred by rcov (using simple heuristics).
563
+ </span><span class='uncovered0'>Finally, here&apos;s a line marked as not executed.
564
+ </span></pre>
565
+ <table class='report'><thead><tr><td class='heading'>Name</td>
566
+ <td class='heading'>Total lines</td>
567
+ <td class='heading'>Lines of code</td>
568
+ <td class='heading'>Total coverage</td>
569
+ <td class='heading'>Code coverage</td>
570
+ </tr>
571
+ </thead>
572
+ <tbody><tr class='light'><td><a href='lib-googleauthsub_rb.html'>lib/googleauthsub.rb</a>
573
+ </td>
574
+ <td class='lines_total'><tt>267</tt>
575
+ </td>
576
+ <td class='lines_code'><tt>157</tt>
577
+ </td>
578
+ <td><table cellspacing='0' cellpadding='0' align='right'><tr><td><tt class='coverage_total'>50.6%</tt>
579
+ &nbsp;</td>
580
+ <td><table cellspacing='0' class='percent_graph' cellpadding='0' width='100'><tr><td class='covered' width='51'/>
581
+ <td class='uncovered' width='49'/>
582
+ </tr>
583
+ </table>
584
+ </td>
585
+ </tr>
586
+ </table>
587
+ </td>
588
+ <td><table cellspacing='0' cellpadding='0' align='right'><tr><td><tt class='coverage_code'>21.7%</tt>
589
+ &nbsp;</td>
590
+ <td><table cellspacing='0' class='percent_graph' cellpadding='0' width='100'><tr><td class='covered' width='22'/>
591
+ <td class='uncovered' width='78'/>
592
+ </tr>
593
+ </table>
594
+ </td>
595
+ </tr>
596
+ </table>
597
+ </td>
598
+ </tr>
599
+ </tbody>
600
+ </table>
601
+ <pre><span class="inferred1"><a name="line1"></a> 1 # AuthSub - Ruby library for Google Authorization
602
+ </span><span class="inferred0"><a name="line2"></a> 2 # # Copyright 2008 Stuart Coyle &lt;stuart.coyle@gmail.com&gt;
603
+ </span><span class="inferred1"><a name="line3"></a> 3 #
604
+ </span><span class="inferred0"><a name="line4"></a> 4 # Permission is hereby granted, free of charge, to any person obtaining
605
+ </span><span class="inferred1"><a name="line5"></a> 5 # a copy of this software and associated documentation files (the
606
+ </span><span class="inferred0"><a name="line6"></a> 6 # &quot;Software&quot;), to deal in the Software without restriction, including
607
+ </span><span class="inferred1"><a name="line7"></a> 7 # without limitation the rights to use, copy, modify, merge, publish,
608
+ </span><span class="inferred0"><a name="line8"></a> 8 # distribute, sublicense, and/or sell copies of the Software, and to
609
+ </span><span class="inferred1"><a name="line9"></a> 9 # permit persons to whom the Software is furnished to do so, subject to
610
+ </span><span class="inferred0"><a name="line10"></a> 10 # the following conditions:
611
+ </span><span class="inferred1"><a name="line11"></a> 11 #
612
+ </span><span class="inferred0"><a name="line12"></a> 12 # The above copyright notice and this permission notice shall be
613
+ </span><span class="inferred1"><a name="line13"></a> 13 # included in all copies or substantial portions of the Software.
614
+ </span><span class="inferred0"><a name="line14"></a> 14 #
615
+ </span><span class="inferred1"><a name="line15"></a> 15 # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,
616
+ </span><span class="inferred0"><a name="line16"></a> 16 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
617
+ </span><span class="inferred1"><a name="line17"></a> 17 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
618
+ </span><span class="inferred0"><a name="line18"></a> 18 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
619
+ </span><span class="inferred1"><a name="line19"></a> 19 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
620
+ </span><span class="inferred0"><a name="line20"></a> 20 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
621
+ </span><span class="inferred1"><a name="line21"></a> 21 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
622
+ </span><span class="inferred0"><a name="line22"></a> 22
623
+ </span><span class="marked1"><a name="line23"></a> 23 require 'uri'
624
+ </span><span class="marked0"><a name="line24"></a> 24 require 'net/https'
625
+ </span><span class="marked1"><a name="line25"></a> 25 require 'openssl'
626
+ </span><span class="marked0"><a name="line26"></a> 26 require 'base64'
627
+ </span><span class="inferred1"><a name="line27"></a> 27
628
+ </span><span class="inferred0"><a name="line28"></a> 28 # Note: The module declared here may change depending on what other developers are using
629
+ </span><span class="inferred1"><a name="line29"></a> 29 #
630
+ </span><span class="marked0"><a name="line30"></a> 30 module GData
631
+ </span><span class="marked1"><a name="line31"></a> 31 GOOGLE_HOST_URL = &quot;www.google.com&quot;
632
+ </span><span class="marked0"><a name="line32"></a> 32 GOOGLE_AUTHSUB_BASE_PATH = &quot;/accounts&quot;
633
+ </span><span class="marked1"><a name="line33"></a> 33 GOOGLE_AUTHSUB_REQUEST_PATH = GOOGLE_AUTHSUB_BASE_PATH + &quot;/AuthSubRequest&quot;
634
+ </span><span class="marked0"><a name="line34"></a> 34 GOOGLE_AUTHSUB_SESSION_TOKEN_PATH = GOOGLE_AUTHSUB_BASE_PATH + &quot;/AuthSubSessionToken&quot;
635
+ </span><span class="marked1"><a name="line35"></a> 35 GOOGLE_AUTHSUB_REVOKE_PATH = GOOGLE_AUTHSUB_BASE_PATH + &quot;/AuthSubRevokeToken&quot;
636
+ </span><span class="marked0"><a name="line36"></a> 36 GOOGLE_AUTHSUB_TOKEN_INFO_PATH = GOOGLE_AUTHSUB_BASE_PATH + &quot;/AuthSubTokenInfo&quot;
637
+ </span><span class="inferred1"><a name="line37"></a> 37
638
+ </span><span class="marked0"><a name="line38"></a> 38 class Error &lt; Exception
639
+ </span><span class="inferred1"><a name="line39"></a> 39 end
640
+ </span><span class="inferred0"><a name="line40"></a> 40
641
+ </span><span class="marked1"><a name="line41"></a> 41 class AuthSubError &lt; Error
642
+ </span><span class="marked0"><a name="line42"></a> 42 def message
643
+ </span><span class="uncovered1"><a name="line43"></a> 43 &quot;Google Authentication Error&quot;
644
+ </span><span class="uncovered0"><a name="line44"></a> 44 end
645
+ </span><span class="uncovered1"><a name="line45"></a> 45 end
646
+ </span><span class="inferred0"><a name="line46"></a> 46
647
+ </span><span class="inferred1"><a name="line47"></a> 47
648
+ </span><span class="inferred0"><a name="line48"></a> 48 # GoogleAuthSub
649
+ </span><span class="inferred1"><a name="line49"></a> 49 # This class handles the Google Authentication for Web Applications API
650
+ </span><span class="inferred0"><a name="line50"></a> 50 #
651
+ </span><span class="marked1"><a name="line51"></a> 51 class GoogleAuthSub
652
+ </span><span class="inferred0"><a name="line52"></a> 52
653
+ </span><span class="marked1"><a name="line53"></a> 53 attr_accessor :target, :scope, :session, :secure, :next_url, :token, :sigalg
654
+ </span><span class="inferred0"><a name="line54"></a> 54
655
+ </span><span class="inferred1"><a name="line55"></a> 55 # +key+ can be a File, String or OpenSSL::Pkey::RSA
656
+ </span><span class="inferred0"><a name="line56"></a> 56 # Sets the private key to use for secure sessions.
657
+ </span><span class="inferred1"><a name="line57"></a> 57 # This should correspond to the public key sent to Google in
658
+ </span><span class="inferred0"><a name="line58"></a> 58 # the registration process.
659
+ </span><span class="inferred1"><a name="line59"></a> 59 # For registration details see:
660
+ </span><span class="inferred0"><a name="line60"></a> 60 # http://code.google.com/apis/accounts/docs/RegistrationForWebAppsAuto.html
661
+ </span><span class="inferred1"><a name="line61"></a> 61 #
662
+ </span><span class="inferred0"><a name="line62"></a> 62 # This sets the class variable @@pkey to an OpenSSL::Pkey::RSA object
663
+ </span><span class="marked1"><a name="line63"></a> 63 def self.set_private_key(key)
664
+ </span><span class="uncovered0"><a name="line64"></a> 64 case key
665
+ </span><span class="uncovered1"><a name="line65"></a> 65 when OpenSSL::PKey::RSA
666
+ </span><span class="uncovered0"><a name="line66"></a> 66 @@pkey = key
667
+ </span><span class="uncovered1"><a name="line67"></a> 67 when File
668
+ </span><span class="uncovered0"><a name="line68"></a> 68 # Read key from a PEM file.
669
+ </span><span class="uncovered1"><a name="line69"></a> 69 @@pkey = OpenSSL::PKey::RSA.new(key.read)
670
+ </span><span class="uncovered0"><a name="line70"></a> 70 when String
671
+ </span><span class="uncovered1"><a name="line71"></a> 71 # Get key from a PEM in the form of a string.
672
+ </span><span class="uncovered0"><a name="line72"></a> 72 @@pkey = OpenSSL::PKey::RSA.new(key)
673
+ </span><span class="uncovered1"><a name="line73"></a> 73 else
674
+ </span><span class="uncovered0"><a name="line74"></a> 74 raise AuthSubError, &quot;Private Key in wrong format. Require IO, String or OpenSSL::Pkey::RSA, you gave me #{key.class}&quot;
675
+ </span><span class="uncovered1"><a name="line75"></a> 75 end
676
+ </span><span class="uncovered0"><a name="line76"></a> 76 end
677
+ </span><span class="inferred1"><a name="line77"></a> 77
678
+ </span><span class="inferred0"><a name="line78"></a> 78 # Create a new GoogleAuthsub object
679
+ </span><span class="inferred1"><a name="line79"></a> 79 # Options specified in +opts+ consist of:
680
+ </span><span class="inferred0"><a name="line80"></a> 80 #
681
+ </span><span class="inferred1"><a name="line81"></a> 81 # * :next_url - (String) The url to redirect back to once the user has signed in to Google.
682
+ </span><span class="inferred0"><a name="line82"></a> 82 # * :scope_url - (String) The service from Google that you wish to receive data from with this token.
683
+ </span><span class="inferred1"><a name="line83"></a> 83 # * :session - (boolean) Whether the token is able to be used to get a session token or is just one use.
684
+ </span><span class="inferred0"><a name="line84"></a> 84 # * :secure - (boolean) Whether the token can be used for sessions.
685
+ </span><span class="inferred1"><a name="line85"></a> 85 # * :sigalg - (String) Currently not needed, as the Authsub specification only has rsa-sha1.
686
+ </span><span class="marked0"><a name="line86"></a> 86 def initialize(opts = {})
687
+ </span><span class="uncovered1"><a name="line87"></a> 87 self.next_url = opts[:next_url] || ''
688
+ </span><span class="uncovered0"><a name="line88"></a> 88 self.scope = opts[:scope_url] || ''
689
+ </span><span class="uncovered1"><a name="line89"></a> 89 self.session = opts[:session] || false
690
+ </span><span class="uncovered0"><a name="line90"></a> 90 self.secure = opts[:secure] || false
691
+ </span><span class="uncovered1"><a name="line91"></a> 91 self.sigalg = opts[:sigalg] || &quot;rsa-sha1&quot;
692
+ </span><span class="uncovered0"><a name="line92"></a> 92 end
693
+ </span><span class="inferred1"><a name="line93"></a> 93
694
+ </span><span class="inferred0"><a name="line94"></a> 94 # This returns a URI::HTTPS object which contains the Google url to request a token from.
695
+ </span><span class="marked1"><a name="line95"></a> 95 def request_url
696
+ </span><span class="uncovered0"><a name="line96"></a> 96 #FIXME: these currently cause a crash.
697
+ </span><span class="uncovered1"><a name="line97"></a> 97 raise AuthSubError, &quot;Invalid next URL: #{@next_url}&quot; if !full_url?(@next_url)
698
+ </span><span class="uncovered0"><a name="line98"></a> 98 raise AuthSubError, &quot;Invalid scope URL: #{@scope}&quot; if !full_url?(@scope)
699
+ </span><span class="uncovered1"><a name="line99"></a> 99 query = &quot;next=&quot; &lt;&lt; @next_url &lt;&lt; &quot;&amp;scope=&quot; &lt;&lt; @scope &lt;&lt; &quot;&amp;session=&quot;&lt;&lt;
700
+ </span><span class="uncovered0"><a name="line100"></a>100 (session_token? ? '1' : '0')&lt;&lt; &quot;&amp;secure=&quot;&lt;&lt; (secure_token? ? '1' : '0')
701
+ </span><span class="uncovered1"><a name="line101"></a>101 query = URI.encode(query)
702
+ </span><span class="uncovered0"><a name="line102"></a>102 URI::HTTPS.build({:host =&gt; GOOGLE_HOST_URL, :path =&gt; GOOGLE_AUTHSUB_REQUEST_PATH, :query =&gt; query })
703
+ </span><span class="uncovered1"><a name="line103"></a>103 end
704
+ </span><span class="inferred0"><a name="line104"></a>104
705
+ </span><span class="inferred1"><a name="line105"></a>105 # +url+ :the URL received from Google once the user has signed in.
706
+ </span><span class="inferred0"><a name="line106"></a>106 #
707
+ </span><span class="inferred1"><a name="line107"></a>107 # This method extracts the token from the request url that Google
708
+ </span><span class="inferred0"><a name="line108"></a>108 # sends the user back to.
709
+ </span><span class="inferred1"><a name="line109"></a>109 # This url will be like: http://www.example.com/next?Token=CMDshfjfkeodf
710
+ </span><span class="inferred0"><a name="line110"></a>110 # In Rails applications you don't need this method, just use
711
+ </span><span class="inferred1"><a name="line111"></a>111 # +GoogleAuthsub#token=params[:token]+
712
+ </span><span class="inferred0"><a name="line112"></a>112 #
713
+ </span><span class="marked1"><a name="line113"></a>113 def receive_token(url)
714
+ </span><span class="uncovered0"><a name="line114"></a>114 puts url
715
+ </span><span class="uncovered1"><a name="line115"></a>115 q = url.query.match( /.*token=(.*)/i)
716
+ </span><span class="uncovered0"><a name="line116"></a>116 @token = q[1] if !q.nil?
717
+ </span><span class="uncovered1"><a name="line117"></a>117 end
718
+ </span><span class="inferred0"><a name="line118"></a>118
719
+ </span><span class="inferred1"><a name="line119"></a>119 # Returns true if this token can be exchanged for a session token
720
+ </span><span class="marked0"><a name="line120"></a>120 def session_token?
721
+ </span><span class="uncovered1"><a name="line121"></a>121 session == true
722
+ </span><span class="uncovered0"><a name="line122"></a>122 end
723
+ </span><span class="inferred1"><a name="line123"></a>123
724
+ </span><span class="inferred0"><a name="line124"></a>124 # Returns true if the token is used for secure sessions
725
+ </span><span class="marked1"><a name="line125"></a>125 def secure_token?
726
+ </span><span class="uncovered0"><a name="line126"></a>126 secure == true
727
+ </span><span class="uncovered1"><a name="line127"></a>127 end
728
+ </span><span class="inferred0"><a name="line128"></a>128
729
+ </span><span class="inferred1"><a name="line129"></a>129 # session_token
730
+ </span><span class="inferred0"><a name="line130"></a>130 # This method exchanges a previously received single use token with a session token.
731
+ </span><span class="inferred1"><a name="line131"></a>131 # Raises error if an invalid response is received.
732
+ </span><span class="marked0"><a name="line132"></a>132 def session_token
733
+ </span><span class="uncovered1"><a name="line133"></a>133 url = URI::HTTPS.build({:host =&gt; GOOGLE_HOST_URL,
734
+ </span><span class="uncovered0"><a name="line134"></a>134 :path =&gt; GOOGLE_AUTHSUB_SESSION_TOKEN_PATH})
735
+ </span><span class="uncovered1"><a name="line135"></a>135 begin
736
+ </span><span class="uncovered0"><a name="line136"></a>136 @token = get(url).body.match(/^Token=(.*)$/)[1]
737
+ </span><span class="uncovered1"><a name="line137"></a>137 rescue
738
+ </span><span class="uncovered0"><a name="line138"></a>138 raise AuthSubError, &quot;Invalid session token response.&quot;
739
+ </span><span class="uncovered1"><a name="line139"></a>139 end
740
+ </span><span class="uncovered0"><a name="line140"></a>140 end
741
+ </span><span class="inferred1"><a name="line141"></a>141
742
+ </span><span class="inferred0"><a name="line142"></a>142 # revoke_token
743
+ </span><span class="inferred1"><a name="line143"></a>143 # This revokes either a single use or session token
744
+ </span><span class="inferred0"><a name="line144"></a>144 # The token will not be able to be used again if this call is successful.
745
+ </span><span class="inferred1"><a name="line145"></a>145 # It returns true on sucess, false on failure.
746
+ </span><span class="marked0"><a name="line146"></a>146 def revoke_token
747
+ </span><span class="uncovered1"><a name="line147"></a>147 url = URI::HTTPS.build({:host=&gt;GOOGLE_HOST_URL,
748
+ </span><span class="uncovered0"><a name="line148"></a>148 :path =&gt; GOOGLE_AUTHSUB_REVOKE_PATH})
749
+ </span><span class="uncovered1"><a name="line149"></a>149 begin
750
+ </span><span class="uncovered0"><a name="line150"></a>150 get(url)
751
+ </span><span class="uncovered1"><a name="line151"></a>151 true
752
+ </span><span class="uncovered0"><a name="line152"></a>152 rescue
753
+ </span><span class="uncovered1"><a name="line153"></a>153 false
754
+ </span><span class="uncovered0"><a name="line154"></a>154 end
755
+ </span><span class="uncovered1"><a name="line155"></a>155 end
756
+ </span><span class="inferred0"><a name="line156"></a>156
757
+ </span><span class="inferred1"><a name="line157"></a>157 # token_info
758
+ </span><span class="inferred0"><a name="line158"></a>158 # Returns the information for the session token from Google.
759
+ </span><span class="inferred1"><a name="line159"></a>159 # Returns a map {:target, :scope, :secure}
760
+ </span><span class="marked0"><a name="line160"></a>160 def token_info
761
+ </span><span class="uncovered1"><a name="line161"></a>161 url = URI::HTTPS.build({:host=&gt;GOOGLE_HOST_URL,
762
+ </span><span class="uncovered0"><a name="line162"></a>162 :path =&gt; GOOGLE_AUTHSUB_TOKEN_INFO_PATH})
763
+ </span><span class="uncovered1"><a name="line163"></a>163 response = get(url)
764
+ </span><span class="uncovered0"><a name="line164"></a>164 info = Hash.new
765
+ </span><span class="uncovered1"><a name="line165"></a>165 begin
766
+ </span><span class="uncovered0"><a name="line166"></a>166 info[:target] = response.body.match(/^Target=(.*)$/)[1]
767
+ </span><span class="uncovered1"><a name="line167"></a>167 info[:scope] = response.body.match(/^Scope=(.*)$/)[1]
768
+ </span><span class="uncovered0"><a name="line168"></a>168 info[:secure] = (response.body.match(/^Secure=(.*)$/)[1].downcase == 'true')
769
+ </span><span class="uncovered1"><a name="line169"></a>169 rescue
770
+ </span><span class="uncovered0"><a name="line170"></a>170 raise AuthSubError, &quot;Google Authsub Error: invalid token info packet received.&quot;
771
+ </span><span class="uncovered1"><a name="line171"></a>171 end
772
+ </span><span class="uncovered0"><a name="line172"></a>172 return info
773
+ </span><span class="uncovered1"><a name="line173"></a>173 end
774
+ </span><span class="inferred0"><a name="line174"></a>174
775
+ </span><span class="inferred1"><a name="line175"></a>175 # get +url+
776
+ </span><span class="inferred0"><a name="line176"></a>176 # Does a HTTP GET request to Google using the AuthSub token.
777
+ </span><span class="inferred1"><a name="line177"></a>177 # This returns a Net::HTTPResponse object.
778
+ </span><span class="marked0"><a name="line178"></a>178 def get(url)
779
+ </span><span class="uncovered1"><a name="line179"></a>179 authsub_http_request(Net::HTTP::Get,url)
780
+ </span><span class="uncovered0"><a name="line180"></a>180 end
781
+ </span><span class="inferred1"><a name="line181"></a>181
782
+ </span><span class="inferred0"><a name="line182"></a>182 # post +url+
783
+ </span><span class="inferred1"><a name="line183"></a>183 # Does a HTTP POST request to Google using the AuthSub token.
784
+ </span><span class="inferred0"><a name="line184"></a>184 # This returns a Net::HTTPResponse object.
785
+ </span><span class="marked1"><a name="line185"></a>185 def post(url)
786
+ </span><span class="uncovered0"><a name="line186"></a>186 authsub_http_request(Net::HTTP::Post,url)
787
+ </span><span class="uncovered1"><a name="line187"></a>187 end
788
+ </span><span class="inferred0"><a name="line188"></a>188
789
+ </span><span class="inferred1"><a name="line189"></a>189 # put +url+
790
+ </span><span class="inferred0"><a name="line190"></a>190 # Does a HTTP PUT request to Google using the AuthSub token.
791
+ </span><span class="inferred1"><a name="line191"></a>191 # This returns a Net::HTTPResponse object.
792
+ </span><span class="marked0"><a name="line192"></a>192 def put(url)
793
+ </span><span class="uncovered1"><a name="line193"></a>193 authsub_http_request(Net::HTTP::Put,url)
794
+ </span><span class="uncovered0"><a name="line194"></a>194 end
795
+ </span><span class="inferred1"><a name="line195"></a>195
796
+ </span><span class="inferred0"><a name="line196"></a>196 # delete +url+
797
+ </span><span class="inferred1"><a name="line197"></a>197 # Does a HTTP DELETE request to Google using the AuthSub token.
798
+ </span><span class="inferred0"><a name="line198"></a>198 # This returns a Net::HTTPResponse object.
799
+ </span><span class="marked1"><a name="line199"></a>199 def delete(url)
800
+ </span><span class="uncovered0"><a name="line200"></a>200 authsub_http_request(Net::HTTP::Delete,url)
801
+ </span><span class="uncovered1"><a name="line201"></a>201 end
802
+ </span><span class="inferred0"><a name="line202"></a>202
803
+ </span><span class="marked1"><a name="line203"></a>203 private
804
+ </span><span class="inferred0"><a name="line204"></a>204
805
+ </span><span class="marked1"><a name="line205"></a>205 def authsub_http_request(method, u) #:nodoc:
806
+ </span><span class="uncovered0"><a name="line206"></a>206 case u
807
+ </span><span class="uncovered1"><a name="line207"></a>207 when String
808
+ </span><span class="uncovered0"><a name="line208"></a>208 # Add scope
809
+ </span><span class="uncovered1"><a name="line209"></a>209 u = (@scope &lt;&lt; u) if @scope &amp;&amp; !u.include?(@scope)
810
+ </span><span class="uncovered0"><a name="line210"></a>210 begin
811
+ </span><span class="uncovered1"><a name="line211"></a>211 url = URI.parse(u)
812
+ </span><span class="uncovered0"><a name="line212"></a>212 rescue URI::InvalidURIError
813
+ </span><span class="uncovered1"><a name="line213"></a>213 raise URI::InvalidURIError
814
+ </span><span class="uncovered0"><a name="line214"></a>214 end
815
+ </span><span class="uncovered1"><a name="line215"></a>215 when URI
816
+ </span><span class="uncovered0"><a name="line216"></a>216 url = u
817
+ </span><span class="uncovered1"><a name="line217"></a>217 else
818
+ </span><span class="uncovered0"><a name="line218"></a>218 raise AuthSubError, &quot;url must be String or URI, #{url.class} received.&quot;
819
+ </span><span class="uncovered1"><a name="line219"></a>219 end
820
+ </span><span class="uncovered0"><a name="line220"></a>220
821
+ </span><span class="uncovered1"><a name="line221"></a>221 if method.superclass != Net::HTTPRequest
822
+ </span><span class="uncovered0"><a name="line222"></a>222 raise AuthSubError, &quot;method must be a Net::HTTPRequest subclass. #{method} received.&quot;
823
+ </span><span class="uncovered1"><a name="line223"></a>223 end
824
+ </span><span class="uncovered0"><a name="line224"></a>224 request = method.new(url.path)
825
+ </span><span class="uncovered1"><a name="line225"></a>225 request['Authorization'] = authorization_header(request, url)
826
+ </span><span class="uncovered0"><a name="line226"></a>226 connection = Net::HTTP.new(url.host, url.port)
827
+ </span><span class="uncovered1"><a name="line227"></a>227 connection.use_ssl= (url.scheme == 'https')
828
+ </span><span class="uncovered0"><a name="line228"></a>228 response = connection.start{ |http| http.request(request) }
829
+ </span><span class="uncovered1"><a name="line229"></a>229 case response
830
+ </span><span class="uncovered0"><a name="line230"></a>230 when Net::HTTPSuccess
831
+ </span><span class="uncovered1"><a name="line231"></a>231 #OK
832
+ </span><span class="uncovered0"><a name="line232"></a>232 else
833
+ </span><span class="uncovered1"><a name="line233"></a>233 response.error!
834
+ </span><span class="uncovered0"><a name="line234"></a>234 end
835
+ </span><span class="uncovered1"><a name="line235"></a>235 response
836
+ </span><span class="uncovered0"><a name="line236"></a>236 end
837
+ </span><span class="inferred1"><a name="line237"></a>237
838
+ </span><span class="inferred0"><a name="line238"></a>238 # Construct the authorization header for a request
839
+ </span><span class="marked1"><a name="line239"></a>239 def authorization_header(request, url)
840
+ </span><span class="uncovered0"><a name="line240"></a>240 case secure_token?
841
+ </span><span class="uncovered1"><a name="line241"></a>241 when false
842
+ </span><span class="uncovered0"><a name="line242"></a>242 return &quot;AuthSub token=\&quot;#{@token}\&quot;&quot;
843
+ </span><span class="uncovered1"><a name="line243"></a>243 when true
844
+ </span><span class="uncovered0"><a name="line244"></a>244 timestamp = Time.now.to_i
845
+ </span><span class="uncovered1"><a name="line245"></a>245 nonce = OpenSSL::BN.rand_range(2**64)
846
+ </span><span class="uncovered0"><a name="line246"></a>246 data = request.method + ' ' + url.to_s + ' ' + timestamp.to_s + ' ' + nonce.to_s
847
+ </span><span class="uncovered1"><a name="line247"></a>247 digest = OpenSSL::Digest::SHA1.new(data).hexdigest
848
+ </span><span class="uncovered0"><a name="line248"></a>248 sig = [@@pkey.private_encrypt(digest)].pack(&quot;m&quot;) #Base64 encode
849
+ </span><span class="uncovered1"><a name="line249"></a>249 return &quot;AuthSub token=\&quot;#{@token}\&quot; data=\&quot;#{data}\&quot; sig=\&quot;#{sig}\&quot; sigalg=\&quot;#{sigalg}\&quot;&quot;
850
+ </span><span class="uncovered0"><a name="line250"></a>250 end
851
+ </span><span class="uncovered1"><a name="line251"></a>251 end
852
+ </span><span class="inferred0"><a name="line252"></a>252
853
+ </span><span class="inferred1"><a name="line253"></a>253 # Checks whether a URL is a full url, i.e. has all of scheme, host and path.
854
+ </span><span class="marked0"><a name="line254"></a>254 def full_url?(url)
855
+ </span><span class="uncovered1"><a name="line255"></a>255 # First check if it is a bad uri
856
+ </span><span class="uncovered0"><a name="line256"></a>256 begin
857
+ </span><span class="uncovered1"><a name="line257"></a>257 u = URI.parse(url)
858
+ </span><span class="uncovered0"><a name="line258"></a>258 rescue URI.InvalidURIError
859
+ </span><span class="uncovered1"><a name="line259"></a>259 return false
860
+ </span><span class="uncovered0"><a name="line260"></a>260 end
861
+ </span><span class="uncovered1"><a name="line261"></a>261 return false if u.scheme.nil? || u.host.nil? || u.path.nil?
862
+ </span><span class="uncovered0"><a name="line262"></a>262 true
863
+ </span><span class="uncovered1"><a name="line263"></a>263 end
864
+ </span><span class="uncovered0"><a name="line264"></a>264
865
+ </span><span class="uncovered1"><a name="line265"></a>265 end
866
+ </span><span class="uncovered0"><a name="line266"></a>266
867
+ </span><span class="uncovered1"><a name="line267"></a>267 end
868
+ </span></pre><hr/>
869
+ <p>Generated using the <a href='http://eigenclass.org/hiki.rb?rcov'>rcov code coverage analysis tool for Ruby</a>
870
+ version 0.8.1.2.</p>
871
+ <p><a href='http://validator.w3.org/check/referer'><img src='http://www.w3.org/Icons/valid-xhtml10' height='31' alt='Valid XHTML 1.0!' width='88'/>
872
+ </a>
873
+ <a href='http://jigsaw.w3.org/css-validator/check/referer'><img src='http://jigsaw.w3.org/css-validator/images/vcss' alt='Valid CSS!' style='border:0;width:88px;height:31px'/>
874
+ </a>
875
+ </p>
876
+ </body>
877
+ </html>