rolypoly 0.0.1
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.
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +74 -0
- data/Rakefile +6 -0
- data/lib/rolypoly/controller_role_dsl.rb +77 -0
- data/lib/rolypoly/role_gatekeeper.rb +81 -0
- data/lib/rolypoly/version.rb +3 -0
- data/lib/rolypoly.rb +2 -0
- data/rolypoly.gemspec +24 -0
- data/spec/lib/rolypoly/controller_role_dsl_spec.rb +58 -0
- data/spec/lib/rolypoly/role_gatekeeper_spec.rb +105 -0
- data/spec/spec_helper.rb +16 -0
- metadata +119 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rolypoly
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-1.9.3-p448
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Jon Phenow
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Rolypoly
|
2
|
+
|
3
|
+
Allow certain roles access to certain controller actions.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'rolypoly'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
```bash
|
16
|
+
$> bundle
|
17
|
+
```
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
class ApplicationController < ActionController::Base
|
23
|
+
def current_roles
|
24
|
+
current_user.roles
|
25
|
+
end
|
26
|
+
|
27
|
+
rescue_from(Rolypoly::FailedRoleCheckError) do
|
28
|
+
render text: "Failed Authorization!", status: 401
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class UsersController < ApplicationController
|
33
|
+
include Rolypoly::ControllerRoleDSL
|
34
|
+
|
35
|
+
def index
|
36
|
+
# ...
|
37
|
+
end
|
38
|
+
restrict(:index).to(:admin)
|
39
|
+
# OR
|
40
|
+
allow(:admin).to_access(:index)
|
41
|
+
|
42
|
+
# Do a bunch at once
|
43
|
+
allow(:scorekeeper, :official).to_access(:show, :score)
|
44
|
+
def show
|
45
|
+
# ...
|
46
|
+
end
|
47
|
+
|
48
|
+
def score
|
49
|
+
# ...
|
50
|
+
end
|
51
|
+
|
52
|
+
# Allow admin role to access all actions of this controller
|
53
|
+
allow(:admin).to_all
|
54
|
+
|
55
|
+
# Make action public
|
56
|
+
restrict(:landing).to_none
|
57
|
+
publicize :landing
|
58
|
+
|
59
|
+
def landing
|
60
|
+
# ...
|
61
|
+
end
|
62
|
+
|
63
|
+
# Give up and make all public
|
64
|
+
all_public
|
65
|
+
end
|
66
|
+
```
|
67
|
+
|
68
|
+
## Contributing
|
69
|
+
|
70
|
+
1. Fork it
|
71
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
72
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
73
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
74
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'rolypoly/role_gatekeeper'
|
2
|
+
module Rolypoly
|
3
|
+
FailedRoleCheckError = Class.new StandardError
|
4
|
+
module ControllerRoleDSL
|
5
|
+
def self.included(sub)
|
6
|
+
sub.send :extend, ClassMethods
|
7
|
+
sub.before_filter(:rolypoly_check_role_access!) if sub.respond_to? :before_filter
|
8
|
+
if sub.respond_to? :rescue_from
|
9
|
+
sub.rescue_from(FailedRoleCheckError) do
|
10
|
+
respond_to do |f|
|
11
|
+
f.html { render text: "Not Authorized", status: 401 }
|
12
|
+
f.json { render json: { error: "Not Authorized" }, status: 401 }
|
13
|
+
f.xml { render xml: { error: "Not Authorized" }, status: 401 }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def rolypoly_check_role_access!
|
20
|
+
failed_role_check! unless rolypoly_role_access?
|
21
|
+
end
|
22
|
+
|
23
|
+
def current_roles # OVERRIDE
|
24
|
+
[]
|
25
|
+
end
|
26
|
+
|
27
|
+
def failed_role_check!
|
28
|
+
raise Rolypoly::FailedRoleCheckError
|
29
|
+
end
|
30
|
+
|
31
|
+
def rolypoly_role_access?
|
32
|
+
rolypoly_gatekeepers.any? { |gatekeeper|
|
33
|
+
gatekeeper.allow? current_roles, action_name
|
34
|
+
}
|
35
|
+
end
|
36
|
+
private :rolypoly_role_access?
|
37
|
+
|
38
|
+
def rolypoly_gatekeepers
|
39
|
+
self.class.rolypoly_gatekeepers
|
40
|
+
end
|
41
|
+
private :rolypoly_gatekeepers
|
42
|
+
|
43
|
+
module ClassMethods
|
44
|
+
def all_public
|
45
|
+
build_gatekeeper(nil, nil).all_public
|
46
|
+
end
|
47
|
+
|
48
|
+
def restrict(*actions)
|
49
|
+
build_gatekeeper nil, actions
|
50
|
+
end
|
51
|
+
|
52
|
+
def allow(*roles)
|
53
|
+
build_gatekeeper roles, nil
|
54
|
+
end
|
55
|
+
|
56
|
+
def publicize(*actions)
|
57
|
+
restrict(*actions).to_none
|
58
|
+
end
|
59
|
+
|
60
|
+
def rolypoly_gatekeepers
|
61
|
+
@rolypoly_gatekeepers ||= []
|
62
|
+
end
|
63
|
+
|
64
|
+
def build_gatekeeper(roles, actions)
|
65
|
+
RoleGatekeeper.new(roles, actions).tap { |gatekeeper|
|
66
|
+
rolypoly_gatekeepers << gatekeeper
|
67
|
+
}
|
68
|
+
end
|
69
|
+
private :build_gatekeeper
|
70
|
+
|
71
|
+
def rolypoly_gatekeepers=(arry)
|
72
|
+
@rolypoly_gatekeepers = Array(arry)
|
73
|
+
end
|
74
|
+
private :rolypoly_gatekeepers=
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'set'
|
2
|
+
module Rolypoly
|
3
|
+
class RoleGatekeeper
|
4
|
+
def initialize(roles, actions)
|
5
|
+
self.roles = Set.new Array(roles).map(&:to_s)
|
6
|
+
self.actions = Set.new Array(actions).map(&:to_s)
|
7
|
+
self.all_actions = false
|
8
|
+
self.public = false
|
9
|
+
end
|
10
|
+
|
11
|
+
# restrict(*actions).to *roles
|
12
|
+
def to(*roles)
|
13
|
+
self.roles = self.roles.merge roles.flatten.compact.map(&:to_s)
|
14
|
+
end
|
15
|
+
|
16
|
+
# make actions public basically
|
17
|
+
# restrict(:index).to_none
|
18
|
+
def to_none
|
19
|
+
self.public = true
|
20
|
+
end
|
21
|
+
|
22
|
+
# allow(*roles).to_access *actions
|
23
|
+
def to_access(*actions)
|
24
|
+
self.actions = self.actions.merge actions.flatten.compact.map(&:to_s)
|
25
|
+
end
|
26
|
+
|
27
|
+
# allow role access to all actions
|
28
|
+
# allow(*roles).to_all
|
29
|
+
def to_all
|
30
|
+
self.all_actions = true
|
31
|
+
end
|
32
|
+
|
33
|
+
def allow?(current_roles, action)
|
34
|
+
action?(action) &&
|
35
|
+
role?(current_roles)
|
36
|
+
end
|
37
|
+
|
38
|
+
def all_public
|
39
|
+
self.public = true
|
40
|
+
self.all_actions = true
|
41
|
+
end
|
42
|
+
|
43
|
+
protected # self.attr= gets mad
|
44
|
+
attr_accessor :roles
|
45
|
+
attr_accessor :actions
|
46
|
+
attr_accessor :all_actions
|
47
|
+
attr_accessor :public
|
48
|
+
|
49
|
+
def role?(check_roles)
|
50
|
+
check_roles = Set.new Array(check_roles).map(&:to_s)
|
51
|
+
public? || !(check_roles & roles).empty?
|
52
|
+
end
|
53
|
+
private :role?
|
54
|
+
|
55
|
+
def action?(check_actions)
|
56
|
+
check_actions = Set.new Array(check_actions).map(&:to_s)
|
57
|
+
all_actions? || !(check_actions & actions).empty?
|
58
|
+
end
|
59
|
+
private :action?
|
60
|
+
|
61
|
+
def can_set_with_to?
|
62
|
+
roles.empty?
|
63
|
+
end
|
64
|
+
private :can_set_with_to?
|
65
|
+
|
66
|
+
def can_set_with_access_to?
|
67
|
+
actions.empty?
|
68
|
+
end
|
69
|
+
private :can_set_with_access_to?
|
70
|
+
|
71
|
+
def public?
|
72
|
+
!!public
|
73
|
+
end
|
74
|
+
private :public?
|
75
|
+
|
76
|
+
def all_actions?
|
77
|
+
!!all_actions
|
78
|
+
end
|
79
|
+
private :all_actions?
|
80
|
+
end
|
81
|
+
end
|
data/lib/rolypoly.rb
ADDED
data/rolypoly.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rolypoly/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rolypoly"
|
8
|
+
spec.version = Rolypoly::VERSION
|
9
|
+
spec.authors = ["Jon Phenow"]
|
10
|
+
spec.email = ["j.phenow@gmail.com"]
|
11
|
+
spec.description = %q{Tools for handling per-action and per-app Role authorization}
|
12
|
+
spec.summary = %q{Tools for handling per-action and per-app Role authorization}
|
13
|
+
spec.homepage = "https://github.com/sportngin/rolypoly"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Rolypoly
|
3
|
+
describe ControllerRoleDSL do
|
4
|
+
let(:example_controller) do
|
5
|
+
Class.new do
|
6
|
+
include Rolypoly::ControllerRoleDSL
|
7
|
+
end
|
8
|
+
end
|
9
|
+
after { example_controller.instance_variable_set("@rolypoly_gatekeepers", nil) }
|
10
|
+
subject { example_controller }
|
11
|
+
it { should respond_to :restrict }
|
12
|
+
it { should respond_to :allow }
|
13
|
+
|
14
|
+
describe "setting up with DSL" do
|
15
|
+
describe "from allow side" do
|
16
|
+
let(:controller_instance) { subject.new }
|
17
|
+
let(:current_roles) { [:admin] }
|
18
|
+
before do
|
19
|
+
subject.allow(:admin).to_access(:index)
|
20
|
+
subject.publicize(:landing)
|
21
|
+
controller_instance.stub current_roles: current_roles, action_name: action_name
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#index" do
|
25
|
+
let(:action_name) { "index" }
|
26
|
+
it "allows admin access" do
|
27
|
+
expect { controller_instance.rolypoly_check_role_access! }
|
28
|
+
.not_to raise_error
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#show" do
|
33
|
+
let(:action_name) { "show" }
|
34
|
+
it "disallows admin access" do
|
35
|
+
expect { controller_instance.rolypoly_check_role_access! }
|
36
|
+
.to raise_error(Rolypoly::FailedRoleCheckError)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#landing" do
|
41
|
+
let(:action_name) { "landing" }
|
42
|
+
it "allows admin access" do
|
43
|
+
expect { controller_instance.rolypoly_check_role_access! }
|
44
|
+
.not_to raise_error
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "with no role" do
|
48
|
+
let(:current_roles) { [] }
|
49
|
+
it "allows admin access" do
|
50
|
+
expect { controller_instance.rolypoly_check_role_access! }
|
51
|
+
.not_to raise_error
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rolypoly/role_gatekeeper'
|
3
|
+
module Rolypoly
|
4
|
+
describe RoleGatekeeper do
|
5
|
+
let(:roles) { %w[admin scorekeeper] }
|
6
|
+
let(:actions) { %w[index show] }
|
7
|
+
|
8
|
+
subject { described_class.new roles, actions }
|
9
|
+
|
10
|
+
shared_examples_for "allow should behave correctly" do
|
11
|
+
it "shouldn't auto-allow" do
|
12
|
+
subject.allow?(nil, nil).should be_false
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should allow scorekeepr access to index" do
|
16
|
+
subject.allow?([:scorekeeper], "index").should be_true
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should not allow scorekeepr access to edit" do
|
20
|
+
subject.allow?([:scorekeeper], "edit").should be_false
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "all public" do
|
24
|
+
before do
|
25
|
+
subject.all_public
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should allow whatever" do
|
29
|
+
subject.allow?(nil, nil).should be_true
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should allow scorekeepr access to index" do
|
33
|
+
subject.allow?([:scorekeeper], "index").should be_true
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should allow scorekeepr access to edit" do
|
37
|
+
subject.allow?([:scorekeeper], "edit").should be_true
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "all roles" do
|
42
|
+
before do
|
43
|
+
subject.to_none
|
44
|
+
end
|
45
|
+
|
46
|
+
it "shouldn't auto-allow" do
|
47
|
+
subject.allow?(nil, nil).should be_false
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should allow scorekeepr access to index" do
|
51
|
+
subject.allow?([:janitor], "index").should be_true
|
52
|
+
subject.allow?([:admin], "index").should be_true
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should not allow scorekeepr access to edit" do
|
56
|
+
subject.allow?([:scorekeeper], "edit").should be_false
|
57
|
+
subject.allow?([:janitor], "edit").should be_false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "all actions" do
|
62
|
+
before do
|
63
|
+
subject.to_all
|
64
|
+
end
|
65
|
+
|
66
|
+
it "shouldn't auto-allow" do
|
67
|
+
subject.allow?(nil, nil).should be_false
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should allow scorekeepr access to index" do
|
71
|
+
subject.allow?([:scorekeeper], "index").should be_true
|
72
|
+
end
|
73
|
+
|
74
|
+
it "shouldn't allow janitor access to any" do
|
75
|
+
subject.allow?([:janitor], "index").should be_false
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should allow scorekeepr access to edit" do
|
79
|
+
subject.allow?([:scorekeeper], "edit").should be_true
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
it_should_behave_like "allow should behave correctly"
|
84
|
+
|
85
|
+
describe "with only roles set" do
|
86
|
+
let(:actions) { [] }
|
87
|
+
|
88
|
+
before do
|
89
|
+
subject.to_access(:index, :show)
|
90
|
+
end
|
91
|
+
|
92
|
+
it_should_behave_like "allow should behave correctly"
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "with only actions set" do
|
96
|
+
let(:roles) { [] }
|
97
|
+
|
98
|
+
before do
|
99
|
+
subject.to(:admin, :scorekeeper)
|
100
|
+
end
|
101
|
+
|
102
|
+
it_should_behave_like "allow should behave correctly"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
require 'rolypoly'
|
8
|
+
RSpec.configure do |config|
|
9
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
10
|
+
config.run_all_when_everything_filtered = true
|
11
|
+
config.filter_run :focus
|
12
|
+
|
13
|
+
# Run specific random order with `--seed 1234`
|
14
|
+
config.order = 'random'
|
15
|
+
config.color = true
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rolypoly
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jon Phenow
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-09-03 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.3'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.3'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: Tools for handling per-action and per-app Role authorization
|
63
|
+
email:
|
64
|
+
- j.phenow@gmail.com
|
65
|
+
executables: []
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files: []
|
68
|
+
files:
|
69
|
+
- .gitignore
|
70
|
+
- .rspec
|
71
|
+
- .ruby-gemset
|
72
|
+
- .ruby-version
|
73
|
+
- Gemfile
|
74
|
+
- LICENSE.txt
|
75
|
+
- README.md
|
76
|
+
- Rakefile
|
77
|
+
- lib/rolypoly.rb
|
78
|
+
- lib/rolypoly/controller_role_dsl.rb
|
79
|
+
- lib/rolypoly/role_gatekeeper.rb
|
80
|
+
- lib/rolypoly/version.rb
|
81
|
+
- rolypoly.gemspec
|
82
|
+
- spec/lib/rolypoly/controller_role_dsl_spec.rb
|
83
|
+
- spec/lib/rolypoly/role_gatekeeper_spec.rb
|
84
|
+
- spec/spec_helper.rb
|
85
|
+
homepage: https://github.com/sportngin/rolypoly
|
86
|
+
licenses:
|
87
|
+
- MIT
|
88
|
+
post_install_message:
|
89
|
+
rdoc_options: []
|
90
|
+
require_paths:
|
91
|
+
- lib
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
none: false
|
94
|
+
requirements:
|
95
|
+
- - ! '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
segments:
|
99
|
+
- 0
|
100
|
+
hash: -2134864263053242356
|
101
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
|
+
none: false
|
103
|
+
requirements:
|
104
|
+
- - ! '>='
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
segments:
|
108
|
+
- 0
|
109
|
+
hash: -2134864263053242356
|
110
|
+
requirements: []
|
111
|
+
rubyforge_project:
|
112
|
+
rubygems_version: 1.8.25
|
113
|
+
signing_key:
|
114
|
+
specification_version: 3
|
115
|
+
summary: Tools for handling per-action and per-app Role authorization
|
116
|
+
test_files:
|
117
|
+
- spec/lib/rolypoly/controller_role_dsl_spec.rb
|
118
|
+
- spec/lib/rolypoly/role_gatekeeper_spec.rb
|
119
|
+
- spec/spec_helper.rb
|