padrino-auth 0.0.12

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.
@@ -0,0 +1,5 @@
1
+ module Padrino
2
+ module Auth
3
+ def self.version; '0.0.12'; end
4
+ end
5
+ end
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env gem build
2
+ # encoding: utf-8
3
+
4
+ require File.expand_path("../lib/padrino-auth/version.rb", __FILE__)
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "padrino-auth"
8
+ s.rubyforge_project = "padrino-auth"
9
+ s.authors = ["Igor Bochkariov"]
10
+ s.email = "ujifgc@gmail.com"
11
+ s.summary = "Authentication and authorization modules for Padrino"
12
+ s.homepage = "https://github.com/ujifgc/padrino-auth"
13
+ s.description = "Lean authorization and authentication modules for Padrino framework"
14
+ s.required_rubygems_version = ">= 1.3.6"
15
+ s.version = Padrino::Auth.version
16
+ s.date = Time.now.strftime("%Y-%m-%d")
17
+ s.license = "MIT"
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.require_paths = ["lib"]
21
+ s.rdoc_options = ["--charset=UTF-8"]
22
+
23
+ s.add_development_dependency('rake', '~> 10')
24
+ s.add_development_dependency('rack', '~> 1')
25
+ s.add_development_dependency('rack-test', '~> 0', '>= 0.5')
26
+ s.add_development_dependency('slim', '~> 2')
27
+ s.add_development_dependency('padrino-helpers', '~> 0.12')
28
+ s.add_development_dependency('padrino-core', '~> 0.12')
29
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,68 @@
1
+ ENV['RACK_ENV'] = 'test'
2
+
3
+ require 'minitest/autorun'
4
+ require 'rack/test'
5
+ require 'rack'
6
+ require 'padrino-core'
7
+ require 'padrino-auth'
8
+
9
+ # Helper methods for testing Padrino::Access
10
+ class MiniTest::Spec
11
+ include Rack::Test::Methods
12
+
13
+ def mock_app(base=Padrino::Application, &block)
14
+ @app = Sinatra.new(base, &block)
15
+ end
16
+
17
+ def app
18
+ Rack::Lint.new(@app)
19
+ end
20
+
21
+ def status; last_response.status; end
22
+ def body; last_response.body; end
23
+ alias response last_response
24
+
25
+ def set_access(*args)
26
+ @app.set_access(*args)
27
+ end
28
+
29
+ def allow(subject = nil, path = '/')
30
+ @app.fake_session[:visitor] = nil
31
+ get "/login/#{subject.id}" if subject
32
+ get path
33
+ assert_equal 200, status, caller.first.to_s
34
+ end
35
+
36
+ def deny(subject = nil, path = '/')
37
+ @app.fake_session[:visitor] = nil
38
+ get "/login/#{subject.id}" if subject
39
+ get path
40
+ assert_equal 403, status, caller.first.to_s
41
+ end
42
+ end
43
+
44
+ module Character
45
+ extend self
46
+
47
+ def authenticate(credentials)
48
+ case
49
+ when credentials[:email] && credentials[:password]
50
+ target = all.find{ |resource| resource.id.to_s == credentials[:email] }
51
+ target.name.gsub(/[^A-Z]/,'') == credentials[:password] ? target : nil
52
+ when credentials.has_key?(:id)
53
+ all.find{ |resource| resource.id == credentials[:id] }
54
+ else
55
+ false
56
+ end
57
+ end
58
+
59
+ def all
60
+ @all = [
61
+ OpenStruct.new(:id => :bender, :name => 'Bender Bending Rodriguez', :role => :robots ),
62
+ OpenStruct.new(:id => :leela, :name => 'Turanga Leela', :role => :mutants ),
63
+ OpenStruct.new(:id => :fry, :name => 'Philip J. Fry', :role => :humans ),
64
+ OpenStruct.new(:id => :ami, :name => 'Amy Wong', :role => :humans ),
65
+ OpenStruct.new(:id => :zoidberg, :name => 'Dr. John A. Zoidberg', :role => :lobsters),
66
+ ]
67
+ end
68
+ end
@@ -0,0 +1,124 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ describe "Padrino::Access" do
4
+ before do
5
+ mock_app do
6
+ set :credentials_reader, :visitor
7
+ register Padrino::Access
8
+ set_access :*, :allow => :login
9
+ set :users, Character.all
10
+ get(:login, :with => :id) do
11
+ user = settings.users.find{ |user| user.id.to_s == params[:id] }
12
+ self.send(:"#{settings.credentials_reader}=", user)
13
+ end
14
+ get(:index){ 'foo' }
15
+ get(:bend){ 'bend' }
16
+ get(:drink){ 'bend' }
17
+ get(:subject){ self.send(settings.credentials_reader).inspect }
18
+ get(:stop_partying){ 'stop partying' }
19
+ controller :surface do
20
+ get(:live) { 'live on the surface' }
21
+ end
22
+ controller :sewers do
23
+ get(:live) { 'live in the sewers' }
24
+ get(:visit) { 'visit the sewers' }
25
+ end
26
+ set :fake_session, {}
27
+ helpers do
28
+ def visitor
29
+ settings.fake_session[:visitor]
30
+ end
31
+ def visitor=(user)
32
+ settings.fake_session[:visitor] = user
33
+ end
34
+ end
35
+ end
36
+ Character.all.each do |user|
37
+ instance_variable_set :"@#{user.id}", user
38
+ end
39
+ end
40
+
41
+ it 'should register with authorization module' do
42
+ assert @app.respond_to? :set_access
43
+ assert_kind_of Padrino::Permissions, @app.permissions
44
+ end
45
+
46
+ it 'should properly detect access subject' do
47
+ set_access :*
48
+ get '/login/ami'
49
+ get '/subject'
50
+ assert_equal @ami.inspect, body
51
+ end
52
+
53
+ it 'should reset access properly' do
54
+ set_access :*
55
+ allow
56
+ @app.reset_access!
57
+ deny
58
+ end
59
+
60
+ it 'should set group access' do
61
+ # only humans should be allowed on TV
62
+ set_access :humans
63
+ allow @fry
64
+ deny @bender
65
+ end
66
+
67
+ it 'should set individual access' do
68
+ # only Fry should be allowed to romance Leela
69
+ set_access @fry
70
+ allow @fry
71
+ deny @ami
72
+ end
73
+
74
+ it 'should set mixed individual and group access' do
75
+ # only humans and Leela should be allowed on the surface
76
+ set_access :humans
77
+ set_access @leela
78
+ allow @fry
79
+ allow @leela
80
+ end
81
+
82
+ it 'should set action-specific access' do
83
+ # bender should be allowed to bend, and he's denied to stop partying
84
+ set_access @bender, :allow => :bend
85
+ set_access @fry, :allow => :stop_partying
86
+ allow @bender, '/bend'
87
+ deny @bender, '/stop_partying'
88
+ allow @fry, '/stop_partying'
89
+ deny @fry, '/bend'
90
+ end
91
+
92
+ it 'should set multiple action' do
93
+ # bender should be allowed to bend and drink
94
+ set_access @bender, :allow => [:drink, :bend]
95
+ allow @bender, '/drink'
96
+ allow @bender, '/bend'
97
+ end
98
+
99
+ it 'should set object-specific access' do
100
+ # only humans and Leela should be allowed to live on the surface
101
+ # only mutants should be allowed to live in the sewers though humans can visit
102
+ set_access :humans, :allow => :live, :with => :surface
103
+ set_access :mutants, :allow => :live, :with => :sewers
104
+ set_access @leela, :allow => :live, :with => :surface
105
+ set_access :humans, :allow => :visit, :with => :sewers
106
+ allow @fry, '/surface/live'
107
+ deny @fry, '/sewers/live'
108
+ allow @fry, '/sewers/visit'
109
+ allow @leela, '/surface/live'
110
+ allow @leela, '/sewers/live'
111
+ end
112
+
113
+ it 'should detect object when setting access from controller' do
114
+ # only humans and lobsters should have binocular vision
115
+ @app.controller :binocular do
116
+ set_access :humans, :lobsters
117
+ get(:vision) { 'binocular vision' }
118
+ end
119
+ deny @fry, '/'
120
+ allow @fry, '/binocular/vision'
121
+ allow @zoidberg, '/binocular/vision'
122
+ deny @leela, '/binocular/vision'
123
+ end
124
+ end
@@ -0,0 +1,38 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ Account = Character
4
+
5
+ describe "Padrino::Auth" do
6
+ before do
7
+ mock_app do
8
+ enable :sessions
9
+ register Padrino::Login
10
+ register Padrino::Access
11
+ get(:robot_area){ 'robot_area' }
12
+ set_access :robots, :allow => :robot_area
13
+ end
14
+ end
15
+
16
+ it 'should login and access play nicely together' do
17
+ get '/robot_area'
18
+ assert_equal 302, status
19
+
20
+ post '/login', :email => :bender, :password => 'BBR'
21
+ get '/robot_area'
22
+ assert_equal 200, status
23
+
24
+ post '/login', :email => :leela, :password => 'TL'
25
+ get '/robot_area'
26
+ assert_equal 403, status
27
+ end
28
+
29
+ it 'should fail if the order is wrong' do
30
+ whine = capture_io do
31
+ mock_app do
32
+ register Padrino::Access
33
+ register Padrino::Login
34
+ end
35
+ end
36
+ assert_match /must be registered before/, whine.to_s
37
+ end
38
+ end
@@ -0,0 +1,81 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+ require 'padrino-helpers'
3
+
4
+ describe "Padrino::Access" do
5
+ before do
6
+ mock_app do
7
+ set :credentials_accessor, :visitor
8
+ set :login_model, :character
9
+ register Padrino::Rendering
10
+ enable :sessions
11
+ register Padrino::Login
12
+ get(:index){ 'index' }
13
+ get(:restricted){ 'secret' }
14
+ helpers Padrino::Helpers::AssetTagHelpers
15
+ helpers Padrino::Helpers::OutputHelpers
16
+ helpers Padrino::Helpers::TagHelpers
17
+ helpers Padrino::Helpers::FormHelpers
18
+ helpers do
19
+ def authorized?
20
+ return !['/restricted'].include?(request.env['PATH_INFO']) unless visitor
21
+ case
22
+ when visitor.id == :bender
23
+ true
24
+ else
25
+ false
26
+ end
27
+ end
28
+ end
29
+ end
30
+ Character.all.each do |user|
31
+ instance_variable_set :"@#{user.id}", user
32
+ end
33
+ end
34
+
35
+ it 'should pass unrestricted area' do
36
+ get '/'
37
+ assert_equal 200, status
38
+ end
39
+
40
+ it 'should be redirected from restricted area to login page' do
41
+ get '/restricted'
42
+ assert_equal 302, status
43
+ get response.location
44
+ assert_equal 200, status
45
+ assert_match /<form .*<input .*/, body
46
+ end
47
+
48
+ it 'should not be able to authenticate with wrong password' do
49
+ post '/login', :email => :bender, :password => '123'
50
+ assert_equal 200, status
51
+ assert_match 'Wrong password', body
52
+ end
53
+
54
+ it 'should be able to authenticate with email and password' do
55
+ post '/login', :email => :bender, :password => 'BBR'
56
+ assert_equal 302, status
57
+ end
58
+
59
+ it 'should be redirected back' do
60
+ get '/restricted'
61
+ post response.location, :email => :bender, :password => 'BBR'
62
+ assert_match /\/restricted$/, response.location
63
+ end
64
+
65
+ it 'should be redirected to root if no location was saved' do
66
+ post '/login', :email => :bender, :password => 'BBR'
67
+ assert_match /\/$/, response.location
68
+ end
69
+
70
+ it 'should be allowed in restricted area after logging in' do
71
+ post '/login', :email => :bender, :password => 'BBR'
72
+ get '/restricted'
73
+ assert_equal 'secret', body
74
+ end
75
+
76
+ it 'should not be allowed in restricted area after logging in an account lacking privileges' do
77
+ post '/login', :email => :leela, :password => 'TL'
78
+ get '/restricted'
79
+ assert_equal 403, status
80
+ end
81
+ end
metadata ADDED
@@ -0,0 +1,154 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: padrino-auth
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.12
5
+ platform: ruby
6
+ authors:
7
+ - Igor Bochkariov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rack
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rack-test
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: '0.5'
51
+ type: :development
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0.5'
61
+ - !ruby/object:Gem::Dependency
62
+ name: slim
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '2'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '2'
75
+ - !ruby/object:Gem::Dependency
76
+ name: padrino-helpers
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '0.12'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '0.12'
89
+ - !ruby/object:Gem::Dependency
90
+ name: padrino-core
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '0.12'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '0.12'
103
+ description: Lean authorization and authentication modules for Padrino framework
104
+ email: ujifgc@gmail.com
105
+ executables: []
106
+ extensions: []
107
+ extra_rdoc_files: []
108
+ files:
109
+ - ".gitignore"
110
+ - EXAMPLES.md
111
+ - Gemfile
112
+ - LICENSE
113
+ - README.md
114
+ - Rakefile
115
+ - lib/padrino-auth.rb
116
+ - lib/padrino-auth/access.rb
117
+ - lib/padrino-auth/login.rb
118
+ - lib/padrino-auth/login/controller.rb
119
+ - lib/padrino-auth/login/layouts/layout.slim
120
+ - lib/padrino-auth/login/new.slim
121
+ - lib/padrino-auth/permissions.rb
122
+ - lib/padrino-auth/version.rb
123
+ - padrino-auth.gemspec
124
+ - test/helper.rb
125
+ - test/test_padrino_access.rb
126
+ - test/test_padrino_auth.rb
127
+ - test/test_padrino_login.rb
128
+ homepage: https://github.com/ujifgc/padrino-auth
129
+ licenses:
130
+ - MIT
131
+ metadata: {}
132
+ post_install_message:
133
+ rdoc_options:
134
+ - "--charset=UTF-8"
135
+ require_paths:
136
+ - lib
137
+ required_ruby_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: 1.3.6
147
+ requirements: []
148
+ rubyforge_project: padrino-auth
149
+ rubygems_version: 2.2.2
150
+ signing_key:
151
+ specification_version: 4
152
+ summary: Authentication and authorization modules for Padrino
153
+ test_files: []
154
+ has_rdoc: