sinatra_more 0.2.4 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +35 -1
- data/VERSION +1 -1
- data/lib/sinatra_more/markup_plugin/form_builder/abstract_form_builder.rb +12 -7
- data/lib/sinatra_more/support_lite.rb +1 -0
- data/lib/sinatra_more/warden_plugin.rb +30 -23
- data/sinatra_more.gemspec +1 -1
- data/test/fixtures/markup_app/views/form_for.haml +4 -1
- data/test/fixtures/warden_app/app.rb +17 -16
- data/test/markup_plugin/test_form_builder.rb +7 -1
- data/test/markup_plugin/test_form_helpers.rb +1 -0
- metadata +1 -1
data/README.rdoc
CHANGED
@@ -411,7 +411,41 @@ provided to make interacting with warden dead simple.
|
|
411
411
|
* Used to require a user be authenticated before routing to an action
|
412
412
|
* <tt>must_be_authorized!('/login')</tt>
|
413
413
|
|
414
|
-
|
414
|
+
There are a few configuration options and details you need to be aware of. By default, the WardenPlugin
|
415
|
+
assumes you have a User class which represents the authenticating class type. If your user class has a different
|
416
|
+
name then you need to specify that as follows:
|
417
|
+
|
418
|
+
SinatraMore::WardenPlugin::PasswordStrategy.user_class = CustomUser
|
419
|
+
|
420
|
+
Similarly, the strategy used expects that you have an <tt>authenticate</tt> method on your user class as follows:
|
421
|
+
|
422
|
+
def authenticate(username, password)
|
423
|
+
# Returns user record if user and password match; otherwise return false
|
424
|
+
end
|
425
|
+
|
426
|
+
Using this plugin you also do need to define your own routes for managing warden sessions. An example is below:
|
427
|
+
|
428
|
+
get '/unauthenticated/?' do
|
429
|
+
flash[:notice] = "That username and password are not correct!"
|
430
|
+
status 401
|
431
|
+
haml_template 'session/login'
|
432
|
+
end
|
433
|
+
|
434
|
+
get '/login/?' do
|
435
|
+
haml_template 'session/login'
|
436
|
+
end
|
437
|
+
|
438
|
+
post '/login/?' do
|
439
|
+
authenticate_user!
|
440
|
+
redirect "/dashboard"
|
441
|
+
end
|
442
|
+
|
443
|
+
get '/logout/?' do
|
444
|
+
logout_user!
|
445
|
+
redirect '/session/login'
|
446
|
+
end
|
447
|
+
|
448
|
+
I was made aware of other sinatra/warden extensions which work very similarly to the system I outline for this plugin.
|
415
449
|
Most notably is the sinatra_warden plugin by Justin Smestad (http://github.com/jsmestad/sinatra_warden)
|
416
450
|
Eventually I plan to vendor that gem or just remove support for this piece of my plugin completely.
|
417
451
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.5
|
@@ -2,9 +2,10 @@ class AbstractFormBuilder
|
|
2
2
|
attr_accessor :template, :object
|
3
3
|
|
4
4
|
def initialize(template, object)
|
5
|
-
raise "FormBuilder template must be initialized!" unless template
|
6
5
|
@template = template
|
7
6
|
@object = build_object(object)
|
7
|
+
raise "FormBuilder template must be initialized!" unless template
|
8
|
+
raise "FormBuilder object must be not be nil value. If there's no object, use a symbol instead! (i.e :user)" unless object
|
8
9
|
end
|
9
10
|
|
10
11
|
# f.error_messages
|
@@ -118,11 +119,15 @@ class AbstractFormBuilder
|
|
118
119
|
def field_id(field, value=nil)
|
119
120
|
value.blank? ? "#{object_name}_#{field}" : "#{object_name}_#{field}_#{value}"
|
120
121
|
end
|
121
|
-
|
122
|
-
#
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
122
|
+
|
123
|
+
# explicit_object is either a symbol or a record
|
124
|
+
# Returns a new record of the type specified in the object
|
125
|
+
def build_object(object_or_symbol)
|
126
|
+
object_or_symbol.is_a?(Symbol) ? object_class(object_or_symbol).new : object_or_symbol
|
127
|
+
end
|
128
|
+
|
129
|
+
# Returns the class type for the given object
|
130
|
+
def object_class(explicit_object)
|
131
|
+
explicit_object.is_a?(Symbol) ? explicit_object.to_s.classify.constantize : explicit_object.class
|
127
132
|
end
|
128
133
|
end
|
@@ -1,11 +1,35 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/support_lite'
|
2
|
+
require 'warden' unless defined?(Warden)
|
2
3
|
load File.dirname(__FILE__) + '/markup_plugin/output_helpers.rb'
|
3
4
|
Dir[File.dirname(__FILE__) + '/warden_plugin/**/*.rb'].each {|file| load file }
|
4
5
|
|
5
6
|
module SinatraMore
|
6
7
|
module WardenPlugin
|
8
|
+
# This is the basic password strategy for authentication
|
9
|
+
class PasswordStrategy < Warden::Strategies::Base
|
10
|
+
cattr_accessor :user_class
|
11
|
+
|
12
|
+
def valid?
|
13
|
+
username || password
|
14
|
+
end
|
15
|
+
|
16
|
+
def authenticate!
|
17
|
+
raise "Please either define a user class or set SinatraMore::WardenPlugin::PasswordStrategy.user_class" unless user_class
|
18
|
+
u = user_class.authenticate(username, password)
|
19
|
+
u.nil? ? fail!("Could not log in") : success!(u)
|
20
|
+
end
|
21
|
+
|
22
|
+
def username
|
23
|
+
params['username'] || params['nickname'] || params['login'] || params['email']
|
24
|
+
end
|
25
|
+
|
26
|
+
def password
|
27
|
+
params['password'] || params['pass']
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
7
31
|
def self.registered(app)
|
8
|
-
raise "WardenPlugin::Error - Install with 'sudo gem install warden'
|
32
|
+
raise "WardenPlugin::Error - Install warden with 'sudo gem install warden' to use plugin!" unless Warden && Warden::Manager
|
9
33
|
app.use Warden::Manager do |manager|
|
10
34
|
manager.default_strategies :password
|
11
35
|
manager.failure_app = app
|
@@ -13,28 +37,11 @@ module SinatraMore
|
|
13
37
|
app.helpers SinatraMore::OutputHelpers
|
14
38
|
app.helpers SinatraMore::WardenHelpers
|
15
39
|
|
16
|
-
|
17
|
-
Warden::Manager.serialize_into_session{ |user| user.nil? ? nil : user.id }
|
18
|
-
Warden::Manager.serialize_from_session{ |id|
|
19
|
-
|
20
|
-
|
21
|
-
def valid?
|
22
|
-
username || password
|
23
|
-
end
|
24
|
-
|
25
|
-
def authenticate!
|
26
|
-
u = User.authenticate(username, password)
|
27
|
-
u.nil? ? fail!("Could not log in") : success!(u)
|
28
|
-
end
|
29
|
-
|
30
|
-
def username
|
31
|
-
params['username'] || params['nickname'] || params['login'] || params['email']
|
32
|
-
end
|
33
|
-
|
34
|
-
def password
|
35
|
-
params['password'] || params['pass']
|
36
|
-
end
|
37
|
-
end
|
40
|
+
Warden::Manager.before_failure { |env,opts| env['REQUEST_METHOD'] = "POST" }
|
41
|
+
Warden::Manager.serialize_into_session { |user| user.nil? ? nil : user.id }
|
42
|
+
Warden::Manager.serialize_from_session { |id| id.nil? ? nil : PasswordStrategy.user_class.find(id) }
|
43
|
+
Warden::Strategies.add(:password, PasswordStrategy)
|
44
|
+
PasswordStrategy.user_class = User if defined?(User)
|
38
45
|
end
|
39
46
|
end
|
40
47
|
end
|
data/sinatra_more.gemspec
CHANGED
@@ -41,4 +41,7 @@
|
|
41
41
|
= f.check_box_block :remember_me, { :class => 'checker' }
|
42
42
|
= f.select_block :state, :options => ['California', 'Texas'], :class => 'selector'
|
43
43
|
= f.submit_block "Create", { :class => 'button' }
|
44
|
-
= f.image_submit_block "buttons/ok.png", { :class => 'image' }
|
44
|
+
= f.image_submit_block "buttons/ok.png", { :class => 'image' }
|
45
|
+
|
46
|
+
- form_for :markup_user, '/third_demo', :id => 'demo3', :method => 'get' do |f|
|
47
|
+
= f.text_field_block :username
|
@@ -2,63 +2,64 @@ require 'sinatra/base'
|
|
2
2
|
require 'sinatra_more'
|
3
3
|
require 'warden'
|
4
4
|
|
5
|
-
class
|
5
|
+
class WardenUser
|
6
6
|
attr_accessor :id, :name, :username, :password
|
7
|
-
|
7
|
+
|
8
8
|
def initialize(id, name, username, password)
|
9
9
|
self.id, self.name, self.username, self.password = id, name, username, password
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
def self.find(id)
|
13
13
|
return self.john_user if id == self.john_user.id
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
def self.authenticate(username, password)
|
17
17
|
return self.john_user if username == self.john_user.username && password == self.john_user.password
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
def self.john_user
|
21
|
-
@john ||=
|
21
|
+
@john ||= WardenUser.new(21, "John", 'john21', 'secret')
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
class WardenDemo < Sinatra::Base
|
26
26
|
use Rack::Session::Cookie
|
27
27
|
register SinatraMore::WardenPlugin
|
28
|
-
|
28
|
+
SinatraMore::WardenPlugin::PasswordStrategy.user_class = WardenUser
|
29
|
+
|
29
30
|
configure do
|
30
31
|
set :root, File.dirname(__FILE__)
|
31
32
|
end
|
32
|
-
|
33
|
+
|
33
34
|
get '/login' do
|
34
35
|
"<h1>Please login!</h1>"
|
35
36
|
end
|
36
|
-
|
37
|
+
|
37
38
|
post '/login' do
|
38
39
|
authenticate_user!
|
39
40
|
end
|
40
|
-
|
41
|
+
|
41
42
|
get '/logout' do
|
42
43
|
logout_user!
|
43
44
|
end
|
44
|
-
|
45
|
+
|
45
46
|
get '/logged_in' do
|
46
47
|
"<h1>logged_in? #{logged_in?}</h1>"
|
47
48
|
end
|
48
|
-
|
49
|
+
|
49
50
|
get '/authenticated' do
|
50
51
|
haml :dashboard
|
51
52
|
end
|
52
|
-
|
53
|
+
|
53
54
|
get '/unregistered' do
|
54
55
|
haml :dashboard
|
55
56
|
end
|
56
|
-
|
57
|
+
|
57
58
|
get '/must_be_authorized' do
|
58
59
|
must_be_authorized!('/login')
|
59
60
|
"<h1>Valid Authorized Page</h1>"
|
60
61
|
end
|
61
|
-
|
62
|
+
|
62
63
|
get '/current_user' do
|
63
64
|
if current_user
|
64
65
|
"<h1>#{current_user.name}</h1>"
|
@@ -66,4 +67,4 @@ class WardenDemo < Sinatra::Base
|
|
66
67
|
"<h2>Not logged in</h2>"
|
67
68
|
end
|
68
69
|
end
|
69
|
-
end
|
70
|
+
end
|
@@ -26,7 +26,7 @@ class TestFormBuilder < Test::Unit::TestCase
|
|
26
26
|
assert_has_tag('form', :action => '/register', :id => 'register', :method => 'post', :content => "Demo") { actual_html }
|
27
27
|
assert_has_tag('form input[type=hidden]', :name => '_method', :count => 0) { actual_html } # no method action field
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
should "display correct form html with fake object" do
|
31
31
|
actual_html = form_for(:markup_user, '/register', :id => 'register', :method => 'post') { |f| f.text_field :username }
|
32
32
|
assert_has_tag('form', :action => '/register', :id => 'register', :method => 'post') { actual_html }
|
@@ -61,16 +61,22 @@ class TestFormBuilder < Test::Unit::TestCase
|
|
61
61
|
assert_has_tag('form p input[type=text]') { actual_html }
|
62
62
|
end
|
63
63
|
|
64
|
+
should "display fail for form with no object" do
|
65
|
+
assert_raises(RuntimeError) { form_for(@not_real, '/register', :id => 'register', :method => 'post') { "Demo" } }
|
66
|
+
end
|
67
|
+
|
64
68
|
should "display correct form in haml" do
|
65
69
|
visit '/haml/form_for'
|
66
70
|
assert_have_selector :form, :action => '/demo', :id => 'demo'
|
67
71
|
assert_have_selector :form, :action => '/another_demo', :id => 'demo2', :method => 'get'
|
72
|
+
assert_have_selector :form, :action => '/third_demo', :id => 'demo3', :method => 'get'
|
68
73
|
end
|
69
74
|
|
70
75
|
should "display correct form in erb" do
|
71
76
|
visit '/erb/form_for'
|
72
77
|
assert_have_selector :form, :action => '/demo', :id => 'demo'
|
73
78
|
assert_have_selector :form, :action => '/another_demo', :id => 'demo2', :method => 'get'
|
79
|
+
assert_have_selector :form, :action => '/third_demo', :id => 'demo3', :method => 'get'
|
74
80
|
end
|
75
81
|
end
|
76
82
|
|
@@ -241,6 +241,7 @@ class TestFormHelpers < Test::Unit::TestCase
|
|
241
241
|
should "display check_box tag in ruby" do
|
242
242
|
actual_html = check_box_tag("clear_session")
|
243
243
|
assert_has_tag(:input, :type => 'checkbox', :value => '1', :name => 'clear_session') { actual_html }
|
244
|
+
assert_has_no_tag(:input, :type => 'hidden') { actual_html }
|
244
245
|
end
|
245
246
|
|
246
247
|
should "display check_box tag in ruby with extended attributes" do
|