padrino-auth 0.0.12

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: