lolita 3.3.9 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Gemfile +1 -1
- data/README.md +1 -1
- data/app/assets/stylesheets/lolita/style.css.erb +7 -1
- data/app/controllers/lolita/info_controller.rb +1 -1
- data/lib/lolita/adapter/common_helper.rb +3 -1
- data/lib/lolita/controller_additions.rb +3 -2
- data/lib/lolita/extensions/authentication/default_adapter.rb +3 -3
- data/lib/lolita/extensions/authorization/cancan_adapter.rb +4 -4
- data/lib/lolita/extensions/authorization/proxy.rb +4 -3
- data/lib/lolita/extensions/authorization/pundit_adapter.rb +77 -0
- data/lib/lolita/extensions/extensions.rb +2 -2
- data/lib/lolita/system_configuration/base.rb +10 -4
- data/lib/lolita/version.rb +2 -2
- data/spec/configuration/filter_spec.rb +9 -16
- data/spec/extensions/authorization/cancan_adapter_spec.rb +3 -3
- data/spec/extensions/authorization/pundit_adapter_spec.rb +104 -0
- data/spec/simple_spec_helper.rb +5 -0
- data/spec/spec_helper.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4b73d7232b6d16a4d0b0b0c0c35a1928fe316390
|
4
|
+
data.tar.gz: 8f0f31e08f83abff1884b007b8559fa96c25108c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25028f189a32ad2a665b3f4cbfff3002e5517845d6c1e84a2d2d329cd0f18fd1e0a8ebec07d8118cb2471260fb263b632667b9065fd506cebe493d669d8baaf9
|
7
|
+
data.tar.gz: 502fd36b78421dcb183bf3c9a03ac535653f257773a3742065bf1b3197948648e0fc37fa9c3057f3fd974ef71fcca2431896ae0d38b5cde59e8d6fa07a3b6c6c
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -431,7 +431,13 @@ tr.nested-list td{
|
|
431
431
|
display: inline-block;
|
432
432
|
margin-right: 10px;
|
433
433
|
}
|
434
|
-
|
434
|
+
#main .box form.filter .field {
|
435
|
+
overflow: inherit;
|
436
|
+
}
|
437
|
+
.filter button[type='submit'] {
|
438
|
+
float: right;
|
439
|
+
margin-top: 8px;
|
440
|
+
}
|
435
441
|
/* --------------------------------------------- */
|
436
442
|
|
437
443
|
/* Pagination */
|
@@ -4,7 +4,7 @@ class Lolita::InfoController < ApplicationController
|
|
4
4
|
|
5
5
|
def index
|
6
6
|
if Lolita.mappings.any?
|
7
|
-
if available_mapping = Lolita.mappings.detect{ |name,mapping| authorization_proxy.
|
7
|
+
if available_mapping = Lolita.mappings.detect{ |name,mapping| authorization_proxy.can?(:read, mapping.to) }
|
8
8
|
mapping = available_mapping.last
|
9
9
|
return redirect_to(lolita_resources_path(mapping))
|
10
10
|
end
|
@@ -50,6 +50,8 @@ module Lolita
|
|
50
50
|
def ability_criteria
|
51
51
|
@ability_criteria ||= if @adapter.klass.respond_to?(:accessible_by)
|
52
52
|
@adapter.klass.accessible_by(current_ability)
|
53
|
+
elsif current_ability.respond_to?(:scope)
|
54
|
+
current_ability.scope
|
53
55
|
else
|
54
56
|
nil
|
55
57
|
end
|
@@ -216,4 +218,4 @@ module Lolita
|
|
216
218
|
|
217
219
|
end
|
218
220
|
end
|
219
|
-
end
|
221
|
+
end
|
@@ -7,10 +7,11 @@ module Lolita
|
|
7
7
|
include Lolita::Controllers::InternalHelpers
|
8
8
|
include Lolita::Controllers::AuthenticationHelpers
|
9
9
|
if Lolita.rails?
|
10
|
-
include Lolita::Controllers::RailsHelpers
|
10
|
+
include Lolita::Controllers::RailsHelpers
|
11
11
|
end
|
12
|
+
attr_accessor :current_ability
|
12
13
|
end
|
13
14
|
end
|
14
15
|
|
15
16
|
end
|
16
|
-
end
|
17
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Lolita
|
2
2
|
module Extensions
|
3
3
|
module Authentication
|
4
|
-
|
4
|
+
|
5
5
|
class DefaultAdapter
|
6
6
|
def initialize context, options={}
|
7
7
|
end
|
@@ -9,7 +9,7 @@ module Lolita
|
|
9
9
|
def current_user
|
10
10
|
nil
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
def user_signed_in?
|
14
14
|
false
|
15
15
|
end
|
@@ -21,4 +21,4 @@ module Lolita
|
|
21
21
|
|
22
22
|
end
|
23
23
|
end
|
24
|
-
end
|
24
|
+
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
module Lolita
|
2
2
|
module Extensions
|
3
3
|
module Authorization
|
4
|
-
|
4
|
+
|
5
5
|
class CanCanAdapter
|
6
|
-
|
6
|
+
|
7
7
|
def initialize context, options={}
|
8
8
|
raise NameError, "CanCan is not defined" unless defined?(CanCan)
|
9
9
|
raise Lolita::NoAuthorizationDefinedError, "Lolita.authorization is not defined" unless Lolita.authorization
|
@@ -32,7 +32,7 @@ module Lolita
|
|
32
32
|
def authorize! *args
|
33
33
|
current_ability && @context && @context.authorize!(*args) || current_ability.authorize!(*args)
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
private
|
37
37
|
|
38
38
|
def set_default_options
|
@@ -42,4 +42,4 @@ module Lolita
|
|
42
42
|
|
43
43
|
end
|
44
44
|
end
|
45
|
-
end
|
45
|
+
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
require "#{File.dirname(__FILE__)}/default_adapter"
|
2
2
|
require "#{File.dirname(__FILE__)}/cancan_adapter"
|
3
|
+
require "#{File.dirname(__FILE__)}/pundit_adapter"
|
3
4
|
|
4
5
|
module Lolita
|
5
6
|
class NoAuthorizationDefinedError < ArgumentError ; end
|
6
|
-
|
7
|
+
|
7
8
|
module Extensions
|
8
9
|
module Authorization
|
9
10
|
|
@@ -31,7 +32,7 @@ module Lolita
|
|
31
32
|
def current_ability *args
|
32
33
|
@adapter.current_ability *args
|
33
34
|
end
|
34
|
-
|
35
|
+
|
35
36
|
private
|
36
37
|
|
37
38
|
def get_adapter
|
@@ -45,4 +46,4 @@ module Lolita
|
|
45
46
|
|
46
47
|
end
|
47
48
|
end
|
48
|
-
end
|
49
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Lolita
|
2
|
+
module Extensions
|
3
|
+
module Authorization
|
4
|
+
class PunditAdapter
|
5
|
+
|
6
|
+
def initialize context, options={}
|
7
|
+
raise NameError, "Pundit is not defined" unless defined?(Pundit)
|
8
|
+
raise Lolita::NoAuthorizationDefinedError, "Lolita.authorization is not defined" unless Lolita.authorization
|
9
|
+
@context = context
|
10
|
+
@options = options
|
11
|
+
current_ability
|
12
|
+
end
|
13
|
+
|
14
|
+
def can? *args
|
15
|
+
!!(ability = current_ability(*args) and ability.send(policy_method(args)))
|
16
|
+
end
|
17
|
+
|
18
|
+
def cannot? *args
|
19
|
+
!can?(*args)
|
20
|
+
end
|
21
|
+
|
22
|
+
def current_ability *args
|
23
|
+
if current_user && record = get_record(*args)
|
24
|
+
@current_ability = Pundit.policy(current_user, record) || Lolita.policy_class.new(current_user, record)
|
25
|
+
@context && @context.instance_variable_set(:"@current_ability", @current_ability)
|
26
|
+
end
|
27
|
+
@current_ability
|
28
|
+
end
|
29
|
+
|
30
|
+
def authorize! *args
|
31
|
+
unless ability = current_ability(*args) and ability.public_send(policy_method(args))
|
32
|
+
raise Pundit::NotAuthorizedError.new("not allowed to #{args.first} this #{args.last}")
|
33
|
+
end
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def current_user
|
40
|
+
@context && @context.authentication_proxy.current_user
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_record *args
|
44
|
+
if args.any?
|
45
|
+
record_as_instance(args.last)
|
46
|
+
else
|
47
|
+
mapping = @options[:request].env["lolita.mapping"] and mapping.class_name.constantize
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def policy_method args
|
52
|
+
"#{args.first}?"
|
53
|
+
end
|
54
|
+
|
55
|
+
# pundit can receive only instance as record, but Lolita can give
|
56
|
+
# sometime instance sometimes class or module, so we try to make it
|
57
|
+
# as instance
|
58
|
+
def record_as_instance record
|
59
|
+
if is_instance?(record)
|
60
|
+
record
|
61
|
+
elsif is_module?(record)
|
62
|
+
Object.new
|
63
|
+
else
|
64
|
+
record.new
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def is_module? obj
|
69
|
+
obj.class == Module
|
70
|
+
end
|
71
|
+
def is_instance? obj
|
72
|
+
!obj.respond_to? :ancestors
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -25,7 +25,7 @@ module Lolita
|
|
25
25
|
load_extension_proxy(type,context,options)
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
def load_extension_proxy type,context=self,options={}
|
30
30
|
proxy_class = "Lolita::Extensions::#{type.to_s.camelize}::Proxy".constantize
|
31
31
|
initialize_arity = proxy_class.instance_method(:initialize).arity
|
@@ -63,4 +63,4 @@ Lolita::Extensions.add :authentication
|
|
63
63
|
Lolita::Extensions.add :authorization
|
64
64
|
|
65
65
|
require 'lolita/extensions/authorization/proxy'
|
66
|
-
require 'lolita/extensions/authentication/proxy'
|
66
|
+
require 'lolita/extensions/authentication/proxy'
|
@@ -3,7 +3,7 @@ module Lolita
|
|
3
3
|
class Base
|
4
4
|
attr_reader :scope, :modules, :routes, :controllers,:resources
|
5
5
|
attr_accessor :mappings,:default_route,:user_classes,:authentication,:authorization
|
6
|
-
attr_writer :default_locale, :ability_class
|
6
|
+
attr_writer :default_locale, :ability_class, :policy_class
|
7
7
|
|
8
8
|
def initialize(scope)
|
9
9
|
@scope=scope
|
@@ -31,11 +31,17 @@ module Lolita
|
|
31
31
|
end
|
32
32
|
Lolita::Navigation::Tree[:"left_side_navigation"]
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
|
+
# ability class for CanCan
|
35
36
|
def ability_class
|
36
37
|
@ability_class || (::Ability rescue nil) || raise("No ability class found.")
|
37
38
|
end
|
38
39
|
|
40
|
+
# policy class for Pundit
|
41
|
+
def policy_class
|
42
|
+
@policy_class || (::LolitaPolicy rescue nil) || raise("No policy class found.")
|
43
|
+
end
|
44
|
+
|
39
45
|
def locales=(value)
|
40
46
|
unless value.is_a?(Array)
|
41
47
|
@locales=[value]
|
@@ -95,7 +101,7 @@ module Lolita
|
|
95
101
|
end
|
96
102
|
}.flatten.compact.uniq
|
97
103
|
end
|
98
|
-
|
104
|
+
|
99
105
|
# Include module in Lolita, don't know why i need this
|
100
106
|
def use(module_name)
|
101
107
|
Lolita.send(:include,module_name)
|
@@ -165,4 +171,4 @@ module Lolita
|
|
165
171
|
|
166
172
|
end
|
167
173
|
end
|
168
|
-
end
|
174
|
+
end
|
data/lib/lolita/version.rb
CHANGED
@@ -91,6 +91,9 @@ describe Lolita::Configuration::Filter do
|
|
91
91
|
|
92
92
|
describe "Filtering list" do
|
93
93
|
let(:list){ Lolita::Configuration::List}
|
94
|
+
let(:request){
|
95
|
+
double('request', headers: {}, params: {})
|
96
|
+
}
|
94
97
|
|
95
98
|
it "should filter with default filters" do
|
96
99
|
tags = %w(Android Linux Windows).map{|name| Fabricate(:tag, :name => name )}
|
@@ -101,16 +104,11 @@ describe Lolita::Configuration::Filter do
|
|
101
104
|
field :tags
|
102
105
|
end
|
103
106
|
end
|
104
|
-
list_conf.paginate(1).should have(3).items
|
105
|
-
request
|
106
|
-
request.
|
107
|
-
def params
|
108
|
-
{:filter => {:tag_ids => Tag.where(:name => 'Android').first.id}}
|
109
|
-
end
|
110
|
-
end
|
111
|
-
list_conf.paginate(1,request).should have(1).items
|
107
|
+
list_conf.paginate(1, request).should have(3).items
|
108
|
+
request.stub(params: {:filter => {:tag_ids => Tag.where(:name => 'Android').first.id}})
|
109
|
+
list_conf.paginate(1, request).should have(1).items
|
112
110
|
end
|
113
|
-
|
111
|
+
|
114
112
|
it "should filter with custom search" do
|
115
113
|
tags = %w(Android Linux Windows).map{|name| Fabricate(:tag, :name => name )}
|
116
114
|
3.times {|i| Fabricate(:post,:tags => [tags[i]])}
|
@@ -125,13 +123,8 @@ describe Lolita::Configuration::Filter do
|
|
125
123
|
search :custom_filter
|
126
124
|
end
|
127
125
|
end
|
128
|
-
list_conf.paginate(1).should have(3).items
|
129
|
-
request
|
130
|
-
request.class_eval do
|
131
|
-
def params
|
132
|
-
{:filter => {:tag_ids => Tag.where(:name => 'Android').first.id}}
|
133
|
-
end
|
134
|
-
end
|
126
|
+
list_conf.paginate(1, request).should have(3).items
|
127
|
+
request.stub(params: {:filter => {:tag_ids => Tag.where(:name => 'Android').first.id}})
|
135
128
|
list_conf.paginate(1,request).should have(2).items
|
136
129
|
end
|
137
130
|
end
|
@@ -71,8 +71,8 @@ describe Lolita::Extensions::Authorization::CanCanAdapter do
|
|
71
71
|
it "should authorize resource" do
|
72
72
|
adapter2 = klass.new(nil)
|
73
73
|
expect do
|
74
|
-
adapter2.authorize!(:read,Object).should == "ability_response"
|
75
|
-
adapter.authorize!(:read,Object).should == "context_response"
|
74
|
+
adapter2.authorize!(:read, Object).should == "ability_response"
|
75
|
+
adapter.authorize!(:read, Object).should == "context_response"
|
76
76
|
end.not_to raise_error
|
77
77
|
end
|
78
78
|
end
|
@@ -91,4 +91,4 @@ describe Lolita::Extensions::Authorization::CanCanAdapter do
|
|
91
91
|
proxy.adapter.current_ability == adapter.current_ability
|
92
92
|
end
|
93
93
|
end
|
94
|
-
end
|
94
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../simple_spec_helper')
|
2
|
+
|
3
|
+
class TestApplicationController
|
4
|
+
include Lolita::Extensions
|
5
|
+
end
|
6
|
+
|
7
|
+
class TestPolicy
|
8
|
+
def initialize user, record
|
9
|
+
end
|
10
|
+
|
11
|
+
def read?
|
12
|
+
true
|
13
|
+
end
|
14
|
+
|
15
|
+
def create?
|
16
|
+
false
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module Pundit
|
21
|
+
class NotAuthorizedError < StandardError ; end
|
22
|
+
|
23
|
+
def self.policy user, record
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe Lolita::Extensions::Authorization::PunditAdapter do
|
28
|
+
let(:klass){ Lolita::Extensions::Authorization::PunditAdapter }
|
29
|
+
around(:each){|example|
|
30
|
+
Lolita.authorization = 'Pundit'
|
31
|
+
Lolita.policy_class = TestPolicy
|
32
|
+
example.run
|
33
|
+
Lolita.authorization = nil
|
34
|
+
Lolita.policy_class = nil
|
35
|
+
}
|
36
|
+
let(:adapter){ klass.new(TestApplicationController.new,{request: double(env: {})}) }
|
37
|
+
|
38
|
+
it "should create new" do
|
39
|
+
expect do
|
40
|
+
klass.new(TestApplicationController.new,{request: double(env: {})})
|
41
|
+
end.not_to raise_error
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should raise error without authorization" do
|
45
|
+
expect do
|
46
|
+
Lolita.authorization = nil
|
47
|
+
klass.new(TestApplicationController.new,{request: double(env: {})})
|
48
|
+
end.to raise_error(Lolita::NoAuthorizationDefinedError)
|
49
|
+
end
|
50
|
+
|
51
|
+
context "current user" do
|
52
|
+
|
53
|
+
before do
|
54
|
+
TestApplicationController.any_instance.stub(authentication_proxy: double(current_user: double('Admin')))
|
55
|
+
end
|
56
|
+
|
57
|
+
it "can do some action with current policy" do
|
58
|
+
adapter.can?(:read,"HiddenText".class).should be_true
|
59
|
+
adapter.can?(:create,"HiddenText".class).should be_false
|
60
|
+
end
|
61
|
+
|
62
|
+
it "can ONLY do actions from policy" do
|
63
|
+
adapter.cannot?(:read,"HiddenText".class).should be_false
|
64
|
+
adapter.cannot?(:create,"HiddenText".class).should be_true
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should have current policy" do
|
68
|
+
adapter.current_ability(Object.new).should be_a(Lolita.policy_class)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should not authorize resource without current_user" do
|
72
|
+
adapter2 = klass.new(nil)
|
73
|
+
expect do
|
74
|
+
adapter2.authorize!(:read, Object)
|
75
|
+
end.to raise_error
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should authorize resource" do
|
79
|
+
expect do
|
80
|
+
adapter.authorize!(:read, Object).should be_true
|
81
|
+
end.to_not raise_error
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe 'Integration with proxy' do
|
86
|
+
let(:proxy){
|
87
|
+
mock_class = Object.new
|
88
|
+
mock_class.class_eval{include Lolita::Extensions}
|
89
|
+
Lolita::Extensions::Authorization::Proxy.new(mock_class,{request: double(env: {})})
|
90
|
+
}
|
91
|
+
|
92
|
+
before do
|
93
|
+
TestApplicationController.any_instance.stub(authentication_proxy: double(current_user: double('Admin')))
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should have the same method results for adapter and proxy" do
|
97
|
+
proxy.adapter = adapter
|
98
|
+
%w(can? cannot? authorize!).each do |name|
|
99
|
+
proxy.send(name,:read, String).should eql(adapter.send(name,:read,String))
|
100
|
+
end
|
101
|
+
proxy.adapter.current_ability(Object) == adapter.current_ability(Object)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
data/spec/simple_spec_helper.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lolita
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ITHouse (Latvia) and Arturs Meisters
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-03-
|
11
|
+
date: 2014-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: kaminari
|
@@ -329,6 +329,7 @@ files:
|
|
329
329
|
- lib/lolita/extensions/authorization/cancan_adapter.rb
|
330
330
|
- lib/lolita/extensions/authorization/default_adapter.rb
|
331
331
|
- lib/lolita/extensions/authorization/proxy.rb
|
332
|
+
- lib/lolita/extensions/authorization/pundit_adapter.rb
|
332
333
|
- lib/lolita/extensions/extensions.rb
|
333
334
|
- lib/lolita/helpers.rb
|
334
335
|
- lib/lolita/hooks.rb
|
@@ -383,6 +384,7 @@ files:
|
|
383
384
|
- spec/extensions/authorization/cancan_adapter_spec.rb
|
384
385
|
- spec/extensions/authorization/default_adapter_spec.rb
|
385
386
|
- spec/extensions/authorization/proxy_spec.rb
|
387
|
+
- spec/extensions/authorization/pundit_adapter_spec.rb
|
386
388
|
- spec/extensions/extensions_spec.rb
|
387
389
|
- spec/fabricators/category_fabricator.rb
|
388
390
|
- spec/fabricators/post_fabricator.rb
|
@@ -552,6 +554,7 @@ test_files:
|
|
552
554
|
- spec/extensions/authorization/cancan_adapter_spec.rb
|
553
555
|
- spec/extensions/authorization/default_adapter_spec.rb
|
554
556
|
- spec/extensions/authorization/proxy_spec.rb
|
557
|
+
- spec/extensions/authorization/pundit_adapter_spec.rb
|
555
558
|
- spec/extensions/extensions_spec.rb
|
556
559
|
- spec/fabricators/category_fabricator.rb
|
557
560
|
- spec/fabricators/post_fabricator.rb
|