reuser 1.0.0 → 2.0.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.
- data/lib/reuser/role.rb +19 -31
- data/lib/reuser/version.rb +6 -0
- data/lib/reuser.rb +37 -2
- data/spec/reuser/class_spec.rb +61 -0
- data/spec/reuser/instances_spec.rb +34 -0
- data/spec/reuser/role_spec.rb +49 -0
- data/spec/spec_helper.rb +5 -0
- metadata +14 -14
- data/README.md +0 -95
- data/Rakefile +0 -24
- data/lib/reuser/reuser.rb +0 -46
- data/spec/reuser/reuser_spec.rb +0 -65
- data/spec/reuser/test_reuser.rb +0 -22
- data/spec/reuser.rb +0 -1
data/lib/reuser/role.rb
CHANGED
@@ -1,46 +1,34 @@
|
|
1
|
-
require_relative('../reuser')
|
2
|
-
|
3
1
|
module ReUser
|
4
2
|
class Role
|
5
|
-
|
6
|
-
@name = name
|
7
|
-
@actions = {}
|
8
|
-
end
|
3
|
+
attr_reader :name
|
9
4
|
|
10
|
-
def
|
11
|
-
|
5
|
+
def permissions
|
6
|
+
@permissions.keys
|
12
7
|
end
|
13
8
|
|
14
|
-
def
|
15
|
-
|
9
|
+
def initialize name, permissions=[]
|
10
|
+
@name = name
|
11
|
+
@permissions = {}
|
12
|
+
self.can *permissions
|
16
13
|
end
|
17
14
|
|
18
|
-
def
|
19
|
-
|
20
|
-
|
15
|
+
def can *permissions
|
16
|
+
permissions.each do |permission|
|
17
|
+
@permissions[permission] = lambda {|*args| true }
|
21
18
|
end
|
22
19
|
end
|
23
20
|
|
24
|
-
def
|
25
|
-
|
26
|
-
if actions[name].is_a?(Proc)
|
27
|
-
actions[name].call(data)
|
28
|
-
else
|
29
|
-
true
|
30
|
-
end
|
31
|
-
end
|
21
|
+
def can? permission
|
22
|
+
@permissions[permission].is_a? Proc
|
32
23
|
end
|
33
24
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
end
|
39
|
-
@actions
|
40
|
-
end
|
25
|
+
def could permission, &block
|
26
|
+
raise "#could requires a block" unless block_given?
|
27
|
+
@permissions[permission] = block
|
28
|
+
end
|
41
29
|
|
42
|
-
|
43
|
-
|
44
|
-
|
30
|
+
def could? permission, block_args
|
31
|
+
@permissions[permission].call(block_args)
|
32
|
+
end
|
45
33
|
end
|
46
34
|
end
|
data/lib/reuser.rb
CHANGED
@@ -1,2 +1,37 @@
|
|
1
|
-
require_relative
|
2
|
-
|
1
|
+
require_relative "./reuser/role"
|
2
|
+
|
3
|
+
module ReUser
|
4
|
+
|
5
|
+
def self.included klass
|
6
|
+
|
7
|
+
klass.instance_eval do
|
8
|
+
def roles &block
|
9
|
+
@@roles ||= {}
|
10
|
+
yield if block_given?
|
11
|
+
@@roles.freeze.keys
|
12
|
+
end
|
13
|
+
|
14
|
+
def role name, permissions=[], &block
|
15
|
+
role = ( @@roles[name] ||= ReUser::Role.new(name, permissions) )
|
16
|
+
yield(role) if block_given?
|
17
|
+
role
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def can? permission
|
23
|
+
@role.can? permission
|
24
|
+
end
|
25
|
+
|
26
|
+
def cant? permission
|
27
|
+
!(can? permission)
|
28
|
+
end
|
29
|
+
|
30
|
+
def could? permission, block_args
|
31
|
+
@role.could? permission, block_args
|
32
|
+
end
|
33
|
+
|
34
|
+
def couldnt? permission, block_args
|
35
|
+
!(couldnt? permission, block_args)
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe "Classes including ReUser" do
|
4
|
+
let(:klass) do
|
5
|
+
kls = Class.new
|
6
|
+
kls.instance_eval do
|
7
|
+
include ReUser
|
8
|
+
|
9
|
+
roles do
|
10
|
+
role(:admin)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
kls
|
14
|
+
end
|
15
|
+
subject { klass }
|
16
|
+
|
17
|
+
context ".roles" do
|
18
|
+
it "optionally takes a block" do
|
19
|
+
lambda { subject.roles { :good } }.should_not raise_error
|
20
|
+
lambda { subject.roles }.should_not raise_error
|
21
|
+
end
|
22
|
+
|
23
|
+
it "returns an array of role names" do
|
24
|
+
subject.roles.should be_kind_of Array
|
25
|
+
subject.roles.all? {|el| el.is_a? Symbol}.should be_true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context ".role" do
|
30
|
+
|
31
|
+
it "takes a symbol" do
|
32
|
+
lambda { subject.role(:admin) }.should_not raise_error
|
33
|
+
end
|
34
|
+
|
35
|
+
it "takes a symbol, and an optional array" do
|
36
|
+
lambda { subject.role(:admin, [:read, :write]) }.should_not raise_error
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns a ReUser::Role instance" do
|
40
|
+
subject.role(:admin).should be_instance_of ReUser::Role
|
41
|
+
end
|
42
|
+
|
43
|
+
context "passing in a role that is already defined" do
|
44
|
+
it "returns the same role" do
|
45
|
+
expected = subject.role(:admin)
|
46
|
+
subject.role(:admin).should === expected
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "passing in a role that is not already defined" do
|
51
|
+
it "raises an error" do
|
52
|
+
subject.class_eval do
|
53
|
+
roles do
|
54
|
+
role(:admin)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
lambda { subject.role(:user) }.should raise_error
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe "Instances of a Class including ReUser" do
|
4
|
+
let(:klass) do
|
5
|
+
kls = Class.new
|
6
|
+
kls.instance_eval do
|
7
|
+
include ReUser
|
8
|
+
|
9
|
+
roles do
|
10
|
+
role :admin do |admin|
|
11
|
+
admin.can :read
|
12
|
+
admin.could :write do |language|
|
13
|
+
language == "English"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
kls
|
19
|
+
end
|
20
|
+
|
21
|
+
subject do
|
22
|
+
instance = klass.new
|
23
|
+
instance.instance_variable_set(:@role, klass.role(:admin))
|
24
|
+
instance
|
25
|
+
end
|
26
|
+
|
27
|
+
it "#can? and #could? are delegated to the ReUser::Role" do
|
28
|
+
true
|
29
|
+
end
|
30
|
+
|
31
|
+
it "#cant? and #couldnt? are negations of #can? and #could?" do
|
32
|
+
true
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe ReUser::Role do
|
4
|
+
subject do
|
5
|
+
role = ReUser::Role.new(:admin)
|
6
|
+
role.can(:read)
|
7
|
+
role
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'is initialized with a name, and optionally an array of permissions' do
|
11
|
+
role = ReUser::Role.new :admin
|
12
|
+
role.name.should == :admin
|
13
|
+
role.permissions.should == []
|
14
|
+
|
15
|
+
role = ReUser::Role.new :user
|
16
|
+
role.name.should == :user
|
17
|
+
role.permissions.should == []
|
18
|
+
|
19
|
+
role = ReUser::Role.new :user, [:read, :write]
|
20
|
+
role.name.should == :user
|
21
|
+
role.permissions.should == [:read, :write]
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'shares its name and permissions' do
|
25
|
+
its(:name) { should === :admin }
|
26
|
+
its(:permissions) { should === [:read] }
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'permissions are added and checked with #can and #can?' do
|
30
|
+
subject.can?(:read).should be_true
|
31
|
+
subject.can?(:write).should be_false
|
32
|
+
subject.can(:write)
|
33
|
+
subject.can?(:write).should be_true
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'you need to supply #could with a test block' do
|
37
|
+
lambda { subject.could(:read) }.should raise_error
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'conditional permissions are added and checked with #could and #could?' do
|
41
|
+
subject.can?(:write).should be_false
|
42
|
+
subject.could :write do |language|
|
43
|
+
language == "English"
|
44
|
+
end
|
45
|
+
subject.can?(:write).should be_true
|
46
|
+
subject.could?(:write, "Japanese").should be_false
|
47
|
+
subject.could?(:write, "English").should be_true
|
48
|
+
end
|
49
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reuser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,23 +9,22 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-02-03 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: ReUse is an Internal DSL for Ruby to create roles and manage actions.
|
15
|
-
email: isaacsanders
|
15
|
+
email: isaac@isaacsanders.com
|
16
16
|
executables: []
|
17
17
|
extensions: []
|
18
18
|
extra_rdoc_files: []
|
19
19
|
files:
|
20
20
|
- lib/reuser.rb
|
21
21
|
- lib/reuser/role.rb
|
22
|
-
- lib/reuser/
|
23
|
-
-
|
24
|
-
-
|
25
|
-
- spec/reuser.rb
|
26
|
-
- spec/reuser/
|
27
|
-
|
28
|
-
homepage: http://isaacsanders.github.com/reuser
|
22
|
+
- lib/reuser/version.rb
|
23
|
+
- spec/spec_helper.rb
|
24
|
+
- spec/reuser/class_spec.rb
|
25
|
+
- spec/reuser/role_spec.rb
|
26
|
+
- spec/reuser/instances_spec.rb
|
27
|
+
homepage: http://isaacbfsanders.com/reuser
|
29
28
|
licenses: []
|
30
29
|
post_install_message:
|
31
30
|
rdoc_options: []
|
@@ -45,11 +44,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
45
44
|
version: '0'
|
46
45
|
requirements: []
|
47
46
|
rubyforge_project:
|
48
|
-
rubygems_version: 1.8.
|
47
|
+
rubygems_version: 1.8.15
|
49
48
|
signing_key:
|
50
49
|
specification_version: 3
|
51
50
|
summary: An internal DSL for Ruby to make user role management simple.
|
52
51
|
test_files:
|
53
|
-
- spec/
|
54
|
-
- spec/reuser/
|
55
|
-
- spec/reuser/
|
52
|
+
- spec/spec_helper.rb
|
53
|
+
- spec/reuser/class_spec.rb
|
54
|
+
- spec/reuser/role_spec.rb
|
55
|
+
- spec/reuser/instances_spec.rb
|
data/README.md
DELETED
@@ -1,95 +0,0 @@
|
|
1
|
-
#ReUser
|
2
|
-
##Purpose
|
3
|
-
Whenever you start a web app where a user has specific permissions, do you
|
4
|
-
end up writing your own solution or using something that has brain-bending
|
5
|
-
abstractions? If so, ReUser is the solution for you.
|
6
|
-
##Description
|
7
|
-
ReUser is an Internal DSL for Ruby to create roles and manage actions.
|
8
|
-
##Usage
|
9
|
-
Installing ReUser is easy:
|
10
|
-
|
11
|
-
gem install reuser
|
12
|
-
|
13
|
-
Now to incorporate it into a model:
|
14
|
-
|
15
|
-
require 'reuser'
|
16
|
-
|
17
|
-
class User
|
18
|
-
include ReUser
|
19
|
-
|
20
|
-
roles do
|
21
|
-
|
22
|
-
# declare a role with the can method, taking a list of actions.
|
23
|
-
role(:admin).can :read, :write, :execute
|
24
|
-
|
25
|
-
role :user do |usr| # pass a block, so you can
|
26
|
-
usr.can :read
|
27
|
-
|
28
|
-
# declare a role, then declare a conditional action with could.
|
29
|
-
# could takes a list of names, then assigns a test to them.
|
30
|
-
# You can then ask your model:
|
31
|
-
##usr.could?(:write, 'un-owned-file')
|
32
|
-
###=> false
|
33
|
-
# or
|
34
|
-
##usr.could?(:write, 'owned-file')
|
35
|
-
###=> true
|
36
|
-
# could? will pass the second argument as the block's argument'
|
37
|
-
|
38
|
-
usr.could :write do |file|
|
39
|
-
usr.owns? file
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
# Or you can declare a role with the name, followed by an array of names
|
44
|
-
role :writer, [:read, :write]
|
45
|
-
|
46
|
-
# Then, you can declare a default, accessible by storing :default as
|
47
|
-
# your model's role, it will point to original role.
|
48
|
-
default :user
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
You can restrict the instances from doing things based on role:
|
53
|
-
|
54
|
-
def administrate
|
55
|
-
if @user.role? :admin
|
56
|
-
administer
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
Or based on their actions:
|
61
|
-
|
62
|
-
def do_something_risky
|
63
|
-
if @user.can?(:do_this)
|
64
|
-
do_it
|
65
|
-
else
|
66
|
-
tell_them_to_get_out!
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def do_something_with_obj
|
71
|
-
if @user.could?(:write, file)
|
72
|
-
write file
|
73
|
-
else
|
74
|
-
raise 'Not your file!'
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
##Issues?
|
79
|
-
Please don't hesitate to open up an issue. You can even contribute! Which
|
80
|
-
brings me to...
|
81
|
-
##Contributing!
|
82
|
-
This is open source, so I want others to help too. For now I have no plans
|
83
|
-
on adding too much more to this project, as far as functionality is
|
84
|
-
concerned, but don't let that get in your way of opening a request or forking
|
85
|
-
the project and adding something. I just ask that:
|
86
|
-
|
87
|
-
- You are polite about it.
|
88
|
-
- You test it.
|
89
|
-
- You explain it, or it is easy to read.
|
90
|
-
|
91
|
-
Following these will let us get along and make better software, quicker, and
|
92
|
-
with less bugs.(hypothetically)
|
93
|
-
|
94
|
-
I am still working on the final syntax, but we are getting closer. If you
|
95
|
-
have any suggestions on syntax, open a feature require
|
data/Rakefile
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
desc 'build the .gem file from gemspec'
|
2
|
-
task :build do
|
3
|
-
sh 'gem build reuser.gemspec'
|
4
|
-
end
|
5
|
-
|
6
|
-
desc 'install the gem from .gem file'
|
7
|
-
task :install do
|
8
|
-
sh 'gem install reuser-*.gem'
|
9
|
-
end
|
10
|
-
|
11
|
-
desc 'push the gem to rubygems.org'
|
12
|
-
task :push do
|
13
|
-
sh 'gem push reuser-*.gem'
|
14
|
-
end
|
15
|
-
|
16
|
-
desc 'make (build and install the gem from gemspec)'
|
17
|
-
task :make => [:build, :install]
|
18
|
-
|
19
|
-
require 'rspec/core/rake_task'
|
20
|
-
RSpec::Core::RakeTask.new(:spec) do |t|
|
21
|
-
t.rspec_opts = '--color'
|
22
|
-
end
|
23
|
-
|
24
|
-
task :default => :spec
|
data/lib/reuser/reuser.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
require_relative('../reuser')
|
2
|
-
|
3
|
-
module ReUser
|
4
|
-
class NoRoleError < StandardError; end;
|
5
|
-
class NoDefaultRoleError < StandardError; end;
|
6
|
-
instance_eval do
|
7
|
-
def included(subclass)
|
8
|
-
subclass.instance_eval do
|
9
|
-
def roles(&block)
|
10
|
-
@@roles ||= {}
|
11
|
-
yield if block
|
12
|
-
@@roles.freeze
|
13
|
-
@@roles.keys
|
14
|
-
end
|
15
|
-
|
16
|
-
def role(name, actions_list = nil, &block)
|
17
|
-
@@roles[name] ||= ReUser::Role.new(name)
|
18
|
-
role_name = @@roles[name]
|
19
|
-
yield(role_name) if block
|
20
|
-
if actions_list
|
21
|
-
role_name.can(*actions_list)
|
22
|
-
end
|
23
|
-
role_name
|
24
|
-
end
|
25
|
-
end
|
26
|
-
subclass.class_eval do
|
27
|
-
|
28
|
-
def can?(action)
|
29
|
-
!!@role.can?(action)
|
30
|
-
end
|
31
|
-
|
32
|
-
def cant?(action)
|
33
|
-
!@role.can?(action)
|
34
|
-
end
|
35
|
-
|
36
|
-
def could?(action, obj)
|
37
|
-
!!@role.could?(action, obj)
|
38
|
-
end
|
39
|
-
|
40
|
-
def couldnt?(action, obj)
|
41
|
-
!@role.could?(action, obj)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
data/spec/reuser/reuser_spec.rb
DELETED
@@ -1,65 +0,0 @@
|
|
1
|
-
require_relative 'test_reuser'
|
2
|
-
|
3
|
-
describe TestReUser do
|
4
|
-
context "has included the ReUser module" do
|
5
|
-
it "should be able to define roles with blocks" do
|
6
|
-
test_ru = TestReUser.new(:admin)
|
7
|
-
test_ru.can?(:read).should == true
|
8
|
-
end
|
9
|
-
|
10
|
-
it "should be able to define roles with arrays" do
|
11
|
-
test_ru = TestReUser.new(:admin)
|
12
|
-
test_ru.can?(:read).should == true
|
13
|
-
end
|
14
|
-
|
15
|
-
context "has defined the :admin and :user roles," do
|
16
|
-
context "is instantiated as test_ru" do
|
17
|
-
context "with role :user" do
|
18
|
-
before do
|
19
|
-
@test_ru = TestReUser.new(:user)
|
20
|
-
end
|
21
|
-
context " using the default role" do
|
22
|
-
it "should not be able to write" do
|
23
|
-
@test_ru.cant?(:write).should == true
|
24
|
-
end
|
25
|
-
|
26
|
-
it "should be able to read" do
|
27
|
-
@test_ru.can?(:read).should == true
|
28
|
-
end
|
29
|
-
|
30
|
-
it "should not be able to call methods restricted to `:admin` roles" do
|
31
|
-
class InsufficientPermissionsError < StandardError;end
|
32
|
-
TestReUser.class_eval do
|
33
|
-
def foo
|
34
|
-
if @role == :admin
|
35
|
-
:something
|
36
|
-
else
|
37
|
-
raise InsufficientPermissionsError, "You can't do that!"
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
lambda {@test_ru.foo}.should raise_error(InsufficientPermissionsError)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
it "should be able to execute on a 1 object." do
|
47
|
-
@test_ru.could?(:execute, 1).should == true
|
48
|
-
@test_ru.couldnt?(:execute, 3).should == true
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
context "set role to :admin" do
|
53
|
-
before do
|
54
|
-
@test_ru = TestReUser.new :admin
|
55
|
-
end
|
56
|
-
it "should be able to read, write, and execute" do
|
57
|
-
@test_ru.can?(:read).should == true
|
58
|
-
@test_ru.can?(:write).should == true
|
59
|
-
@test_ru.can?(:execute).should == true
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
data/spec/reuser/test_reuser.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
require_relative '../reuser'
|
2
|
-
|
3
|
-
class TestReUser
|
4
|
-
include ReUser
|
5
|
-
|
6
|
-
roles do
|
7
|
-
role(:admin).can(:read, :write, :execute)
|
8
|
-
role(:user) do |usr|
|
9
|
-
usr.can :read
|
10
|
-
|
11
|
-
usr.could :execute do |obj|
|
12
|
-
obj == 1
|
13
|
-
end
|
14
|
-
end
|
15
|
-
role :writer, :write
|
16
|
-
role :sysadmin, [:write, :execute]
|
17
|
-
end
|
18
|
-
|
19
|
-
def initialize(name)
|
20
|
-
@role = TestReUser.role(name)
|
21
|
-
end
|
22
|
-
end
|
data/spec/reuser.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require_relative '../lib/reuser'
|