king_tokens 1.0.0

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.
@@ -0,0 +1,344 @@
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'>
3
+ <head>
4
+ <title>
5
+ lib/tokenizer.rb - C0 code coverage information
6
+ </title>
7
+ <style type='text/css'>
8
+ body { background-color: rgb(240, 240, 245); }
9
+ </style>
10
+ <style type='text/css'>
11
+ span.cross-ref-title { font-size: 140%; } span.cross-ref a {
12
+ text-decoration: none; } span.cross-ref { background-color:#f3f7fa;
13
+ border: 1px dashed #333; margin: 1em; padding: 0.5em; overflow: hidden; }
14
+ a.crossref-toggle { text-decoration: none; } span.marked0 {
15
+ background-color: rgb(185, 210, 200); display: block; } span.marked1 {
16
+ background-color: rgb(190, 215, 205); display: block; } span.inferred0 {
17
+ background-color: rgb(175, 200, 200); display: block; } span.inferred1 {
18
+ background-color: rgb(180, 205, 205); display: block; } span.uncovered0 {
19
+ background-color: rgb(225, 110, 110); display: block; } span.uncovered1 {
20
+ background-color: rgb(235, 120, 120); display: block; } span.overview {
21
+ border-bottom: 8px solid black; } div.overview { border-bottom: 8px solid
22
+ black; } body { font-family: verdana, arial, helvetica; } div.footer {
23
+ font-size: 68%; margin-top: 1.5em; } h1, h2, h3, h4, h5, h6 {
24
+ margin-bottom: 0.5em; } h5 { margin-top: 0.5em; } .hidden { display: none;
25
+ } div.separator { height: 10px; } /* Commented out for better readability,
26
+ esp. on IE */ /* table tr td, table tr th { font-size: 68%; } td.value
27
+ table tr td { font-size: 11px; } */ table.percent_graph { height: 12px;
28
+ border: #808080 1px solid; empty-cells: show; } table.percent_graph
29
+ td.covered { height: 10px; background: #00f000; } table.percent_graph
30
+ td.uncovered { height: 10px; background: #e00000; } table.percent_graph
31
+ td.NA { height: 10px; background: #eaeaea; } table.report {
32
+ border-collapse: collapse; width: 100%; } table.report td.heading {
33
+ background: #dcecff; border: #d0d0d0 1px solid; font-weight: bold;
34
+ text-align: center; } table.report td.heading:hover { background: #c0ffc0;
35
+ } table.report td.text { border: #d0d0d0 1px solid; } table.report
36
+ td.value, table.report td.lines_total, table.report td.lines_code {
37
+ text-align: right; border: #d0d0d0 1px solid; } table.report tr.light {
38
+ background-color: rgb(240, 240, 245); } table.report tr.dark {
39
+ background-color: rgb(230, 230, 235); }
40
+ </style>
41
+ <script type='text/javascript'>
42
+ // <![CDATA[ function toggleCode( id ) { if ( document.getElementById )
43
+ elem = document.getElementById( id ); else if ( document.all ) elem =
44
+ eval( "document.all." + id ); else return false; elemStyle = elem.style;
45
+ if ( elemStyle.display != "block" ) { elemStyle.display = "block" } else {
46
+ elemStyle.display = "none" } return true; } // Make cross-references
47
+ hidden by default document.writeln( "<style
48
+ type=\"text/css\">span.cross-ref { display: none }</style>" ) // ]]>
49
+ </script>
50
+ <style type='text/css'>
51
+ span.run0 { background-color: rgb(178, 204, 255); display: block; }
52
+ span.run1 { background-color: rgb(178, 206, 255); display: block; }
53
+ span.run2 { background-color: rgb(178, 209, 255); display: block; }
54
+ span.run3 { background-color: rgb(178, 211, 255); display: block; }
55
+ span.run4 { background-color: rgb(178, 214, 255); display: block; }
56
+ span.run5 { background-color: rgb(178, 218, 255); display: block; }
57
+ span.run6 { background-color: rgb(178, 220, 255); display: block; }
58
+ span.run7 { background-color: rgb(178, 223, 255); display: block; }
59
+ span.run8 { background-color: rgb(178, 225, 255); display: block; }
60
+ span.run9 { background-color: rgb(178, 228, 255); display: block; }
61
+ span.run10 { background-color: rgb(178, 232, 255); display: block; }
62
+ span.run11 { background-color: rgb(178, 234, 255); display: block; }
63
+ span.run12 { background-color: rgb(178, 237, 255); display: block; }
64
+ span.run13 { background-color: rgb(178, 239, 255); display: block; }
65
+ span.run14 { background-color: rgb(178, 242, 255); display: block; }
66
+ span.run15 { background-color: rgb(178, 246, 255); display: block; }
67
+ span.run16 { background-color: rgb(178, 248, 255); display: block; }
68
+ span.run17 { background-color: rgb(178, 251, 255); display: block; }
69
+ span.run18 { background-color: rgb(178, 253, 255); display: block; }
70
+ span.run19 { background-color: rgb(178, 255, 253); display: block; }
71
+ span.run20 { background-color: rgb(178, 255, 249); display: block; }
72
+ span.run21 { background-color: rgb(178, 255, 247); display: block; }
73
+ span.run22 { background-color: rgb(178, 255, 244); display: block; }
74
+ span.run23 { background-color: rgb(178, 255, 242); display: block; }
75
+ span.run24 { background-color: rgb(178, 255, 239); display: block; }
76
+ span.run25 { background-color: rgb(178, 255, 235); display: block; }
77
+ span.run26 { background-color: rgb(178, 255, 233); display: block; }
78
+ span.run27 { background-color: rgb(178, 255, 230); display: block; }
79
+ span.run28 { background-color: rgb(178, 255, 228); display: block; }
80
+ span.run29 { background-color: rgb(178, 255, 225); display: block; }
81
+ span.run30 { background-color: rgb(178, 255, 221); display: block; }
82
+ span.run31 { background-color: rgb(178, 255, 219); display: block; }
83
+ span.run32 { background-color: rgb(178, 255, 216); display: block; }
84
+ span.run33 { background-color: rgb(178, 255, 214); display: block; }
85
+ span.run34 { background-color: rgb(178, 255, 211); display: block; }
86
+ span.run35 { background-color: rgb(178, 255, 207); display: block; }
87
+ span.run36 { background-color: rgb(178, 255, 205); display: block; }
88
+ span.run37 { background-color: rgb(178, 255, 202); display: block; }
89
+ span.run38 { background-color: rgb(178, 255, 200); display: block; }
90
+ span.run39 { background-color: rgb(178, 255, 197); display: block; }
91
+ span.run40 { background-color: rgb(178, 255, 193); display: block; }
92
+ span.run41 { background-color: rgb(178, 255, 191); display: block; }
93
+ span.run42 { background-color: rgb(178, 255, 188); display: block; }
94
+ span.run43 { background-color: rgb(178, 255, 186); display: block; }
95
+ span.run44 { background-color: rgb(178, 255, 183); display: block; }
96
+ span.run45 { background-color: rgb(178, 255, 179); display: block; }
97
+ span.run46 { background-color: rgb(179, 255, 178); display: block; }
98
+ span.run47 { background-color: rgb(182, 255, 178); display: block; }
99
+ span.run48 { background-color: rgb(184, 255, 178); display: block; }
100
+ span.run49 { background-color: rgb(187, 255, 178); display: block; }
101
+ span.run50 { background-color: rgb(191, 255, 178); display: block; }
102
+ span.run51 { background-color: rgb(193, 255, 178); display: block; }
103
+ span.run52 { background-color: rgb(196, 255, 178); display: block; }
104
+ span.run53 { background-color: rgb(198, 255, 178); display: block; }
105
+ span.run54 { background-color: rgb(201, 255, 178); display: block; }
106
+ span.run55 { background-color: rgb(205, 255, 178); display: block; }
107
+ span.run56 { background-color: rgb(207, 255, 178); display: block; }
108
+ span.run57 { background-color: rgb(210, 255, 178); display: block; }
109
+ span.run58 { background-color: rgb(212, 255, 178); display: block; }
110
+ span.run59 { background-color: rgb(215, 255, 178); display: block; }
111
+ span.run60 { background-color: rgb(219, 255, 178); display: block; }
112
+ span.run61 { background-color: rgb(221, 255, 178); display: block; }
113
+ span.run62 { background-color: rgb(224, 255, 178); display: block; }
114
+ span.run63 { background-color: rgb(226, 255, 178); display: block; }
115
+ span.run64 { background-color: rgb(229, 255, 178); display: block; }
116
+ span.run65 { background-color: rgb(233, 255, 178); display: block; }
117
+ span.run66 { background-color: rgb(235, 255, 178); display: block; }
118
+ span.run67 { background-color: rgb(238, 255, 178); display: block; }
119
+ span.run68 { background-color: rgb(240, 255, 178); display: block; }
120
+ span.run69 { background-color: rgb(243, 255, 178); display: block; }
121
+ span.run70 { background-color: rgb(247, 255, 178); display: block; }
122
+ span.run71 { background-color: rgb(249, 255, 178); display: block; }
123
+ span.run72 { background-color: rgb(252, 255, 178); display: block; }
124
+ span.run73 { background-color: rgb(255, 255, 178); display: block; }
125
+ span.run74 { background-color: rgb(255, 252, 178); display: block; }
126
+ span.run75 { background-color: rgb(255, 248, 178); display: block; }
127
+ span.run76 { background-color: rgb(255, 246, 178); display: block; }
128
+ span.run77 { background-color: rgb(255, 243, 178); display: block; }
129
+ span.run78 { background-color: rgb(255, 240, 178); display: block; }
130
+ span.run79 { background-color: rgb(255, 238, 178); display: block; }
131
+ span.run80 { background-color: rgb(255, 234, 178); display: block; }
132
+ span.run81 { background-color: rgb(255, 232, 178); display: block; }
133
+ span.run82 { background-color: rgb(255, 229, 178); display: block; }
134
+ span.run83 { background-color: rgb(255, 226, 178); display: block; }
135
+ span.run84 { background-color: rgb(255, 224, 178); display: block; }
136
+ span.run85 { background-color: rgb(255, 220, 178); display: block; }
137
+ span.run86 { background-color: rgb(255, 218, 178); display: block; }
138
+ span.run87 { background-color: rgb(255, 215, 178); display: block; }
139
+ span.run88 { background-color: rgb(255, 212, 178); display: block; }
140
+ span.run89 { background-color: rgb(255, 210, 178); display: block; }
141
+ span.run90 { background-color: rgb(255, 206, 178); display: block; }
142
+ span.run91 { background-color: rgb(255, 204, 178); display: block; }
143
+ span.run92 { background-color: rgb(255, 201, 178); display: block; }
144
+ span.run93 { background-color: rgb(255, 198, 178); display: block; }
145
+ span.run94 { background-color: rgb(255, 196, 178); display: block; }
146
+ span.run95 { background-color: rgb(255, 192, 178); display: block; }
147
+ span.run96 { background-color: rgb(255, 189, 178); display: block; }
148
+ span.run97 { background-color: rgb(255, 187, 178); display: block; }
149
+ span.run98 { background-color: rgb(255, 184, 178); display: block; }
150
+ span.run99 { background-color: rgb(255, 182, 178); display: block; }
151
+ span.run100 { background-color: rgb(255, 178, 178); display: block; }
152
+ </style>
153
+ </head>
154
+ <body>
155
+ <h3>
156
+ C0 code coverage information
157
+ </h3>
158
+ <p>
159
+ Generated on Sun Dec 07 02:06:42 +0100 2008 with
160
+ <a href='http://eigenclass.org/hiki/rcov'>
161
+ rcov 0.8.1.2
162
+ </a>
163
+ </p>
164
+ <hr />
165
+ <pre><span class='marked0'>Code reported as executed by Ruby looks like
166
+ this... </span><span class='marked1'>and this: this line is also marked as
167
+ covered. </span><span class='inferred0'>Lines considered as run by rcov, but
168
+ not reported by Ruby, look like this, </span><span class='inferred1'>and
169
+ this: these lines were inferred by rcov (using simple heuristics).
170
+ </span><span class='uncovered0'>Finally, here&apos;s a line marked as not
171
+ executed. </span></pre>
172
+ <table class='report'> <thead> <tr> <td class='heading'> Name </td> <td
173
+ class='heading'> Total lines </td> <td class='heading'> Lines of code </td>
174
+ <td class='heading'> Total coverage </td> <td class='heading'> Code coverage
175
+ </td> </tr> </thead> <tbody> <tr class='light'> <td> <a
176
+ href='lib-tokenizer_rb.html'> lib/tokenizer.rb </a> </td> <td
177
+ class='lines_total'> <tt> 121 </tt> </td> <td class='lines_code'> <tt> 63
178
+ </tt> </td> <td> <table cellspacing='0' align='right' cellpadding='0'> <tr>
179
+ <td> <tt class='coverage_total'> 100.0% </tt> &nbsp; </td> <td> <table
180
+ class='percent_graph' cellspacing='0' width='100' cellpadding='0'> <tr> <td
181
+ class='covered' width='100' /> <td class='uncovered' width='0' /> </tr>
182
+ </table> </td> </tr> </table> </td> <td> <table cellspacing='0'
183
+ align='right' cellpadding='0'> <tr> <td> <tt class='coverage_code'> 100.0%
184
+ </tt> &nbsp; </td> <td> <table class='percent_graph' cellspacing='0'
185
+ width='100' cellpadding='0'> <tr> <td class='covered' width='100' /> <td
186
+ class='uncovered' width='0' /> </tr> </table> </td> </tr> </table> </td>
187
+ </tr> </tbody> </table><pre><span class="marked1"><a name="line1"></a> 1
188
+ module KingTokens </span><span class="inferred0"><a name="line2"></a> 2 #
189
+ Module which adds the token methods to the including class </span><span
190
+ class="marked1"><a name="line3"></a> 3 module Tokenizer </span><span
191
+ class="inferred0"><a name="line4"></a> 4 </span><span class="marked1"><a
192
+ name="line5"></a> 5 def self.included(base) </span><span class="marked0"><a
193
+ name="line6"></a> 6 base.extend(ClassMethods) </span><span
194
+ class="inferred1"><a name="line7"></a> 7 end </span><span
195
+ class="inferred0"><a name="line8"></a> 8 </span><span class="marked1"><a
196
+ name="line9"></a> 9 module ClassMethods </span><span class="inferred0"><a
197
+ name="line10"></a> 10 </span><span class="inferred1"><a name="line11"></a>
198
+ 11 # Define what kind of tokens the class should have </span><span
199
+ class="inferred0"><a name="line12"></a> 12 # ==== Parameter </span><span
200
+ class="inferred1"><a name="line13"></a> 13 # *tokens </span><span
201
+ class="marked0"><a name="line14"></a> 14 def can_has_tokens(*tokens)
202
+ </span><span class="marked1"><a name="line15"></a> 15 options =
203
+ tokens.extract_options! </span><span class="marked0"><a name="line16"></a>
204
+ 16 options[:tokens] = tokens </span><span class="marked1"><a
205
+ name="line17"></a> 17 options[:days_valid] ||= 5 </span><span
206
+ class="marked0"><a name="line18"></a> 18 options[:object_type] =
207
+ ActiveRecord::Base.send(:class_name_of_active_record_descendant, self).to_s
208
+ </span><span class="inferred1"><a name="line19"></a> 19 </span><span
209
+ class="marked0"><a name="line20"></a> 20 class_inheritable_accessor
210
+ :can_has_tokens_options </span><span class="marked1"><a name="line21"></a>
211
+ 21 self.can_has_tokens_options = options </span><span class="inferred0"><a
212
+ name="line22"></a> 22 </span><span class="marked1"><a name="line23"></a> 23
213
+ has_many :token_codes, :as =&gt; :object, :dependent =&gt; :destroy
214
+ </span><span class="inferred0"><a name="line24"></a> 24 </span><span
215
+ class="marked1"><a name="line25"></a> 25 extend
216
+ KingTokens::Tokenizer::SingletonMethods </span><span class="marked0"><a
217
+ name="line26"></a> 26 include KingTokens::Tokenizer::InstanceMethods
218
+ </span><span class="inferred1"><a name="line27"></a> 27 # define
219
+ getter/setter methods for each defined token </span><span class="marked0"><a
220
+ name="line28"></a> 28 tokens.each do |name| </span><span class="marked1"><a
221
+ name="line29"></a> 29 define_method(&quot;#{name}_token&quot;) do
222
+ </span><span class="marked0"><a name="line30"></a> 30 token =
223
+ self.token(name) </span><span class="marked1"><a name="line31"></a> 31
224
+ return token.token if token </span><span class="inferred0"><a
225
+ name="line32"></a> 32 end </span><span class="marked1"><a name="line33"></a>
226
+ 33 define_method(&quot;get_#{name}_token&quot;) do </span><span
227
+ class="marked0"><a name="line34"></a> 34 self.token(name) </span><span
228
+ class="inferred1"><a name="line35"></a> 35 end </span><span
229
+ class="marked0"><a name="line36"></a> 36
230
+ define_method(&quot;set_#{name}_token&quot;) do |*args| </span><span
231
+ class="marked1"><a name="line37"></a> 37 options = args.first || {}
232
+ </span><span class="marked0"><a name="line38"></a> 38
233
+ create_token(name,options) </span><span class="inferred1"><a
234
+ name="line39"></a> 39 end </span><span class="marked0"><a name="line40"></a>
235
+ 40 define_method(&quot;#{name}_token?&quot;) do </span><span
236
+ class="marked1"><a name="line41"></a> 41 return !self.token(name).nil?
237
+ </span><span class="inferred0"><a name="line42"></a> 42 end </span><span
238
+ class="inferred1"><a name="line43"></a> 43 end </span><span
239
+ class="inferred0"><a name="line44"></a> 44 end </span><span
240
+ class="inferred1"><a name="line45"></a> 45 </span><span class="inferred0"><a
241
+ name="line46"></a> 46 end </span><span class="inferred1"><a
242
+ name="line47"></a> 47 </span><span class="marked0"><a name="line48"></a> 48
243
+ module SingletonMethods </span><span class="inferred1"><a name="line49"></a>
244
+ 49 </span><span class="inferred0"><a name="line50"></a> 50 # Find a token.
245
+ </span><span class="inferred1"><a name="line51"></a> 51 # </span><span
246
+ class="inferred0"><a name="line52"></a> 52 # ==== Parameter </span><span
247
+ class="inferred1"><a name="line53"></a> 53 # args&lt;Hash{Symbol=&gt;}&gt;::
248
+ arguments passed to the conditions of the TokenCode.find method </span><span
249
+ class="inferred0"><a name="line54"></a> 54 # ==== Options (args)
250
+ </span><span class="inferred1"><a name="line55"></a> 55 #
251
+ :object_type&lt;String&gt;:: the name of the object tpye, normally the class
252
+ name of the related object </span><span class="inferred0"><a
253
+ name="line56"></a> 56 # </span><span class="inferred1"><a name="line57"></a>
254
+ 57 # </span><span class="inferred0"><a name="line58"></a> 58 # ==== Returns
255
+ </span><span class="inferred1"><a name="line59"></a> 59 # Object:: the
256
+ object to which the token belongs </span><span class="marked0"><a
257
+ name="line60"></a> 60 def find_token(args={}) </span><span
258
+ class="marked1"><a name="line61"></a> 61 args.merge!({:object_type =&gt;
259
+ can_has_tokens_options[:object_type]}) </span><span class="marked0"><a
260
+ name="line62"></a> 62 TokenCode.find(:first, :conditions =&gt; args)
261
+ </span><span class="inferred1"><a name="line63"></a> 63 end </span><span
262
+ class="inferred0"><a name="line64"></a> 64 </span><span class="inferred1"><a
263
+ name="line65"></a> 65 # Find an object by its token. </span><span
264
+ class="inferred0"><a name="line66"></a> 66 # </span><span
265
+ class="inferred1"><a name="line67"></a> 67 # ==== Parameter </span><span
266
+ class="inferred0"><a name="line68"></a> 68 # name&lt;String&gt;:: the name
267
+ of the token </span><span class="inferred1"><a name="line69"></a> 69 #
268
+ token&lt;String&gt;:: the token </span><span class="inferred0"><a
269
+ name="line70"></a> 70 # </span><span class="inferred1"><a name="line71"></a>
270
+ 71 # ==== Returns </span><span class="inferred0"><a name="line72"></a> 72 #
271
+ Object:: the object to which the token belongs </span><span
272
+ class="marked1"><a name="line73"></a> 73 def find_by_token(name,token)
273
+ </span><span class="marked0"><a name="line74"></a> 74 token =
274
+ find_token(:name =&gt; &quot;#{name}&quot;, :token =&gt; token) </span><span
275
+ class="marked1"><a name="line75"></a> 75 token.object if token </span><span
276
+ class="inferred0"><a name="line76"></a> 76 end </span><span
277
+ class="inferred1"><a name="line77"></a> 77 </span><span class="inferred0"><a
278
+ name="line78"></a> 78 # Find an object by a valid token. </span><span
279
+ class="inferred1"><a name="line79"></a> 79 # </span><span
280
+ class="inferred0"><a name="line80"></a> 80 # ==== Parameter </span><span
281
+ class="inferred1"><a name="line81"></a> 81 # name&lt;String&gt;:: the name
282
+ of the token </span><span class="inferred0"><a name="line82"></a> 82 #
283
+ token&lt;String&gt;:: the token </span><span class="inferred1"><a
284
+ name="line83"></a> 83 # </span><span class="inferred0"><a name="line84"></a>
285
+ 84 # ==== Returns </span><span class="inferred1"><a name="line85"></a> 85 #
286
+ Object:: the object to which the token belongs </span><span
287
+ class="marked0"><a name="line86"></a> 86 def find_by_valid_token(name,
288
+ token) </span><span class="marked1"><a name="line87"></a> 87 token =
289
+ find_token(:name =&gt; &quot;#{name}&quot;, :token =&gt; token) </span><span
290
+ class="marked0"><a name="line88"></a> 88 return token.object if token
291
+ &amp;&amp; token.valid_for_use? </span><span class="inferred1"><a
292
+ name="line89"></a> 89 end </span><span class="inferred0"><a
293
+ name="line90"></a> 90 end </span><span class="inferred1"><a
294
+ name="line91"></a> 91 </span><span class="marked0"><a name="line92"></a> 92
295
+ module InstanceMethods </span><span class="inferred1"><a name="line93"></a>
296
+ 93 # Create a token </span><span class="inferred0"><a name="line94"></a> 94
297
+ # ==== Parameter </span><span class="inferred1"><a name="line95"></a> 95 #
298
+ name&lt;String&gt;:: the name of the token .. required </span><span
299
+ class="inferred0"><a name="line96"></a> 96 #
300
+ args&lt;Hash{:Symbol=&gt;String}&gt;:: arguments for the create call of this
301
+ token. </span><span class="inferred1"><a name="line97"></a> 97 # ====
302
+ Options (args) </span><span class="inferred0"><a name="line98"></a> 98 #
303
+ :valid_until =&gt; </span><span class="inferred1"><a name="line99"></a> 99 #
304
+ :valid =&gt; </span><span class="inferred0"><a name="line100"></a>100 #
305
+ :days_valid =&gt; </span><span class="marked1"><a name="line101"></a>101 def
306
+ create_token(name, args={}) </span><span class="inferred0"><a
307
+ name="line102"></a>102 # find an existing token and delete it </span><span
308
+ class="marked1"><a name="line103"></a>103 unless self.token(name).nil?
309
+ </span><span class="marked0"><a name="line104"></a>104
310
+ self.token(name).destroy </span><span class="inferred1"><a
311
+ name="line105"></a>105 end </span><span class="marked0"><a
312
+ name="line106"></a>106 args[:name] = &quot;#{name}&quot; </span><span
313
+ class="marked1"><a name="line107"></a>107 args[:valid_until] ||=
314
+ (args.delete(:valid) ||
315
+ self.can_has_tokens_options[:days_valid].days).from_now </span><span
316
+ class="marked0"><a name="line108"></a>108 self.token_codes.create(args)
317
+ </span><span class="inferred1"><a name="line109"></a>109 end </span><span
318
+ class="inferred0"><a name="line110"></a>110 </span><span
319
+ class="inferred1"><a name="line111"></a>111 # Return a token found by its
320
+ name </span><span class="inferred0"><a name="line112"></a>112 # ====
321
+ Parameter </span><span class="inferred1"><a name="line113"></a>113 #
322
+ name&lt;String/Symbol&gt;:: The name of the token </span><span
323
+ class="marked0"><a name="line114"></a>114 def token(name) </span><span
324
+ class="marked1"><a name="line115"></a>115
325
+ self.token_codes.find_by_name(&quot;#{name}&quot;) </span><span
326
+ class="inferred0"><a name="line116"></a>116 end </span><span
327
+ class="inferred1"><a name="line117"></a>117 </span><span
328
+ class="inferred0"><a name="line118"></a>118 end </span><span
329
+ class="inferred1"><a name="line119"></a>119 </span><span
330
+ class="inferred0"><a name="line120"></a>120 end #module </span><span
331
+ class="inferred1"><a name="line121"></a>121 end # namespace </span></pre>
332
+ <hr />
333
+ <p> Generated using the <a href='http://eigenclass.org/hiki.rb?rcov'> rcov
334
+ code coverage analysis tool for Ruby </a> version 0.8.1.2. </p>
335
+ <p>
336
+ <a href='http://validator.w3.org/check/referer'>
337
+ <img src='http://www.w3.org/Icons/valid-xhtml10' height='31' alt='Valid XHTML 1.0!' width='88' />
338
+ </a>
339
+ <a href='http://jigsaw.w3.org/css-validator/check/referer'>
340
+ <img src='http://jigsaw.w3.org/css-validator/images/vcss' alt='Valid CSS!' style='border:0;width:88px;height:31px' />
341
+ </a>
342
+ </p>
343
+ </body>
344
+ </html>
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require "#{File.dirname(__FILE__)}/lib/king_tokens"
@@ -0,0 +1,81 @@
1
+ require "digest/sha1"
2
+
3
+ # Class to handle polymorphic tokens
4
+ class TokenCode < ActiveRecord::Base
5
+
6
+ #In case someone is using uuids
7
+ usesguid if defined?(usesguid)
8
+
9
+ belongs_to :object, :polymorphic => true
10
+ before_create :set_token
11
+
12
+ validates_presence_of :name
13
+ validates_format_of :name, :with => /^[a-zA-Z0-9\_\-]+$/
14
+ validates_uniqueness_of :name, :scope => [:object_id, :object_type] #second not really needed if uuid
15
+
16
+ def to_s
17
+ self.token
18
+ end
19
+
20
+ # Use a token for an object.
21
+ # Sets the used_at field
22
+ def use!
23
+ update_attribute(:used_at,Time.now)
24
+ end
25
+
26
+ # Revoke the usage of a token by emptying its used_at field
27
+ def unuse!
28
+ update_attribute(:used_at,nil)
29
+ end
30
+
31
+ # Check if the token has already been used
32
+ def used?
33
+ !! read_attribute(:used_at)
34
+ end
35
+
36
+ # Check if the token has expired
37
+ def expired?
38
+ valid_until && valid_until < Time.now
39
+ end
40
+
41
+ # A token is valid to be used if:
42
+ # - its has not been used
43
+ # - its not expired
44
+ # - its valid in terms of AR validation
45
+ def valid_for_use?
46
+ valid? && !used? && !expired?
47
+ end
48
+
49
+ # Delete all tokens which have been used
50
+ def self.delete_used
51
+ delete_all "used_at IS NOT NULL"
52
+ end
53
+
54
+ # Delete all tokens which are expired
55
+ def self.delete_expired
56
+ delete_all ["valid_until IS NOT NULL AND valid_until < ? ", Time.now]
57
+ end
58
+
59
+ private
60
+
61
+ # Generate a token with a default length of 12.
62
+ # Takes a block to validate the token, which should return true/false
63
+ # ==== Parameter
64
+ # size<Integer>:: The length of the token. Defaults to 40
65
+ # validity<Proc>:: A block to check the validity of the token, see #set_token for usage
66
+ def generate_token(size = 40, &validity)
67
+ begin
68
+ token = secure_digest(Time.now, "#{self.object_type}#{self.object_id}", (1..10).map{ rand.to_s }).first(size)
69
+ end while !validity.call(token) if block_given?
70
+ token
71
+ end
72
+
73
+ def secure_digest(*args)
74
+ Digest::SHA1.hexdigest(args.flatten.join('--'))
75
+ end
76
+
77
+ def set_token
78
+ self.token = generate_token { |token| TokenCode.find_by_token(token).nil? }
79
+ end
80
+
81
+ end
@@ -0,0 +1,121 @@
1
+ module KingTokens
2
+ # Module which adds the token methods to the including class
3
+ module Tokenizer
4
+
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+
11
+ # Define what kind of tokens the class should have
12
+ # ==== Parameter
13
+ # *tokens
14
+ def can_has_tokens(*tokens)
15
+ options = tokens.extract_options!
16
+ options[:tokens] = tokens
17
+ options[:days_valid] ||= 5
18
+ options[:object_type] = ActiveRecord::Base.send(:class_name_of_active_record_descendant, self).to_s
19
+
20
+ class_inheritable_accessor :can_has_tokens_options
21
+ self.can_has_tokens_options = options
22
+
23
+ has_many :token_codes, :as => :object, :dependent => :destroy
24
+
25
+ extend KingTokens::Tokenizer::SingletonMethods
26
+ include KingTokens::Tokenizer::InstanceMethods
27
+ # define getter/setter methods for each defined token
28
+ tokens.each do |name|
29
+ define_method("#{name}_token") do
30
+ token = self.token(name)
31
+ return token.token if token
32
+ end
33
+ define_method("get_#{name}_token") do
34
+ self.token(name)
35
+ end
36
+ define_method("set_#{name}_token") do |*args|
37
+ options = args.first || {}
38
+ create_token(name,options)
39
+ end
40
+ define_method("#{name}_token?") do
41
+ return !self.token(name).nil?
42
+ end
43
+ end
44
+ end
45
+
46
+ end
47
+
48
+ module SingletonMethods
49
+
50
+ # Find a token.
51
+ #
52
+ # ==== Parameter
53
+ # args<Hash{Symbol=>}>:: arguments passed to the conditions of the TokenCode.find method
54
+ # ==== Options (args)
55
+ # :object_type<String>:: the name of the object tpye, normally the class name of the related object
56
+ #
57
+ #
58
+ # ==== Returns
59
+ # Object:: the object to which the token belongs
60
+ def find_token(args={})
61
+ args.merge!({:object_type => can_has_tokens_options[:object_type]})
62
+ TokenCode.find(:first, :conditions => args)
63
+ end
64
+
65
+ # Find an object by its token.
66
+ #
67
+ # ==== Parameter
68
+ # name<String>:: the name of the token
69
+ # token<String>:: the token
70
+ #
71
+ # ==== Returns
72
+ # Object:: the object to which the token belongs
73
+ def find_by_token(name,token)
74
+ token = find_token(:name => "#{name}", :token => token)
75
+ token.object if token
76
+ end
77
+
78
+ # Find an object by a valid token.
79
+ #
80
+ # ==== Parameter
81
+ # name<String>:: the name of the token
82
+ # token<String>:: the token
83
+ #
84
+ # ==== Returns
85
+ # Object:: the object to which the token belongs
86
+ def find_by_valid_token(name, token)
87
+ token = find_token(:name => "#{name}", :token => token)
88
+ return token.object if token && token.valid_for_use?
89
+ end
90
+ end
91
+
92
+ module InstanceMethods
93
+ # Create a token
94
+ # ==== Parameter
95
+ # name<String>:: the name of the token .. required
96
+ # args<Hash{:Symbol=>String}>:: arguments for the create call of this token.
97
+ # ==== Options (args)
98
+ # :valid_until =>
99
+ # :valid =>
100
+ # :days_valid =>
101
+ def create_token(name, args={})
102
+ # find an existing token and delete it
103
+ unless self.token(name).nil?
104
+ self.token(name).destroy
105
+ end
106
+ args[:name] = "#{name}"
107
+ args[:valid_until] ||= (args.delete(:valid) || self.can_has_tokens_options[:days_valid].days).from_now
108
+ self.token_codes.create(args)
109
+ end
110
+
111
+ # Return a token found by its name
112
+ # ==== Parameter
113
+ # name<String/Symbol>:: The name of the token
114
+ def token(name)
115
+ self.token_codes.find_by_name("#{name}")
116
+ end
117
+
118
+ end
119
+
120
+ end #module
121
+ end # namespace