sinatra_more 0.2.4 → 0.2.5
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/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
|