johnsbrn-has_permission 0.1.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/VERSION.yml +4 -0
- data/lib/active_record/has/permission.rb +61 -0
- data/lib/has_permission.rb +5 -0
- data/lib/permission/base.rb +37 -0
- data/lib/permission_exception.rb +2 -0
- data/test/has_permission_test.rb +66 -0
- data/test/test_helper.rb +53 -0
- metadata +63 -0
data/VERSION.yml
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module Has
|
3
|
+
module Permission
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
|
10
|
+
def has_permission(options = {})
|
11
|
+
class_eval <<-_DEF
|
12
|
+
def self.permission_namespace
|
13
|
+
"#{options[:namespace] || 'Permission'}"
|
14
|
+
end
|
15
|
+
_DEF
|
16
|
+
extend ActiveRecord::Has::Permission::SingletonMethods
|
17
|
+
include ActiveRecord::Has::Permission::InstanceMethods
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
module SingletonMethods
|
23
|
+
|
24
|
+
def with_permission(user)
|
25
|
+
permission_class.new :user => user, :object => self
|
26
|
+
end
|
27
|
+
|
28
|
+
def permission_class
|
29
|
+
if respond_to?(:base_class)
|
30
|
+
begin
|
31
|
+
[permission_namespace, "#{self.to_s}Permission"].join('::').constantize
|
32
|
+
rescue
|
33
|
+
[permission_namespace ,"#{self.base_class.to_s}Permission"].join('::').constantize
|
34
|
+
end
|
35
|
+
elsif respond_to?(:proxy_reflection)
|
36
|
+
begin
|
37
|
+
[permission_namespace, "#{self.proxy_reflection.class_name}Permsission"].join('::').constantize
|
38
|
+
rescue
|
39
|
+
[permission_namespace, "#{self.proxy_reflection.class_name.constantize.base_class.to_s}Permission"].join('::').constantize
|
40
|
+
end
|
41
|
+
else
|
42
|
+
begin
|
43
|
+
[permission_namespace, "#{self.to_s}Permission"].join('::').constantize
|
44
|
+
rescue
|
45
|
+
[permission_namespace, "#{self.superclass.to_s}Permission"].join('::').constantize
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
module InstanceMethods
|
52
|
+
|
53
|
+
def with_permission(user)
|
54
|
+
self.class.permission_class.new :user => user, :object => self
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Permission
|
2
|
+
class Base
|
3
|
+
require 'forwardable'
|
4
|
+
extend Forwardable
|
5
|
+
|
6
|
+
# delegate important object methods so they don't return the values for the proxy - am I missing any??
|
7
|
+
def_delegators :@object, :==, :=~, :class, :enum_for, :eql?, :new, :freeze, :frozen?,
|
8
|
+
:hash, :id, :instance_of?, :is_a?, :kind_of?,
|
9
|
+
:method, :methods, :object_id, :respond_to?, :send,
|
10
|
+
:taint, :tainted?, :to_a, :to_enum, :to_s, :to_yaml, :to_yaml_properties, :to_yaml_style,
|
11
|
+
:type, :untaint
|
12
|
+
|
13
|
+
attr_accessor :user, :object
|
14
|
+
|
15
|
+
DEFAULT_FINDERS = /^((find|with).*|first|last|all|children|paginate|scoped|count)$/
|
16
|
+
DEFAULT_SEARCHES = /^search_.*/
|
17
|
+
|
18
|
+
def initialize(params)
|
19
|
+
@user = params[:user]
|
20
|
+
@object = params[:object]
|
21
|
+
end
|
22
|
+
|
23
|
+
def method_missing(method, *args)
|
24
|
+
object.send(method, *args)
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
|
29
|
+
def check_roles(user, roles, object)
|
30
|
+
roles.each do |role|
|
31
|
+
return true if user != nil && user.has_role?(user, object)
|
32
|
+
end
|
33
|
+
false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class HasPermissionTest < Test::Unit::TestCase
|
4
|
+
context "model instance" do
|
5
|
+
setup do
|
6
|
+
@model = Model.new
|
7
|
+
end
|
8
|
+
|
9
|
+
should "not intercept method" do
|
10
|
+
assert_equal "no permission", @model.some_method
|
11
|
+
end
|
12
|
+
|
13
|
+
should "intercept method" do
|
14
|
+
assert_equal "with permission", @model.with_permission(nil).some_method
|
15
|
+
end
|
16
|
+
|
17
|
+
should "use model id" do
|
18
|
+
assert_equal @model.id, @model.with_permission(nil).id
|
19
|
+
end
|
20
|
+
|
21
|
+
should "use model to_param" do
|
22
|
+
assert_equal @model.to_param, @model.with_permission(nil).to_param
|
23
|
+
end
|
24
|
+
|
25
|
+
should "use model class" do
|
26
|
+
assert_equal @model.class, @model.with_permission(nil).class
|
27
|
+
end
|
28
|
+
|
29
|
+
should "use model ==" do
|
30
|
+
assert @model.with_permission(nil) == @model
|
31
|
+
end
|
32
|
+
|
33
|
+
should "use model eql?" do
|
34
|
+
assert @model.with_permission(nil).eql?(@model)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
context "model class" do
|
40
|
+
should "not intercept method" do
|
41
|
+
assert_equal ["no permission"], Model.all
|
42
|
+
end
|
43
|
+
|
44
|
+
should "intercept method" do
|
45
|
+
assert_equal ["with permission"], Model.with_permission(nil).all
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
should "use default namespace setting" do
|
50
|
+
assert_equal Permission::ModelPermission, Model.permission_class
|
51
|
+
end
|
52
|
+
|
53
|
+
should "override default namespace setting" do
|
54
|
+
assert_equal ModelBPermission, ModelB.permission_class
|
55
|
+
end
|
56
|
+
|
57
|
+
should "use class to_s method" do
|
58
|
+
assert_equal Model.to_s, Model.with_permission(nil).to_s
|
59
|
+
end
|
60
|
+
|
61
|
+
should "use class class method" do
|
62
|
+
assert_equal Model.class, Model.with_permission(nil).class
|
63
|
+
end
|
64
|
+
|
65
|
+
# TODO need to test proxy associations somehow
|
66
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'shoulda'
|
4
|
+
require 'mocha'
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
7
|
+
require 'has_permission'
|
8
|
+
|
9
|
+
# this doesn't seem like the best way to do this - maybe someone will suggest a better method
|
10
|
+
class Model
|
11
|
+
|
12
|
+
include ActiveRecord::Has::Permission
|
13
|
+
|
14
|
+
has_permission
|
15
|
+
|
16
|
+
def some_method
|
17
|
+
"no permission"
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.all
|
21
|
+
["no permission"]
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
class ModelB
|
27
|
+
include ActiveRecord::Has::Permission
|
28
|
+
|
29
|
+
has_permission :namespace => ''
|
30
|
+
end
|
31
|
+
|
32
|
+
class ModelBPermission
|
33
|
+
end
|
34
|
+
|
35
|
+
module Permission
|
36
|
+
class ModelPermission < Permission::Base
|
37
|
+
|
38
|
+
def some_method
|
39
|
+
"with permission"
|
40
|
+
end
|
41
|
+
|
42
|
+
def method_missing(method, *args)
|
43
|
+
if method.to_s.match(DEFAULT_FINDERS)
|
44
|
+
["with permission"]
|
45
|
+
else
|
46
|
+
object.send(method, *args)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class Test::Unit::TestCase
|
53
|
+
end
|
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: johnsbrn-has_permission
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brian Johnson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-01-25 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Fine grained access control based on method interception. This is a proxy that allows you to define permissions on your models without breaking MVC by putting user code in your models.
|
17
|
+
email: github@brianjohnson.cc
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- VERSION.yml
|
26
|
+
- lib/active_record
|
27
|
+
- lib/active_record/has
|
28
|
+
- lib/active_record/has/permission.rb
|
29
|
+
- lib/has_permission.rb
|
30
|
+
- lib/permission
|
31
|
+
- lib/permission/base.rb
|
32
|
+
- lib/permission_exception.rb
|
33
|
+
- test/has_permission_test.rb
|
34
|
+
- test/test_helper.rb
|
35
|
+
has_rdoc: true
|
36
|
+
homepage: http://github.com/johnsbrn/has_permission
|
37
|
+
post_install_message:
|
38
|
+
rdoc_options:
|
39
|
+
- --inline-source
|
40
|
+
- --charset=UTF-8
|
41
|
+
require_paths:
|
42
|
+
- lib
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: "0"
|
48
|
+
version:
|
49
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
requirements: []
|
56
|
+
|
57
|
+
rubyforge_project:
|
58
|
+
rubygems_version: 1.2.0
|
59
|
+
signing_key:
|
60
|
+
specification_version: 2
|
61
|
+
summary: TODO
|
62
|
+
test_files: []
|
63
|
+
|