session_countdown 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.html ADDED
@@ -0,0 +1,191 @@
1
+
2
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
3
+ <html>
4
+ <head>
5
+ <title>RDoc Documentation</title>
6
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
7
+ </head>
8
+ <body>
9
+ <h2>File: README.rdoc</h2>
10
+ <table>
11
+ <tr><td>Path:</td><td>README.rdoc</td></tr>
12
+ <tr><td>Modified:</td><td>Fri Aug 06 06:53:51 -0400 2010</td></tr>
13
+ </table>
14
+
15
+ <h1>session_countdown</h1>
16
+ <p>
17
+ A Ruby on Rails plugin that puts a countdown timer on the session object.
18
+ </p>
19
+ <pre>
20
+ session.countdown_run(30.minutes)
21
+ session.countdown_running? # =&gt; true
22
+ session.countdown_expire
23
+ session.countdown_running? # =&gt; false
24
+ session.countdown_expired? # =&gt; true
25
+ session.countdown_restart
26
+ session.countdown_running? # =&gt; true
27
+ </pre>
28
+ <h3>But why?!?</h3>
29
+ <p>
30
+ Sometimes I need to build my own custom rails authentication systems rather
31
+ than use plugins such as Authlogic, Devise or restful_authentication.
32
+ </p>
33
+ <p>
34
+ There is always a &quot;timer&quot; in my custom authentication
35
+ contraptions, and there is always a session object lurking when I&#8216;m
36
+ dealing with authentication stuff, so why not combine the two?
37
+ </p>
38
+ <h2>API</h2>
39
+ <p>
40
+ <em>Note that countdown_expire(), countdown_restart() and countdown_count()
41
+ will throw a NoCountdown exception if called on a non-existent countdown
42
+ timer.</em>
43
+ </p>
44
+ <p>
45
+ Start a countdown timer
46
+ </p>
47
+ <pre>
48
+ session.countdown_run(seconds, name = :default)
49
+ </pre>
50
+ <p>
51
+ <em>You can have multiple countdown timers if you name them. The default
52
+ countdown timer is named &quot;default&quot;.</em>
53
+ </p>
54
+ <p>
55
+ Check if a countdown timer exists and is currently running
56
+ </p>
57
+ <pre>
58
+ session.countdown_running?(name = :default)
59
+ </pre>
60
+ <p>
61
+ Expire early (i.e. logout)
62
+ </p>
63
+ <pre>
64
+ session.countdown_expire(name = :default)
65
+ </pre>
66
+ <p>
67
+ Restart, using the duration supplied to countdown_run
68
+ </p>
69
+ <pre>
70
+ session.countdown_restart(name = :default)
71
+ </pre>
72
+ <p>
73
+ Check if expired
74
+ </p>
75
+ <pre>
76
+ session.countdown_expired?(name = :default)
77
+ </pre>
78
+ <p>
79
+ Remaining time in seconds
80
+ </p>
81
+ <pre>
82
+ session.countdown_count(name = :default)
83
+ </pre>
84
+ <p>
85
+ Understanding timer running, expired, and never started
86
+ </p>
87
+ <pre>
88
+ countdown_running? == true # timer running
89
+ countdown_expired? == true # timer expired
90
+ countdown_running? == false &amp;&amp; countdown_expired? == false # never ran
91
+ </pre>
92
+ <h1>Synopsis</h1>
93
+ <h3>In application_controller.rb</h3>
94
+ <pre>
95
+ before_filter :authorize
96
+
97
+ def authorize
98
+ if session.countdown_running?
99
+ session.countdown_restart # extend user's login
100
+ else
101
+ # store attempted access before rudely redirected to login screen
102
+ session[:original_uri] = request.request_uri # rails3 use request.fullpath
103
+ if session.countdown_expired?
104
+ flash[:notice] = &quot;Login Expired&quot;
105
+ else
106
+ flash[:notice] = &quot;Please login&quot;
107
+ end
108
+ redirect_to :login
109
+ end
110
+ end
111
+ </pre>
112
+ <h3>In any controller</h3>
113
+ <pre>
114
+ def login
115
+ user = User.find_by_email(params[:email)
116
+ if user &amp;&amp; user.password_matches?(params[:password])
117
+ session.countdown_run(1.hour)
118
+ redirect_to :controller =&gt; :private
119
+ else
120
+ flash.now[:notice] = &quot;Sorry, email/password wrong&quot;
121
+ render :index
122
+ end
123
+
124
+ end
125
+
126
+ def logout
127
+ session.countdown_expire
128
+ flash[:notice] = &quot;You are now logged out&quot;
129
+ redirect_to :index
130
+ end
131
+ </pre>
132
+ <h3>In user model</h3>
133
+ <pre>
134
+ def before_save
135
+ if self.password_changed?
136
+ self.salt = SecureRandom.hex(10)
137
+ self.password = Digest::MD5.hexdigest(self.salt + self.password)
138
+ end
139
+ end
140
+
141
+ def password_matches?(password_to_match)
142
+ self.password == Digest::MD5.hexdigest(self.salt + password_to_match)
143
+ end
144
+ </pre>
145
+ <h3>Note: Remember me</h3>
146
+ <p>
147
+ If you want an &quot;remember me&quot; feature you need to do two things.
148
+ </p>
149
+ <p>
150
+ Set timer for far future when user checks &quot;remember me&quot;
151
+ </p>
152
+ <pre>
153
+ session.countdown_run(1.year)
154
+ </pre>
155
+ <p>
156
+ Tell rails to serve up a persistent cookie instead of session cookie,
157
+ probably in application_controller.rb
158
+ </p>
159
+ <pre>
160
+ ActionController::Base.session_options[:expire_after] = 1.year
161
+ </pre>
162
+ <h3>Persistent vs session cookies</h3>
163
+ <p>
164
+ There are two types of browser cookies: ones with expiration dates and ones
165
+ without. When a cookie doesnt have an expiration date it&#8216;s a
166
+ <em>session</em> cookie and will be deleted when the browser quits. If the
167
+ cookie has an expiration date it&#8216;s a <em>persistent</em> cookie
168
+ (a.k.a. domain cookie) and will be valid until that date.
169
+ </p>
170
+ <p>
171
+ &quot;Remember me&quot; could work fine with only session cookies, provided
172
+ the user never quits the browser, but users expect &quot;remember me&quot;
173
+ to never expire their login <em>and</em> to persist across browser quits.
174
+ It also makes sense to set a far future expiration date or the cookie will
175
+ eventually expire before the login does.
176
+ </p>
177
+
178
+
179
+
180
+
181
+
182
+
183
+
184
+ <h2>Classes</h2>
185
+ </body>
186
+ </html>
187
+ Files: 1
188
+ Classes: 0
189
+ Modules: 0
190
+ Methods: 0
191
+ Elapsed: 0.048s
data/README.rdoc CHANGED
@@ -26,11 +26,10 @@ authentication stuff, so why not combine the two?
26
26
  == API
27
27
 
28
28
 
29
- <i>Note that except for countdown_run() and countdown_running?() all
30
- the public methods will throw a NoCountdown exception if called on a
29
+ <i>Note that countdown_expire(), countdown_restart() and
30
+ countdown_count() will throw a NoCountdown exception if called on a
31
31
  non-existent countdown timer.</i>
32
32
 
33
-
34
33
  Start a countdown timer
35
34
 
36
35
  session.countdown_run(seconds, name = :default)
@@ -42,7 +41,7 @@ Check if a countdown timer exists and is currently running
42
41
 
43
42
  session.countdown_running?(name = :default)
44
43
 
45
- Expire early
44
+ Expire early (i.e. logout)
46
45
 
47
46
  session.countdown_expire(name = :default)
48
47
 
@@ -54,17 +53,16 @@ Check if expired
54
53
 
55
54
  session.countdown_expired?(name = :default)
56
55
 
57
- <i>countdown_expired? is not the reverse of countdown_running?
58
- because only works on an existing countdown, otherwise it will throw a
59
- NoCountdown exception. Its use will reveal only if an existing
60
- countdown is expired. The statement !countdown_running? can't tell
61
- you if the countdown has expired because it will return true if there
62
- was no countdown in the first place.</i>
63
-
64
56
  Remaining time in seconds
65
57
 
66
58
  session.countdown_count(name = :default)
67
59
 
60
+ Understanding timer running, expired, and never started
61
+
62
+ countdown_running? == true # timer running
63
+ countdown_expired? == true # timer expired
64
+ countdown_running? == false && countdown_expired? == false # never ran
65
+
68
66
 
69
67
  = Synopsis
70
68
 
@@ -72,13 +70,17 @@ Remaining time in seconds
72
70
 
73
71
  before_filter :authorize
74
72
 
75
-
76
73
  def authorize
77
74
  if session.countdown_running?
78
- session.countdown_restart # give user more time
75
+ session.countdown_restart # extend user's login
79
76
  else
80
- session[:original_uri] = request.request_uri
81
- flash[:notice] = session.countdown_expired? ? "Login Expired" : "Please login"
77
+ # store attempted access before rudely redirected to login screen
78
+ session[:original_uri] = request.request_uri # rails3 use request.fullpath
79
+ if session.countdown_expired?
80
+ flash[:notice] = "Login Expired"
81
+ else
82
+ flash[:notice] = "Please login"
83
+ end
82
84
  redirect_to :login
83
85
  end
84
86
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
@@ -17,9 +17,13 @@ module SessionCountdown
17
17
  self[get_zero_key(name)] && self[get_zero_key(name)] > Time.now
18
18
  end
19
19
 
20
+ def countdown_expired?(name = @@default_name)
21
+ self[get_zero_key(name)] && ! countdown_running?(name)
22
+ end
23
+
20
24
  # sanity check for existing countdown for some methods
21
25
  def method_missing(method, *args)
22
- check_countdown_exists(*args) # reason for this method_missing()
26
+ insist_countdown_exists(*args) # reason for this method_missing()
23
27
  method = "_#{method}"
24
28
  respond_to?(method) ? send(method, *args) : raise(NoMethodError)
25
29
  end
@@ -30,10 +34,6 @@ module SessionCountdown
30
34
  self[get_zero_key(name)] = Time.now
31
35
  end
32
36
 
33
- def _countdown_expired?(name = @@default_name)
34
- ! countdown_running?(name)
35
- end
36
-
37
37
  def _countdown_restart(name = @@default_name)
38
38
  self[get_zero_key(name)] = Time.now + self[get_zero_delta_key(name)]
39
39
  end
@@ -55,7 +55,7 @@ module SessionCountdown
55
55
  "session_countdown:#{name}_delta"
56
56
  end
57
57
 
58
- def check_countdown_exists(name = @@default_name)
58
+ def insist_countdown_exists(name = @@default_name)
59
59
  unless self[get_zero_key(name)]
60
60
  raise NoCountdown, "no session countdown named '#{name}'"
61
61
  end
@@ -5,15 +5,16 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{session_countdown}
8
- s.version = "0.1.0"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Kevin Swope"]
12
- s.date = %q{2010-08-05}
12
+ s.date = %q{2010-08-06}
13
13
  s.description = %q{A Ruby on Rails plugin that puts a countdown timer on the session object}
14
14
  s.email = %q{gems-kevdev@snkmail.com}
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE",
17
+ "README.html",
17
18
  "README.rdoc"
18
19
  ]
