lolita 3.3.9 → 3.4.0
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.
- 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
|