reuser 0.2.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/README.md ADDED
@@ -0,0 +1,75 @@
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
+ role(:admin).can :read, :write, :execute
22
+ role :user do |usr|
23
+ usr.can :read
24
+ usr.could :write {|obj| usr.owns?(obj)}
25
+ usr.cant :execute
26
+ end
27
+ role :writer, [:read, :write]
28
+ default :user
29
+ end
30
+ end
31
+
32
+ You can restrict the instances from doing things based on role:
33
+
34
+ def administrate
35
+ if @user.role? :admin
36
+ administer
37
+ end
38
+ end
39
+
40
+ Or based on their actions:
41
+
42
+ def do_something_risky
43
+ if @user.can?(:do_this)
44
+ do_it
45
+ else
46
+ tell_them_to_get_out!
47
+ end
48
+ end
49
+
50
+ def do_something_with_obj
51
+ if @user.could?(:write, file)
52
+ write file
53
+ else
54
+ raise 'Not your file!'
55
+ end
56
+ end
57
+
58
+ ##Issues?
59
+ Please don't hesitate to open up an issue. You can even contribute! Which
60
+ brings me to...
61
+ ##Contributing!
62
+ This is open source, so I want others to help too. For now I have no plans
63
+ on adding too much more to this project, as far as functionality is
64
+ concerned, but don't let that get in your way of opening a request or forking
65
+ the project and adding something. I just ask that:
66
+
67
+ - You are polite about it.
68
+ - You test it.
69
+ - You explain it, or it is easy to read.
70
+
71
+ Following these will let us get along and make better software, quicker, and
72
+ with less bugs.(hypothetically)
73
+
74
+ I am still working on the final syntax, but we are getting closer. If you
75
+ have any suggestions on syntax, open a feature require
data/Rakefile ADDED
@@ -0,0 +1,24 @@
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
+ desc 'run all the specs in the `spec/` directory.'
20
+ task :spec do
21
+ Dir.glob('./spec/reuser/**/*.rb').each do |file|
22
+ sh "rspec #{file}"
23
+ end
24
+ end
@@ -0,0 +1,70 @@
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
+ @@roles = {}
10
+ def roles(&block)
11
+ @@roles ||= {}
12
+ yield if block
13
+ @@roles.freeze
14
+ @@roles.keys
15
+ end
16
+
17
+ def role(name, actions_list = nil, &block)
18
+ @@roles[name] ||= ReUser::Role.new(name)
19
+ role_name = @@roles[name]
20
+ yield(role_name) if block
21
+ if actions_list
22
+ role_name.can(*actions_list)
23
+ end
24
+ role_name
25
+ end
26
+
27
+ def default(name = nil)
28
+ if name
29
+ @@roles[:default] = @@roles[name]
30
+ else
31
+ @@roles[:default]
32
+ end
33
+ end
34
+ end
35
+ subclass.class_eval do
36
+
37
+ def role(name = nil)
38
+ if name
39
+ if @@roles[name]
40
+ @role = @@roles[name]
41
+ else
42
+ raise NoRoleError, "No role #{name} defined for #{self}"
43
+ end
44
+ end
45
+ @role
46
+ end
47
+
48
+ def role?(name)
49
+ role == self.class.role(name)
50
+ end
51
+
52
+ def can?(name)
53
+ !!role.can?(name)
54
+ end
55
+
56
+ def cant?(name)
57
+ !role.can?(name)
58
+ end
59
+
60
+ def could?(name, obj)
61
+ role.could?(name, obj)
62
+ end
63
+
64
+ def couldnt?(name, obj)
65
+ !role.could?(name, obj)
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,43 @@
1
+ require_relative('../reuser')
2
+
3
+ module ReUser
4
+ class Role
5
+ attr_reader :actions
6
+
7
+ def initialize(name)
8
+ @actions = {}
9
+ end
10
+
11
+ def can(*names)
12
+ names.each do |name|
13
+ action(name)
14
+ end
15
+ end
16
+
17
+ def can?(name)
18
+ actions[name]
19
+ end
20
+
21
+ def could(*names, &test)
22
+ names.each do |name|
23
+ action(name, test)
24
+ end
25
+ end
26
+
27
+ def could?(name, data)
28
+ @actions[name].call(data)
29
+ end
30
+
31
+ private
32
+ def actions(*names)
33
+ names.each do |name|
34
+ action(name)
35
+ end
36
+ @actions
37
+ end
38
+
39
+ def action(name, test = true)
40
+ @actions[name] = test
41
+ end
42
+ end
43
+ end
data/lib/reuser.rb ADDED
@@ -0,0 +1,2 @@
1
+ require_relative(reuser_file = './reuser/reuser')
2
+ require_relative(role_file = './reuser/role')
@@ -0,0 +1,97 @@
1
+ require 'rspec'
2
+ require 'pry'
3
+ require_relative '../reuser'
4
+
5
+ class TestReUser
6
+ include ReUser
7
+
8
+ roles do
9
+ role(:admin).can(:read, :write, :execute)
10
+ role(:user) do |usr|
11
+ usr.can :read
12
+
13
+ usr.could :execute, :read do |obj|
14
+ obj == 1
15
+ end
16
+ end
17
+ role :writer, :write
18
+ role :sysadmin, [:write, :execute]
19
+ default(:user)
20
+ end
21
+
22
+ def initialize(name = :default)
23
+ @role = role(name)
24
+ end
25
+ end
26
+ REUSER_METHODS = [:roles,
27
+ :role,
28
+ :role?,
29
+ :default,
30
+ :can?,
31
+ :cant?,
32
+ :could?,
33
+ :couldnt?].sort
34
+
35
+ describe TestReUser do
36
+ context "has included the ReUser module" do
37
+ it "should be able to define roles with blocks" do
38
+ test_ru = TestReUser.new(:admin)
39
+ test_ru.can?(:read).should == true
40
+ end
41
+
42
+ it "should be able to define roles with arrays" do
43
+ test_ru = TestReUser.new(:admin)
44
+ test_ru.can?(:read).should == true
45
+ end
46
+
47
+ context "has defined the :admin and :user roles," do
48
+ context "is instantiated as test_ru" do
49
+ context "set :user to the default" do
50
+ before do
51
+ @test_ru = TestReUser.new
52
+ end
53
+ context " using the default role" do
54
+ it "should not be able to write" do
55
+ @test_ru.cant?(:write).should == true
56
+ end
57
+
58
+ it "should be able to read" do
59
+ @test_ru.can?(:read).should == true
60
+ end
61
+
62
+ it "should not be able to call methods restricted to `:admin` roles" do
63
+ class InsufficientPermissionsError < StandardError;end
64
+ TestReUser.class_eval do
65
+ def foo
66
+ if @role == :admin
67
+ :something
68
+ else
69
+ raise InsufficientPermissionsError, "You can't do that!"
70
+ end
71
+ end
72
+ end
73
+
74
+ lambda {@test_ru.foo}.should raise_error(InsufficientPermissionsError)
75
+ end
76
+ end
77
+
78
+ it "should be able to execute on a 1 object." do
79
+ @test_ru.could?(:execute, 1).should == true
80
+ @test_ru.couldnt?(:execute, 3).should == true
81
+ end
82
+ end
83
+
84
+ context "set role to :admin" do
85
+ before do
86
+ @test_ru = TestReUser.new :admin
87
+ end
88
+ it "should be able to read, write, and execute" do
89
+ @test_ru.can?(:read).should == true
90
+ @test_ru.can?(:write).should == true
91
+ @test_ru.can?(:execute).should == true
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
data/spec/reuser.rb ADDED
@@ -0,0 +1 @@
1
+ require_relative '../lib/reuser'
metadata ADDED
@@ -0,0 +1,53 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: reuser
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Isaac Sanders
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-10-12 00:00:00.000000000Z
13
+ dependencies: []
14
+ description: ReUse is an Internal DSL for Ruby to create roles and manage actions.
15
+ email: isaacsanders@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/reuser.rb
21
+ - lib/reuser/role.rb
22
+ - lib/reuser/reuser.rb
23
+ - Rakefile
24
+ - README.md
25
+ - spec/reuser.rb
26
+ - spec/reuser/reuser.rb
27
+ homepage: http://isaacsanders.github.com/reuser
28
+ licenses: []
29
+ post_install_message:
30
+ rdoc_options: []
31
+ require_paths:
32
+ - lib
33
+ required_ruby_version: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ required_rubygems_version: !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubyforge_project:
47
+ rubygems_version: 1.8.10
48
+ signing_key:
49
+ specification_version: 3
50
+ summary: An internal DSL for Ruby to make user role management simple.
51
+ test_files:
52
+ - spec/reuser.rb
53
+ - spec/reuser/reuser.rb