19
20
  s.files = [
@@ -7,6 +7,7 @@ class TestControllerTest < ActionController::TestCase
7
7
  test "single default" do
8
8
 
9
9
  assert ! session.countdown_running?
10
+ assert ! session.countdown_expired?
10
11
 
11
12
  session.countdown_run(1.minute)
12
13
  assert session.countdown_running?
@@ -23,6 +24,25 @@ class TestControllerTest < ActionController::TestCase
23
24
 
24
25
  end
25
26
 
27
+ test "truth table test" do
28
+
29
+ # with no countdown started these conditions should be met
30
+ assert ! session.countdown_running?
31
+ assert ! session.countdown_expired?
32
+
33
+ # with countdown started
34
+ session.countdown_run(1.minute)
35
+ assert session.countdown_running?
36
+ assert ! session.countdown_expired?
37
+
38
+ # with countdown expired
39
+ session.countdown_expire
40
+ assert ! session.countdown_running?
41
+ assert session.countdown_expired?
42
+
43
+ end
44
+
45
+
26
46
 
27
47
  test "mixed names" do
28
48
 
@@ -98,19 +118,17 @@ class TestControllerTest < ActionController::TestCase
98
118
 
99
119
  test "unstable state" do
100
120
 
101
- ## all public methods except countdown_run and countdown_running?
102
- ## require an existing countdown
121
+ # restart, expire and count require an existing countdown, should
122
+ # throw exception if there isn't one
103
123
 
104
124
  assert_raise(NoCountdown) { session.countdown_expire }
105
125
  assert_raise(NoCountdown) { session.countdown_restart }
106
- assert_raise(NoCountdown) { session.countdown_expired? }
107
126
  assert_raise(NoCountdown) { session.countdown_count }
108
127
 
109
128
  ## try with named countdown
110
129
 
111
130
  assert_raise(NoCountdown) { session.countdown_expire(:admin) }
112
131
  assert_raise(NoCountdown) { session.countdown_restart(:admin) }
113
- assert_raise(NoCountdown) { session.countdown_expired?(:admin) }
114
132
  assert_raise(NoCountdown) { session.countdown_count(:admin) }
115
133
 
116
134
  end
@@ -7,6 +7,7 @@ class TestControllerTest < ActionController::TestCase
7
7
  test "single default" do
8
8
 
9
9
  assert ! session.countdown_running?
10
+ assert ! session.countdown_expired?
10
11
 
11
12
  session.countdown_run(1.minute)
12
13
  assert session.countdown_running?
@@ -23,6 +24,25 @@ class TestControllerTest < ActionController::TestCase
23
24
 
24
25
  end
25
26
 
27
+ test "truth table test" do
28
+
29
+ # with no countdown started these conditions should be met
30
+ assert ! session.countdown_running?
31
+ assert ! session.countdown_expired?
32
+
33
+ # with countdown started
34
+ session.countdown_run(1.minute)
35
+ assert session.countdown_running?
36
+ assert ! session.countdown_expired?
37
+
38
+ # with countdown expired
39
+ session.countdown_expire
40
+ assert ! session.countdown_running?
41
+ assert session.countdown_expired?
42
+
43
+ end
44
+
45
+
26
46
 
27
47
  test "mixed names" do
28
48
 
@@ -98,19 +118,17 @@ class TestControllerTest < ActionController::TestCase
98
118
 
99
119
  test "unstable state" do
100
120
 
101
- ## all public methods except countdown_run and countdown_running?
102
- ## require an existing countdown
121
+ # restart, expire and count require an existing countdown, should
122
+ # throw exception if there isn't one
103
123
 
104
124
  assert_raise(NoCountdown) { session.countdown_expire }
105
125
  assert_raise(NoCountdown) { session.countdown_restart }
106
- assert_raise(NoCountdown) { session.countdown_expired? }
107
126
  assert_raise(NoCountdown) { session.countdown_count }
108
127
 
109
128
  ## try with named countdown
110
129
 
111
130
  assert_raise(NoCountdown) { session.countdown_expire(:admin) }
112
131
  assert_raise(NoCountdown) { session.countdown_restart(:admin) }
113
- assert_raise(NoCountdown) { session.countdown_expired?(:admin) }
114
132
  assert_raise(NoCountdown) { session.countdown_count(:admin) }
115
133
 
116
134
  end
@@ -7,6 +7,7 @@ class TestControllerTest < ActionController::TestCase
7
7
  test "single default" do
8
8
 
9
9
  assert ! session.countdown_running?
10
+ assert ! session.countdown_expired?
10
11
 
11
12
  session.countdown_run(1.minute)
12
13
  assert session.countdown_running?
@@ -23,6 +24,25 @@ class TestControllerTest < ActionController::TestCase
23
24
 
24
25
  end
25
26
 
27
+ test "truth table test" do
28
+
29
+ # with no countdown started these conditions should be met
30
+ assert ! session.countdown_running?
31
+ assert ! session.countdown_expired?
32
+
33
+ # with countdown started
34
+ session.countdown_run(1.minute)
35
+ assert session.countdown_running?
36
+ assert ! session.countdown_expired?
37
+
38
+ # with countdown expired
39
+ session.countdown_expire
40
+ assert ! session.countdown_running?
41
+ assert session.countdown_expired?
42
+
43
+ end
44
+
45
+
26
46
 
27
47
  test "mixed names" do
28
48
 
@@ -98,19 +118,17 @@ class TestControllerTest < ActionController::TestCase
98
118
 
99
119
  test "unstable state" do
100
120
 
101
- ## all public methods except countdown_run and countdown_running?
102
- ## require an existing countdown
121
+ # restart, expire and count require an existing countdown, should
122
+ # throw exception if there isn't one
103
123
 
104
124
  assert_raise(NoCountdown) { session.countdown_expire }
105
125
  assert_raise(NoCountdown) { session.countdown_restart }
106
- assert_raise(NoCountdown) { session.countdown_expired? }
107
126
  assert_raise(NoCountdown) { session.countdown_count }
108
127
 
109
128
  ## try with named countdown
110
129
 
111
130
  assert_raise(NoCountdown) { session.countdown_expire(:admin) }
112
131
  assert_raise(NoCountdown) { session.countdown_restart(:admin) }
113
- assert_raise(NoCountdown) { session.countdown_expired?(:admin) }
114
132
  assert_raise(NoCountdown) { session.countdown_count(:admin) }
115
133
 
116
134
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: session_countdown
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 1
8
+ - 2
9
9
  - 0
10
- version: 0.1.0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Kevin Swope
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-05 00:00:00 -04:00
18
+ date: 2010-08-06 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -27,6 +27,7 @@ extensions: []
27
27
 
28
28
  extra_rdoc_files:
29
29
  - LICENSE
30
+ - README.html
30
31
  - README.rdoc
31
32
  files:
32
33
  - .document
@@ -94,6 +95,7 @@ files:
94
95
  - test/rails3x_root/script/rails
95
96
  - test/rails3x_root/test/functional/test_controller_test.rb
96
97
  - test/rails3x_root/test/test_helper.rb
98
+ - README.html
97
99
  has_rdoc: true
98
100
  homepage: http://github.com/kswope/session_countdown
99
101
  licenses: []