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 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
- I am aware of other sinatra/warden extensions which work very similarly to the system I outlined here.
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.4
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
- # Either a symbol or a record
123
- def build_object(explicit_object)
124
- explicit_object.is_a?(Symbol) ? explicit_object.to_s.classify.constantize.new : explicit_object
125
- raise "FormBuilder object must be initialized or use a symbol instead! (i.e :user)" unless explicit_object
126
- explicit_object
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
@@ -3,6 +3,7 @@
3
3
  unless String.method_defined?(:titleize)
4
4
  require 'active_support/inflector'
5
5
  require 'active_support/core_ext/blank'
6
+ require 'active_support/core_ext/class/attribute_accessors'
6
7
  end
7
8
 
8
9
  unless Hash.method_defined?(:reverse_merge!)
@@ -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' or require 'warden' in your app." unless Warden::Manager
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
- # TODO Improve serializing methods
17
- Warden::Manager.serialize_into_session{ |user| user.nil? ? nil : user.id }
18
- Warden::Manager.serialize_from_session{ |id| id.nil? ? nil : User.find(id) }
19
-
20
- Warden::Strategies.add(:password) do
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
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{sinatra_more}
8
- s.version = "0.2.4"
8
+ s.version = "0.2.5"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Nathan Esquenazi"]
@@ -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 User
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 ||= User.new(21, "John", 'john21', 'secret')
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sinatra_more
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Esquenazi