reuser 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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