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.
data/.document ADDED
@@ -0,0 +1,3 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+ ## Netbeans
16
+ nbproject/*
17
+
18
+ ## PROJECT::GENERAL
19
+ rdoc
20
+ pkg
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 [name of plugin creator]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,87 @@
1
+ = KingTokens
2
+
3
+ Tokens are a usefull way to give users access to an application. This can be for a limited time or just once.
4
+ Just think of password resets, changing email, protected rss feed urls, timed out private links, .. KingTokens are your easy way out in such cases
5
+
6
+ This plugin consists of two parts:
7
+
8
+ * an ActiveRecord model class TokenCode, which maps to the token table in the db
9
+ * a module Tokenizer mixed into ActiveRecord::Base, providing your models with the possibility to define tokens
10
+
11
+ KingTokens map polymorphic to other objects, through the can_has_tokens :a_tokens_name call
12
+
13
+ == Install
14
+
15
+ Get it as gem (hosted on gemcutter.org)
16
+ gem install king_tokens
17
+
18
+ Or download it from github and use it as rails plugin
19
+
20
+ setup your token db like defined in the test schema => test/schema.rb
21
+
22
+ == Example
23
+
24
+ Define a token on a model
25
+ class User
26
+ can_has_tokens :forgot_password
27
+ end
28
+
29
+ Set and get a user by token in a controller
30
+ class UsersController
31
+ # form with email so user can send himself a password reset link
32
+ def lost_password
33
+ if request.post?
34
+ #create users forgot_password_token
35
+ @user.set_forgot_password_token
36
+ .....
37
+ end
38
+ end
39
+
40
+ # Lookup user by lost_pass_code, send him to his password_edit page
41
+ # params[:code] contains the forgot_passwd token
42
+ def change_password
43
+ # identify by forgot_password_token in params[:code]
44
+ user = User.find_by_valid_token(:forgot_password, params[:code])
45
+ #expire token
46
+ user.get_forgot_password_token.use!
47
+ ...
48
+ end
49
+ end
50
+
51
+ == Docs
52
+
53
+ To get a full understanding of the usage also read the tests. For QM you might check the coverage report in coverage/index.html
54
+
55
+ === Token definition inside an ActiveRecord object:
56
+
57
+ Add a token with the name forgot_pasword to an object.
58
+ can_has_tokens :forgot_password
59
+ A token with the name change email valid for 3 days
60
+ can_has_tokens :change_email, {:days_valid => 3}
61
+
62
+ === Instance methods added to the ActiveRecord object:
63
+ Set a new token and removing any existing one
64
+ user.set_forgot_password_token
65
+ Get the token string
66
+ user.forgot_password_token
67
+ Check if the user has such a token, returns boolean true
68
+ user.forgot_password_token?
69
+ Get the token object
70
+ user.get_forgot_password_token
71
+ Get the token object by name
72
+ user.token(:forgot_password)
73
+ Low level function to create a token with special options, overriding the ones set in the class definition
74
+ user.create_token(:token_name, :valid => 2.days.from_now)
75
+
76
+
77
+ === Class methods
78
+
79
+ Find a user by a specific token which must be valid
80
+ User.find_by_valid_token(:token_name, 'a token string')
81
+ Find a user by specific token, without valid check
82
+ User.find_by_token(:forgot_password, 'a token string')
83
+
84
+ User.find_token
85
+
86
+
87
+ Copyright (c) 2008-2010 Michael Bumann, Georg Leciejewski released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,40 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+
6
+ begin
7
+ require 'jeweler'
8
+ Jeweler::Tasks.new do |gem|
9
+ gem.name = "king_tokens"
10
+ gem.summary = %Q{Access tokens for any active record object}
11
+ gem.description = %Q{Tokens are a usefull way to give users access to an application. This can be for a limited time or just once. Just think of password resets, changing email, protected rss feed urls, timed out private links}
12
+ gem.email = "gl@salesking.eu"
13
+ gem.homepage = "http://github.com/schorsch/king_tokens"
14
+ gem.authors = ["Georg Leciejewski"]
15
+ gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
16
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
17
+ end
18
+ Jeweler::GemcutterTasks.new
19
+ rescue LoadError
20
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
21
+ end
22
+
23
+ desc 'Default: run unit tests.'
24
+ task :default => :test
25
+
26
+ desc 'Test the tokenizer plugin.'
27
+ Rake::TestTask.new(:test) do |t|
28
+ t.libs << 'lib'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = true
31
+ end
32
+
33
+ desc 'Generate documentation for the tokenizer plugin.'
34
+ Rake::RDocTask.new(:rdoc) do |rdoc|
35
+ rdoc.rdoc_dir = 'rdoc'
36
+ rdoc.title = 'KingTokens'
37
+ rdoc.options << '--line-numbers' << '--inline-source'
38
+ rdoc.rdoc_files.include('README')
39
+ rdoc.rdoc_files.include('lib/**/*.rb')
40
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,112 @@
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
+ 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
+ </head>
51
+ <body>
52
+ <h3>
53
+ C0 code coverage information
54
+ </h3>
55
+ <p>
56
+ Generated on Sun Dec 07 02:06:42 +0100 2008 with
57
+ <a href='http://eigenclass.org/hiki/rcov'>
58
+ rcov 0.8.1.2
59
+ </a>
60
+ </p>
61
+ <hr />
62
+ <table class='report'> <thead> <tr> <td class='heading'> Name </td> <td
63
+ class='heading'> Total lines </td> <td class='heading'> Lines of code </td>
64
+ <td class='heading'> Total coverage </td> <td class='heading'> Code coverage
65
+ </td> </tr> </thead> <tbody> <tr class='light'> <td> TOTAL </td> <td
66
+ class='lines_total'> <tt> 201 </tt> </td> <td class='lines_code'> <tt> 109
67
+ </tt> </td> <td> <table cellspacing='0' align='right' cellpadding='0'> <tr>
68
+ <td> <tt class='coverage_total'> 100.0% </tt> &nbsp; </td> <td> <table
69
+ class='percent_graph' cellspacing='0' width='100' cellpadding='0'> <tr> <td
70
+ class='covered' width='100' /> <td class='uncovered' width='0' /> </tr>
71
+ </table> </td> </tr> </table> </td> <td> <table cellspacing='0'
72
+ align='right' cellpadding='0'> <tr> <td> <tt class='coverage_code'> 100.0%
73
+ </tt> &nbsp; </td> <td> <table class='percent_graph' cellspacing='0'
74
+ width='100' cellpadding='0'> <tr> <td class='covered' width='100' /> <td
75
+ class='uncovered' width='0' /> </tr> </table> </td> </tr> </table> </td>
76
+ </tr> <tr class='dark'> <td> <a href='lib-token_code_rb.html'>
77
+ lib/token_code.rb </a> </td> <td class='lines_total'> <tt> 80 </tt> </td>
78
+ <td class='lines_code'> <tt> 46 </tt> </td> <td> <table cellspacing='0'
79
+ align='right' cellpadding='0'> <tr> <td> <tt class='coverage_total'> 100.0%
80
+ </tt> &nbsp; </td> <td> <table class='percent_graph' cellspacing='0'
81
+ width='100' cellpadding='0'> <tr> <td class='covered' width='100' /> <td
82
+ class='uncovered' width='0' /> </tr> </table> </td> </tr> </table> </td>
83
+ <td> <table cellspacing='0' align='right' cellpadding='0'> <tr> <td> <tt
84
+ class='coverage_code'> 100.0% </tt> &nbsp; </td> <td> <table
85
+ class='percent_graph' cellspacing='0' width='100' cellpadding='0'> <tr> <td
86
+ class='covered' width='100' /> <td class='uncovered' width='0' /> </tr>
87
+ </table> </td> </tr> </table> </td> </tr> <tr class='light'> <td> <a
88
+ href='lib-tokenizer_rb.html'> lib/tokenizer.rb </a> </td> <td
89
+ class='lines_total'> <tt> 121 </tt> </td> <td class='lines_code'> <tt> 63
90
+ </tt> </td> <td> <table cellspacing='0' align='right' cellpadding='0'> <tr>
91
+ <td> <tt class='coverage_total'> 100.0% </tt> &nbsp; </td> <td> <table
92
+ class='percent_graph' cellspacing='0' width='100' cellpadding='0'> <tr> <td
93
+ class='covered' width='100' /> <td class='uncovered' width='0' /> </tr>
94
+ </table> </td> </tr> </table> </td> <td> <table cellspacing='0'
95
+ align='right' cellpadding='0'> <tr> <td> <tt class='coverage_code'> 100.0%
96
+ </tt> &nbsp; </td> <td> <table class='percent_graph' cellspacing='0'
97
+ width='100' cellpadding='0'> <tr> <td class='covered' width='100' /> <td
98
+ class='uncovered' width='0' /> </tr> </table> </td> </tr> </table> </td>
99
+ </tr> </tbody> </table>
100
+ <hr />
101
+ <p> Generated using the <a href='http://eigenclass.org/hiki.rb?rcov'> rcov
102
+ code coverage analysis tool for Ruby </a> version 0.8.1.2. </p>
103
+ <p>
104
+ <a href='http://validator.w3.org/check/referer'>
105
+ <img src='http://www.w3.org/Icons/valid-xhtml11' height='31' alt='Valid XHTML 1.1!' width='88' />
106
+ </a>
107
+ <a href='http://jigsaw.w3.org/css-validator/check/referer'>
108
+ <img src='http://jigsaw.w3.org/css-validator/images/vcss' alt='Valid CSS!' style='border:0;width:88px;height:31px' />
109
+ </a>
110
+ </p>
111
+ </body>
112
+ </html>
@@ -0,0 +1,290 @@
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/token_code.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-token_code_rb.html'> lib/token_code.rb </a> </td> <td
177
+ class='lines_total'> <tt> 80 </tt> </td> <td class='lines_code'> <tt> 46
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
+ require &quot;digest/sha1&quot; </span><span class="inferred0"><a
189
+ name="line2"></a> 2 </span><span class="inferred1"><a name="line3"></a> 3 #
190
+ Class to handle polymorphic tokens </span><span class="marked0"><a
191
+ name="line4"></a> 4 class TokenCode &lt; ActiveRecord::Base </span><span
192
+ class="inferred1"><a name="line5"></a> 5 </span><span class="inferred0"><a
193
+ name="line6"></a> 6 # kick this stament if you dont uses uuids .. or better
194
+ we make a check?? </span><span class="inferred1"><a name="line7"></a> 7
195
+ </span><span class="marked0"><a name="line8"></a> 8 usesguid if
196
+ defined?(usesguid) </span><span class="inferred1"><a name="line9"></a> 9
197
+ </span><span class="marked0"><a name="line10"></a>10 belongs_to :object,
198
+ :polymorphic =&gt; true </span><span class="marked1"><a name="line11"></a>11
199
+ before_create :set_token </span><span class="inferred0"><a
200
+ name="line12"></a>12 </span><span class="marked1"><a name="line13"></a>13
201
+ validates_presence_of :name </span><span class="marked0"><a
202
+ name="line14"></a>14 validates_format_of :name, :with =&gt;
203
+ /^[a-zA-Z0-9\_\-]+$/ </span><span class="marked1"><a name="line15"></a>15
204
+ validates_uniqueness_of :name, :scope =&gt; [:object_id, :object_type]
205
+ #second not really needed if uuid </span><span class="inferred0"><a
206
+ name="line16"></a>16 </span><span class="marked1"><a name="line17"></a>17
207
+ def to_s </span><span class="marked0"><a name="line18"></a>18 self.token
208
+ </span><span class="inferred1"><a name="line19"></a>19 end </span><span
209
+ class="inferred0"><a name="line20"></a>20 </span><span class="inferred1"><a
210
+ name="line21"></a>21 # Use a token for an object. </span><span
211
+ class="inferred0"><a name="line22"></a>22 # Sets the used_at field
212
+ </span><span class="marked1"><a name="line23"></a>23 def use! </span><span
213
+ class="marked0"><a name="line24"></a>24 update_attribute(:used_at,Time.now)
214
+ </span><span class="inferred1"><a name="line25"></a>25 end </span><span
215
+ class="inferred0"><a name="line26"></a>26 </span><span class="inferred1"><a
216
+ name="line27"></a>27 # Revoke the usage of a token by emptying its used_at
217
+ field </span><span class="marked0"><a name="line28"></a>28 def unuse!
218
+ </span><span class="marked1"><a name="line29"></a>29
219
+ update_attribute(:used_at,nil) </span><span class="inferred0"><a
220
+ name="line30"></a>30 end </span><span class="inferred1"><a
221
+ name="line31"></a>31 </span><span class="marked0"><a name="line32"></a>32
222
+ def used? </span><span class="marked1"><a name="line33"></a>33 !!
223
+ read_attribute(:used_at) </span><span class="inferred0"><a
224
+ name="line34"></a>34 end </span><span class="inferred1"><a
225
+ name="line35"></a>35 </span><span class="inferred0"><a name="line36"></a>36
226
+ # Check if the token has expired </span><span class="marked1"><a
227
+ name="line37"></a>37 def expired? </span><span class="marked0"><a
228
+ name="line38"></a>38 valid_until &amp;&amp; valid_until &lt; Time.now
229
+ </span><span class="inferred1"><a name="line39"></a>39 end </span><span
230
+ class="inferred0"><a name="line40"></a>40 </span><span class="inferred1"><a
231
+ name="line41"></a>41 # A token is valid to be used if: </span><span
232
+ class="inferred0"><a name="line42"></a>42 # - its has not been used
233
+ </span><span class="inferred1"><a name="line43"></a>43 # - its not expired
234
+ </span><span class="inferred0"><a name="line44"></a>44 # - its valid in
235
+ terms of AR validation </span><span class="marked1"><a name="line45"></a>45
236
+ def valid_for_use? </span><span class="marked0"><a name="line46"></a>46
237
+ valid? &amp;&amp; !used? &amp;&amp; !expired? </span><span
238
+ class="inferred1"><a name="line47"></a>47 end </span><span
239
+ class="inferred0"><a name="line48"></a>48 </span><span class="inferred1"><a
240
+ name="line49"></a>49 </span><span class="marked0"><a name="line50"></a>50
241
+ def self.delete_used </span><span class="marked1"><a name="line51"></a>51
242
+ delete_all &quot;used_at IS NOT NULL&quot; </span><span class="inferred0"><a
243
+ name="line52"></a>52 end </span><span class="inferred1"><a
244
+ name="line53"></a>53 </span><span class="marked0"><a name="line54"></a>54
245
+ def self.delete_expired </span><span class="marked1"><a name="line55"></a>55
246
+ delete_all [&quot;valid_until IS NOT NULL AND valid_until &lt; ? &quot;,
247
+ Time.now] </span><span class="inferred0"><a name="line56"></a>56 end
248
+ </span><span class="inferred1"><a name="line57"></a>57 </span><span
249
+ class="marked0"><a name="line58"></a>58 private </span><span
250
+ class="inferred1"><a name="line59"></a>59 </span><span class="inferred0"><a
251
+ name="line60"></a>60 # Generate a token with a default length of 12.
252
+ </span><span class="inferred1"><a name="line61"></a>61 # Takes a block to
253
+ validate the token, which should return true/false </span><span
254
+ class="inferred0"><a name="line62"></a>62 # ==== Parameter </span><span
255
+ class="inferred1"><a name="line63"></a>63 # size&lt;Integer&gt;:: The length
256
+ of the token. Defaults to 40 </span><span class="inferred0"><a
257
+ name="line64"></a>64 # validity&lt;Proc&gt;:: A block to check the validity
258
+ of the token, see #set_token for usage </span><span class="marked1"><a
259
+ name="line65"></a>65 def generate_token(size = 40, &amp;validity)
260
+ </span><span class="inferred0"><a name="line66"></a>66 begin </span><span
261
+ class="marked1"><a name="line67"></a>67 token = secure_digest(Time.now,
262
+ &quot;#{self.object_type}#{self.object_id}&quot;, (1..10).map{ rand.to_s
263
+ }).first(size) </span><span class="marked0"><a name="line68"></a>68 end
264
+ while !validity.call(token) if block_given? </span><span class="marked1"><a
265
+ name="line69"></a>69 token </span><span class="inferred0"><a
266
+ name="line70"></a>70 end </span><span class="inferred1"><a
267
+ name="line71"></a>71 </span><span class="marked0"><a name="line72"></a>72
268
+ def secure_digest(*args) </span><span class="marked1"><a
269
+ name="line73"></a>73 Digest::SHA1.hexdigest(args.flatten.join('--'))
270
+ </span><span class="inferred0"><a name="line74"></a>74 end </span><span
271
+ class="inferred1"><a name="line75"></a>75 </span><span class="marked0"><a
272
+ name="line76"></a>76 def set_token </span><span class="marked1"><a
273
+ name="line77"></a>77 self.token = generate_token { |token|
274
+ TokenCode.find_by_token(token).nil? } </span><span class="inferred0"><a
275
+ name="line78"></a>78 end </span><span class="inferred1"><a
276
+ name="line79"></a>79 </span><span class="inferred0"><a name="line80"></a>80
277
+ end </span></pre>
278
+ <hr />
279
+ <p> Generated using the <a href='http://eigenclass.org/hiki.rb?rcov'> rcov
280
+ code coverage analysis tool for Ruby </a> version 0.8.1.2. </p>
281
+ <p>
282
+ <a href='http://validator.w3.org/check/referer'>
283
+ <img src='http://www.w3.org/Icons/valid-xhtml10' height='31' alt='Valid XHTML 1.0!' width='88' />
284
+ </a>
285
+ <a href='http://jigsaw.w3.org/css-validator/check/referer'>
286
+ <img src='http://jigsaw.w3.org/css-validator/images/vcss' alt='Valid CSS!' style='border:0;width:88px;height:31px' />
287
+ </a>
288
+ </p>
289
+ </body>
290
+ </html>