tight-engine 0.0.1 → 0.0.2

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.
@@ -1,20 +0,0 @@
1
- module Tight
2
- module Login
3
- module Controller
4
- def self.included(base)
5
- base.get :index do
6
- render :slim, :"new", :layout => :"layout", :views => File.dirname(__FILE__)
7
- end
8
- base.post :index do
9
- if authenticate
10
- restore_location
11
- else
12
- params.delete 'password'
13
- flash.now[:error] = 'Wrong password'
14
- render :slim, :"new", :layout => :"layout", :views => File.dirname(__FILE__)
15
- end
16
- end
17
- end
18
- end
19
- end
20
- end
@@ -1,10 +0,0 @@
1
- doctype html
2
- html
3
- head
4
- meta charset="utf-8"
5
- meta name="robots" content="noindex"
6
- title Padrino::Login
7
- link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/2.3.2/css/bootstrap.min.css"
8
- body
9
- .container.login style='width: 287px'
10
- = yield
@@ -1,37 +0,0 @@
1
- h3
2
- | Login
3
- br
4
- small
5
- a href=url('/') = request.env['HTTP_HOST']
6
-
7
- form.form-horizontal.well action=''
8
- - [:error, :warning, :success, :notice].each do |type|
9
- - next if flash[type].blank?
10
- .alert.alert-message class=('alert-' + (type == :notice ? :info : type).to_s) data-alert=true
11
- = flash[type]
12
-
13
- legend Social
14
- .control-group
15
- a href=url('/oauth/google')
16
- img src='/images/social/google.png'
17
-
18
- legend Obsolete
19
- .control-group
20
- .input-prepend
21
- span.add-on
22
- i.icon-envelope
23
- input type=:text name=:email value=params[:email] placeholder='email'
24
- .control-group
25
- .input-prepend
26
- span.add-on
27
- i.icon-lock
28
- input type=:password name=:password value=params[:password] placeholder='password'
29
- .control-group
30
- input.btn.btn-primary.pull-right type=:submit Log in
31
- - if settings.login_bypass
32
- label.checkbox
33
- | Bypass
34
- input type=:checkbox name=:bypass value='Bypass'
35
-
36
- small
37
- a href=url('/login/reset_password') Forgot password?
@@ -1,180 +0,0 @@
1
- module Tight
2
- ##
3
- # Class to store and check permissions used in Padrino::Access.
4
- #
5
- class Permissions
6
- ##
7
- # Initializes new permissions storage.
8
- #
9
- # @example
10
- # permissions = Permissions.new
11
- #
12
- def initialize
13
- clear!
14
- end
15
-
16
- ##
17
- # Clears permit records and action cache.
18
- #
19
- # @example
20
- # permissions.clear!
21
- #
22
- def clear!
23
- @permits = {}
24
- @actions = {}
25
- end
26
-
27
- ##
28
- # Adds a permission record to storage.
29
- #
30
- # @param [Symbol || Object] subject
31
- # permit subject
32
- # @param [Hash] options
33
- # permit attributes
34
- # @param [Symbol] options[:allow] || options[:action]
35
- # what action to allow with objects
36
- # @param [Symbol] options[:with] || options[:object]
37
- # with what objects allow specified action
38
- #
39
- # @example
40
- # permissions.add :robots, :allow => :protect, :object => :humans
41
- # permissions.add @bender, :allow => :kill, :object => :humans
42
- #
43
- def add(*args)
44
- @actions = {}
45
- options = args.extract_options!
46
- action, object = action_and_object(options)
47
- object_type = detect_type(object)
48
- args.each{ |subject| merge(subject, action, object_type) }
49
- end
50
-
51
- ##
52
- # Checks if permission record exists. Returns a boolean or yield a block.
53
- #
54
- # @param [Object] subject
55
- # performer of an action
56
- # @param [Hash] options
57
- # attributes to check
58
- # @param [Symbol] options[:have]
59
- # check if the subject has a role
60
- # @param [Symbol] options[:allow] || options[:action]
61
- # check if the subject is allowed to perform the action
62
- # @param [Symbol] options[:with] || options[:object]
63
- # check if the subject is allowed to interact with the subject
64
- # @param [Proc]
65
- # optional block to yield if the action is allowed
66
- #
67
- # @example
68
- # # check if @bender have role :robots
69
- # permissions.check @bender, :have => :robots # => true
70
- # # check if @bender is allowed to kill :humans
71
- # permissions.check @bender, :allow => :kill, :object => :humans # => true
72
- # # check if @bender is allowed to kill :humans and yield a block
73
- # permissions.check @bender, :allow => :kill, :object => :humans do
74
- # @bender.kill_all! :humans
75
- # end
76
- #
77
- def check(subject, options)
78
- case
79
- when options[:have]
80
- check_role(subject, options[:have])
81
- else
82
- check_action(subject, *action_and_object(options))
83
- end && (block_given? ? yield : true)
84
- end
85
-
86
- ##
87
- # Populates and returns the list of objects available to the subject.
88
- #
89
- # @param [Object] subject
90
- # the subject to be checked for actions
91
- #
92
- def find_objects(subject, target_action=nil)
93
- find_actions(subject).inject([]) do |all,(action,objects)|
94
- all |= objects if target_action.nil? || action == target_action || action == :*
95
- all
96
- end
97
- end
98
-
99
- private
100
-
101
- # Merges a list of new permits into permissions storage.
102
- def merge(subject, actions, object_type)
103
- subject_id = detect_id(subject)
104
- @permits[subject_id] ||= {}
105
- Array(actions).each do |action|
106
- @permits[subject_id][action] ||= []
107
- @permits[subject_id][action] |= [object_type]
108
- end
109
- end
110
-
111
- # Checks if the subject has the role.
112
- def check_role(subject, roles)
113
- if subject.respond_to?(:role)
114
- Array(roles).include?(subject.role)
115
- else
116
- false
117
- end
118
- end
119
-
120
- # Checks if the subject is allowed to perform the action with the object.
121
- def check_action(subject, action, object)
122
- actions = find_actions(subject)
123
- objects = actions && (Array(actions[action]) | Array(actions[:*]))
124
- objects && (objects & [:*, detect_type(object)]).any?
125
- end
126
-
127
- # Finds all permits for the subject. Caches the permits in @actions.
128
- # find_actions(@bender) # => { :kill => { :humans }, :drink => { :booze }, :* => { :login } }
129
- def find_actions(subject)
130
- subject_id = detect_id(subject)
131
- return @actions[subject_id] if @actions[subject_id]
132
- actions = @permits[subject_id] || {}
133
- if subject.respond_to?(:role) && (role_actions = @permits[subject.role.to_sym])
134
- actions.merge!(role_actions){ |_,left,right| Array(left)|Array(right) }
135
- end
136
- if public_actions = @permits[:*]
137
- actions.merge!(public_actions){ |_,left,right| Array(left)|Array(right) }
138
- end
139
- @actions[subject_id] = actions
140
- end
141
-
142
- # Returns object type.
143
- # detect_type :humans # => :human
144
- # detect_type 'foobar' # => 'foobar'
145
- def detect_type(object)
146
- case object
147
- when Symbol
148
- object.to_s.singularize.to_sym
149
- else
150
- object
151
- end
152
- end
153
-
154
- # Returns parametrized subject.
155
- # detect_id :robots # => :robots
156
- # detect_id sluggable_ar_resource # => 'Sluggable-resource-slug'
157
- # detect_id some_resource_with_id # => '4'
158
- # detect_id generic_object # => "<Object:0x00001234>"
159
- def detect_id(subject)
160
- case
161
- when Symbol === subject
162
- subject
163
- when subject.respond_to?(:to_param)
164
- subject.to_param
165
- when subject.respond_to?(:id)
166
- subject.id.to_s
167
- else
168
- "#{subject}"
169
- end
170
- end
171
-
172
- # Utility function to extract action and object from options. Defaults to [:*, :*]
173
- # action_and_object(:allow => :kill, :object => :humans) # => [:kill, :humans]
174
- # action_and_object(:action => :romance, :with => :mutants) # => [:romance, :mutants]
175
- # action_and_object({}) # => [:*, :*]
176
- def action_and_object(options)
177
- [options[:allow] || options[:action] || :*, options[:with] || options[:object] || :*]
178
- end
179
- end
180
- end
data/lib/tight/version.rb DELETED
@@ -1,3 +0,0 @@
1
- module Tight
2
- VERSION = '0.0.1'
3
- end
data/test/auth_helper.rb DELETED
@@ -1,83 +0,0 @@
1
- ENV['RACK_ENV'] = 'test'
2
-
3
- require 'padrino-core'
4
- require 'tight-auth'
5
- require 'minitest/autorun'
6
- require 'rack/test'
7
-
8
- module TightLogger
9
- attr_accessor :io
10
- def self.io
11
- @io ||= StringIO.new
12
- end
13
- end
14
-
15
- Padrino::Logger::Config[:test] = { :log_level => :devel, :stream => TightLogger.io }
16
-
17
- class Minitest::Spec
18
- include Rack::Test::Methods
19
-
20
- def mock_app(base=Padrino::Application, &block)
21
- @app = Sinatra.new(base, &block)
22
- end
23
-
24
- def app
25
- Rack::Lint.new(@app)
26
- end
27
-
28
- def set_access(*args)
29
- @app.set_access(*args)
30
- end
31
-
32
- def allow(subject = nil, path = '/')
33
- @app.fake_session[:visitor] = nil
34
- get "/login/#{subject.id}" if subject
35
- get path
36
- assert_equal 200, status, caller.first.to_s
37
- end
38
-
39
- def deny(subject = nil, path = '/')
40
- @app.fake_session[:visitor] = nil
41
- get "/login/#{subject.id}" if subject
42
- get path
43
- assert_equal 403, status, caller.first.to_s
44
- end
45
-
46
- def status
47
- response.status
48
- end
49
-
50
- def body
51
- response.body
52
- end
53
-
54
- def response
55
- last_response
56
- end
57
- end
58
-
59
- module Character
60
- extend self
61
-
62
- def authenticate(credentials)
63
- case
64
- when credentials[:email] && credentials[:password]
65
- target = all.find{ |resource| resource.id.to_s == credentials[:email] }
66
- target.name.gsub(/[^A-Z]/,'') == credentials[:password] ? target : nil
67
- when credentials.has_key?(:id)
68
- all.find{ |resource| resource.id == credentials[:id] }
69
- else
70
- false
71
- end
72
- end
73
-
74
- def all
75
- @all = [
76
- OpenStruct.new(:id => :bender, :name => 'Bender Bending Rodriguez', :role => :robots ),
77
- OpenStruct.new(:id => :leela, :name => 'Turanga Leela', :role => :mutants ),
78
- OpenStruct.new(:id => :fry, :name => 'Philip J. Fry', :role => :humans ),
79
- OpenStruct.new(:id => :ami, :name => 'Amy Wong', :role => :humans ),
80
- OpenStruct.new(:id => :zoidberg, :name => 'Dr. John A. Zoidberg', :role => :lobsters),
81
- ]
82
- end
83
- end
@@ -1,124 +0,0 @@
1
- require File.expand_path('../auth_helper', __FILE__)
2
-
3
- describe "Tight::Access" do
4
- before do
5
- mock_app do
6
- set :credentials_reader, :visitor
7
- register Tight::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 Tight::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