monty 0.1.0 → 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/.gitignore +1 -0
- data/README.md +79 -4
- data/Rakefile +2 -1
- data/lib/monty.rb +18 -8
- data/lib/monty/access.rb +10 -10
- data/lib/monty/delivery.rb +80 -0
- data/lib/monty/permission.rb +12 -12
- data/lib/monty/resource.rb +54 -0
- data/lib/monty/watch.rb +2 -23
- data/test/monty/test_access.rb +8 -8
- data/test/monty/test_permission.rb +13 -13
- data/test/monty/test_resource.rb +47 -0
- data/test/monty/test_watch.rb +47 -2
- metadata +7 -7
- data/lib/monty/controller.rb +0 -35
- data/monty.gemspec +0 -68
- data/test/monty/test_controller.rb +0 -47
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,82 @@
|
|
1
|
-
|
1
|
+
monty
|
2
|
+
=============
|
2
3
|
|
3
|
-
|
4
|
+
Rack based authorization system.
|
4
5
|
|
5
|
-
|
6
|
+
[Yard docs](http://yardoc.org/docs/stonean-monty)
|
7
|
+
|
8
|
+
[RSpec Rails Helpers](http://github.com/stonean/monty-rspec-rails)
|
9
|
+
|
10
|
+
More to come, but here's the gist for rails 2.3.5:
|
11
|
+
|
12
|
+
In your environment.rb add:
|
13
|
+
|
14
|
+
require 'monty'
|
15
|
+
config.middleware.insert_after ActionController::ParamsParser, Monty::Watch
|
16
|
+
|
17
|
+
There may be other positions in the middleware stack that will work, I've tested this one.
|
18
|
+
|
19
|
+
Then you'll need to define your access rules. Create a file called authorization.rb in app/models.
|
20
|
+
|
21
|
+
Here's an example:
|
22
|
+
|
23
|
+
class Authorization
|
24
|
+
extend Monty::Access
|
25
|
+
|
26
|
+
# This creates the following regex matching: \/posts(\/.*)?
|
27
|
+
# Allows: /posts, /posts/, /posts/<any method>
|
28
|
+
permission 'posts'
|
29
|
+
|
30
|
+
# This creates the following regex matching: \/posts(?!\/(destroy))(\/.*)?
|
31
|
+
# Not allowed: /posts/destroy
|
32
|
+
# Allows: /posts, /posts/, /posts/<any method but destroy>
|
33
|
+
permission 'posts' do
|
34
|
+
resource 'posts' do
|
35
|
+
except 'destroy'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# This creates the following regex matching: \/posts\/(show|edit|update)
|
40
|
+
# Only allows: /posts/show, /posts/edit and /posts/update
|
41
|
+
permission 'posts' do
|
42
|
+
resource 'posts' do
|
43
|
+
only 'show', 'edit', 'update'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Permissions can have more than one resource
|
48
|
+
permission 'public' do
|
49
|
+
resource 'posts'
|
50
|
+
resource 'welcome'
|
51
|
+
resource 'feeds'
|
52
|
+
end
|
53
|
+
|
54
|
+
permission 'my_account' do
|
55
|
+
resource 'users' do
|
56
|
+
only 'show', 'edit', 'update'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# To make one of the above permissions public
|
61
|
+
public_access 'public'
|
62
|
+
|
63
|
+
# To make one of the above permissions protected
|
64
|
+
protected_access 'my_account'
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
Monty only has the concept of public and protected right now. After you have authenticated your user, you'll need to have some code in your resource that looks like:
|
69
|
+
|
70
|
+
session[:access_rights] = Monty.authenticated_access
|
71
|
+
|
72
|
+
Don't forget to reset your session when the user logs out.
|
73
|
+
|
74
|
+
Ummm, I think that's it for now. Let me know if you have any questions.
|
75
|
+
|
76
|
+
This project is the replacement for Lockdown.
|
77
|
+
|
78
|
+
Note on Patches/Pull Requests
|
79
|
+
=============
|
6
80
|
|
7
81
|
* Fork the project.
|
8
82
|
* Make your feature addition or bug fix.
|
@@ -12,6 +86,7 @@ Description goes here.
|
|
12
86
|
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
13
87
|
* Send me a pull request. Bonus points for topic branches.
|
14
88
|
|
15
|
-
|
89
|
+
Copyright
|
90
|
+
=============
|
16
91
|
|
17
92
|
Copyright (c) 2010 Andrew Stone. See LICENSE for details.
|
data/Rakefile
CHANGED
data/lib/monty.rb
CHANGED
@@ -3,17 +3,27 @@
|
|
3
3
|
$:.unshift(File.dirname(__FILE__))
|
4
4
|
|
5
5
|
module Monty
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
class << self
|
7
|
+
# App version
|
8
|
+
def version
|
9
|
+
'0.2.0'
|
10
|
+
end
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
end
|
12
|
+
# @return [Regexp] with \A \z boundaries
|
13
|
+
def regex(string)
|
14
|
+
Regexp.new(/\A#{string}\z/)
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [String] concatentation of public_access + "|" + protected_access
|
18
|
+
def authenticated_access
|
19
|
+
Monty::Configuration.public_access + "|" + Monty::Configuration.protected_access
|
20
|
+
end
|
21
|
+
end # class block
|
22
|
+
end # Monty
|
14
23
|
|
15
24
|
require 'monty/configuration'
|
16
25
|
require 'monty/watch'
|
17
|
-
require 'monty/
|
26
|
+
require 'monty/delivery'
|
27
|
+
require 'monty/resource'
|
18
28
|
require 'monty/permission'
|
19
29
|
require 'monty/access'
|
data/lib/monty/access.rb
CHANGED
@@ -3,30 +3,30 @@
|
|
3
3
|
module Monty
|
4
4
|
module Access
|
5
5
|
# Define permision that defines how your application is accessed.
|
6
|
-
# # All methods on the site
|
6
|
+
# # All methods on the site resource will be open to users who have
|
7
7
|
# # this permission.
|
8
8
|
# permission :public_pages do
|
9
|
-
#
|
9
|
+
# resource :site
|
10
10
|
# end
|
11
11
|
#
|
12
|
-
# # Can use multiple
|
12
|
+
# # Can use multiple resource statements
|
13
13
|
# permission :public_pages do
|
14
|
-
#
|
15
|
-
#
|
14
|
+
# resource :site
|
15
|
+
# resource :posts
|
16
16
|
# end
|
17
17
|
#
|
18
|
-
# # Only methods show, edit and update on the users
|
18
|
+
# # Only methods show, edit and update on the users resource will
|
19
19
|
# # be open to users who have this permission.
|
20
20
|
# permission :my_account_pages do
|
21
|
-
#
|
21
|
+
# resource :users do
|
22
22
|
# only :show, :edit, :update
|
23
23
|
# end
|
24
24
|
# end
|
25
25
|
#
|
26
|
-
# # All methods except destroy on the users
|
26
|
+
# # All methods except destroy on the users resource will be
|
27
27
|
# # open to users who have this permission.
|
28
28
|
# permission :manage_users do
|
29
|
-
#
|
29
|
+
# resource :users do
|
30
30
|
# except :destroy
|
31
31
|
# end
|
32
32
|
# end
|
@@ -38,7 +38,7 @@ module Monty
|
|
38
38
|
if block_given?
|
39
39
|
permission.instance_eval(&block)
|
40
40
|
else
|
41
|
-
permission.
|
41
|
+
permission.resource(permission.name)
|
42
42
|
end
|
43
43
|
|
44
44
|
unless Monty::Configuration.has_permission?(permission)
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
$:.unshift(File.dirname(__FILE__))
|
4
|
+
|
5
|
+
module Monty
|
6
|
+
class Delivery
|
7
|
+
# env['REQUEST_PATH'] || env['PATH_INFO']
|
8
|
+
attr_accessor :path
|
9
|
+
# env['REQUEST_METHOD']
|
10
|
+
attr_accessor :method
|
11
|
+
# session[:access_rights]
|
12
|
+
attr_accessor :access_rights
|
13
|
+
|
14
|
+
def initialize(env)
|
15
|
+
@path = env['REQUEST_PATH'] || env['PATH_INFO']
|
16
|
+
@method = (env['REQUEST_METHOD'] || 'GET').to_s.downcase.to_sym
|
17
|
+
@post_body = env['rack.input']
|
18
|
+
session = env['rack.session'] || {}
|
19
|
+
@access_rights = session[:access_rights] || Monty::Configuration.public_access
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [true|false] if the given path and method are allowed
|
23
|
+
def allowed?
|
24
|
+
return true if @path == '/'
|
25
|
+
|
26
|
+
begin
|
27
|
+
::Authorization.configure
|
28
|
+
rescue NameError
|
29
|
+
end
|
30
|
+
|
31
|
+
@access_rights_regex = Monty.regex(@access_rights)
|
32
|
+
|
33
|
+
@access_rights_regex.match(@path) || verb_match?
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
# Methods like create and update are determined by the HTTP verb.
|
39
|
+
# If the request is against the root resource path and the REQUEST_METHOD
|
40
|
+
# is POST, determine if the user has access rights to /create or
|
41
|
+
# /update (if _method=put)
|
42
|
+
#
|
43
|
+
# @return [true|false] if request is allowed when considering the HTTP verb
|
44
|
+
def verb_match?
|
45
|
+
|
46
|
+
return false if @method == :get || !Monty::Resource.regex.match(@path)
|
47
|
+
|
48
|
+
@path += "/" unless @path =~ /\/$/
|
49
|
+
|
50
|
+
if @method == :post
|
51
|
+
if put?
|
52
|
+
@access_rights_regex.match("#{@path}update")
|
53
|
+
else
|
54
|
+
@access_rights_regex.match("#{@path}create")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# In Rails, :put method is determined by _method parameter
|
60
|
+
def put?
|
61
|
+
request_query_params.include?('_method=put')
|
62
|
+
end
|
63
|
+
|
64
|
+
# Set request_query_params instance variable if not set
|
65
|
+
def request_query_params
|
66
|
+
@request_query_params ||= parse_request_query_params
|
67
|
+
end
|
68
|
+
|
69
|
+
# Parse out the query params
|
70
|
+
def parse_request_query_params
|
71
|
+
query_params = []
|
72
|
+
if @post_body
|
73
|
+
post_body_string = @post_body.read
|
74
|
+
query_params = post_body_string.split('&')
|
75
|
+
@post_body.rewind if @post_body.respond_to?(:rewind)
|
76
|
+
end
|
77
|
+
query_params
|
78
|
+
end
|
79
|
+
end # Delivery
|
80
|
+
end # Monty
|
data/lib/monty/permission.rb
CHANGED
@@ -4,27 +4,27 @@ module Monty
|
|
4
4
|
class Permission
|
5
5
|
# Name of permission
|
6
6
|
attr_accessor :name
|
7
|
-
# Array of
|
8
|
-
attr_accessor :
|
7
|
+
# Array of resource objects that define the access rights for this permission
|
8
|
+
attr_accessor :resources
|
9
9
|
|
10
10
|
# @param [String,Symbol] name permission reference.
|
11
11
|
def initialize(name)
|
12
12
|
@name = name.to_s
|
13
|
-
@
|
13
|
+
@resources = []
|
14
14
|
end
|
15
15
|
|
16
|
-
# @param [String,Symbol] name
|
17
|
-
# @return new
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
-
@
|
22
|
-
|
16
|
+
# @param [String,Symbol] name resource reference.
|
17
|
+
# @return new resource
|
18
|
+
def resource(name, &block)
|
19
|
+
resource = Monty::Resource.new(name)
|
20
|
+
resource.instance_eval(&block) if block_given?
|
21
|
+
@resources << resource
|
22
|
+
resource
|
23
23
|
end
|
24
24
|
|
25
|
-
# @return String representing all
|
25
|
+
# @return String representing all resources defining this permission
|
26
26
|
def regex_pattern
|
27
|
-
|
27
|
+
resources.collect{|r| "(#{r.regex_pattern})"}.join("|")
|
28
28
|
end
|
29
29
|
end # Permission
|
30
30
|
end # Monty
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Monty
|
4
|
+
class Resource
|
5
|
+
class << self
|
6
|
+
attr_accessor :resources, :resources_regex
|
7
|
+
|
8
|
+
# When a new resource is created, this method is called to register the root
|
9
|
+
def register_regex(resource)
|
10
|
+
resource = "(#{resource})"
|
11
|
+
@resources << resource unless @resources.include?(resource)
|
12
|
+
end
|
13
|
+
|
14
|
+
# @return [Regexp] created from resources' base regex
|
15
|
+
def regex
|
16
|
+
@resources_regex ||= Monty.regex(@resources.join("|"))
|
17
|
+
end
|
18
|
+
end # class block
|
19
|
+
|
20
|
+
# Initialize resources to empty array
|
21
|
+
@resources = []
|
22
|
+
|
23
|
+
# Name of the resource
|
24
|
+
attr_accessor :name
|
25
|
+
# Regular expression pattern
|
26
|
+
attr_accessor :regex_pattern
|
27
|
+
# The only methods restricted on the resource
|
28
|
+
attr_accessor :exceptions
|
29
|
+
# The only methods allowed on the resource
|
30
|
+
attr_accessor :inclusions
|
31
|
+
|
32
|
+
|
33
|
+
# @param [String,Symbol] name resource reference.
|
34
|
+
def initialize(name)
|
35
|
+
@name = name.to_s
|
36
|
+
@regex_pattern = "\/#{@name}(\/.*)?"
|
37
|
+
self.class.register_regex(@regex_pattern)
|
38
|
+
end
|
39
|
+
|
40
|
+
# @param *[String,Symbol] only methods restricted on the resource
|
41
|
+
def except(*methods)
|
42
|
+
return if methods.empty?
|
43
|
+
@exceptions = methods.collect{|m| m.to_s}
|
44
|
+
@regex_pattern = "\/#{@name}(?!\/(#{@exceptions.join('|')}))(\/.*)?"
|
45
|
+
end
|
46
|
+
|
47
|
+
# @param *[String,Symbol] only methods allowed on the resource
|
48
|
+
def only(*methods)
|
49
|
+
return if methods.empty?
|
50
|
+
@inclusions = methods.collect{|m| m.to_s}
|
51
|
+
@regex_pattern = "\/#{@name}\/(#{@inclusions.join('|')})(\/)?"
|
52
|
+
end
|
53
|
+
end # Resource
|
54
|
+
end # Monty
|
data/lib/monty/watch.rb
CHANGED
@@ -15,8 +15,9 @@ module Monty
|
|
15
15
|
|
16
16
|
# Authorize request. Redirect if access is denied.
|
17
17
|
def _call(env)
|
18
|
+
delivery = Monty::Delivery.new(env)
|
18
19
|
|
19
|
-
unless allowed?
|
20
|
+
unless delivery.allowed?
|
20
21
|
return [302, redirect_headers, []]
|
21
22
|
end
|
22
23
|
|
@@ -25,28 +26,6 @@ module Monty
|
|
25
26
|
|
26
27
|
private
|
27
28
|
|
28
|
-
# @return [True,False] created from value of rack.session[:access_rights]
|
29
|
-
def allowed?(env)
|
30
|
-
path = env['PATH_INFO']
|
31
|
-
|
32
|
-
return true if path == '/'
|
33
|
-
|
34
|
-
access_rights(env).match(path)
|
35
|
-
end
|
36
|
-
|
37
|
-
# @return [Regexp] created from value of rack.session[:access_rights]
|
38
|
-
def access_rights(env)
|
39
|
-
begin
|
40
|
-
::Authorization.configure
|
41
|
-
rescue NameError
|
42
|
-
end
|
43
|
-
|
44
|
-
session = env['rack.session'] || {}
|
45
|
-
regex_string = session[:access_rights] || Monty::Configuration.public_access
|
46
|
-
|
47
|
-
Regexp.new(/\A#{regex_string}\z/)
|
48
|
-
end
|
49
|
-
|
50
29
|
def redirect_headers
|
51
30
|
{'Location' => Monty::Configuration.access_denied_path, 'Content-Type' => 'text/html'}
|
52
31
|
end
|
data/test/monty/test_access.rb
CHANGED
@@ -11,22 +11,22 @@ class TestMontyAccess < Test::Unit::TestCase
|
|
11
11
|
assert_respond_to self, :permission
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
14
|
+
def test_permission_with_single_resource
|
15
15
|
perm = permission(:my_perm) do
|
16
|
-
|
16
|
+
resource :my_resource
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
assert_equal '
|
21
|
-
assert_equal "\/
|
19
|
+
resource = perm.resources.first
|
20
|
+
assert_equal 'my_resource', resource.name
|
21
|
+
assert_equal "\/my_resource(\/.*)?", resource.regex_pattern
|
22
22
|
end
|
23
23
|
|
24
24
|
def test_permission_without_block
|
25
25
|
perm = permission(:users)
|
26
26
|
|
27
|
-
|
28
|
-
assert_equal 'users',
|
29
|
-
assert_equal "\/users(\/.*)?",
|
27
|
+
resource = perm.resources.first
|
28
|
+
assert_equal 'users', resource.name
|
29
|
+
assert_equal "\/users(\/.*)?", resource.regex_pattern
|
30
30
|
end
|
31
31
|
|
32
32
|
def test_public_access
|
@@ -8,35 +8,35 @@ class TestMontyPermission < Test::Unit::TestCase
|
|
8
8
|
|
9
9
|
def test_initializer_sets_correct_state
|
10
10
|
assert_equal @permission.name, 'my_account'
|
11
|
-
assert_equal @permission.
|
11
|
+
assert_equal @permission.resources, []
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
15
|
-
@permission.
|
14
|
+
def test_resource
|
15
|
+
@permission.resource(:users)
|
16
16
|
|
17
|
-
|
18
|
-
assert_equal
|
17
|
+
resource = @permission.resources.first
|
18
|
+
assert_equal resource.name, 'users'
|
19
19
|
end
|
20
20
|
|
21
|
-
def
|
22
|
-
@permission.
|
21
|
+
def test_resource_with_block
|
22
|
+
@permission.resource(:users) do
|
23
23
|
except :destroy
|
24
24
|
end
|
25
25
|
|
26
|
-
|
27
|
-
assert_equal
|
26
|
+
resource = @permission.resources.first
|
27
|
+
assert_equal resource.exceptions, ['destroy']
|
28
28
|
end
|
29
29
|
|
30
30
|
|
31
31
|
def test_regex_pattern
|
32
|
-
@permission.
|
32
|
+
@permission.resource(:users)
|
33
33
|
|
34
34
|
assert_equal @permission.regex_pattern, "(\/users(\/.*)?)"
|
35
35
|
end
|
36
36
|
|
37
|
-
def
|
38
|
-
@permission.
|
39
|
-
@permission.
|
37
|
+
def test_regex_pattern_with_multiple_resources
|
38
|
+
@permission.resource(:users)
|
39
|
+
@permission.resource(:posts)
|
40
40
|
|
41
41
|
assert_equal @permission.regex_pattern, "(\/users(\/.*)?)|(\/posts(\/.*)?)"
|
42
42
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestMontyResource < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@resource = Monty::Resource.new(:users)
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_initializer_sets_correct_state
|
10
|
+
assert_equal @resource.name, 'users'
|
11
|
+
assert_equal @resource.regex_pattern, "\/users(\/.*)?"
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_except_sets_correct_regex_pattern
|
15
|
+
@resource.except(:destroy)
|
16
|
+
assert_equal @resource.regex_pattern, "\/users(?!\/(destroy))(\/.*)?"
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_except_with_multiple_params_sets_correct_regex_pattern
|
20
|
+
@resource.except(:index, :destroy)
|
21
|
+
assert_equal @resource.regex_pattern, "\/users(?!\/(index|destroy))(\/.*)?"
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_except_with_no_params_preserves_regex_pattern
|
25
|
+
resource = Monty::Resource.new(:users)
|
26
|
+
resource.except()
|
27
|
+
assert_equal resource.regex_pattern, "\/users(\/.*)?"
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_only_sets_correct_regex_pattern
|
31
|
+
@resource.only(:index)
|
32
|
+
assert_equal @resource.regex_pattern, "\/users\/(index)(\/)?"
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_only_with_multiple_params_sets_correct_regex_pattern
|
36
|
+
@resource.only(:show, :edit)
|
37
|
+
assert_equal @resource.regex_pattern, "\/users\/(show|edit)(\/)?"
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_only_with_no_params_preserves_regex_pattern
|
41
|
+
resource = Monty::Resource.new(:users)
|
42
|
+
resource.only()
|
43
|
+
assert_equal resource.regex_pattern, "\/users(\/.*)?"
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
data/test/monty/test_watch.rb
CHANGED
@@ -56,7 +56,7 @@ class TestMonty < Test::Unit::TestCase
|
|
56
56
|
|
57
57
|
def test_it_allows_uri_access_to_only_show
|
58
58
|
Authorization.permission :posts do
|
59
|
-
|
59
|
+
resource :posts do
|
60
60
|
only :show
|
61
61
|
end
|
62
62
|
end
|
@@ -80,7 +80,7 @@ class TestMonty < Test::Unit::TestCase
|
|
80
80
|
|
81
81
|
def test_it_allows_uri_access_to_all_except_show
|
82
82
|
Authorization.permission :posts do
|
83
|
-
|
83
|
+
resource :posts do
|
84
84
|
except :show
|
85
85
|
end
|
86
86
|
end
|
@@ -100,6 +100,51 @@ class TestMonty < Test::Unit::TestCase
|
|
100
100
|
|
101
101
|
get '/posts/edit', {}
|
102
102
|
assert last_response.ok?
|
103
|
+
|
104
|
+
get '/posts/edit/', {}
|
105
|
+
assert last_response.ok?
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_it_allows_uri_access_to_create_as_post
|
109
|
+
Authorization.permission :posts do
|
110
|
+
resource :posts do
|
111
|
+
only :new, :create
|
112
|
+
end
|
113
|
+
end
|
114
|
+
Authorization.public_access :posts
|
115
|
+
|
116
|
+
post '/posts', {}
|
117
|
+
assert last_response.ok?
|
118
|
+
|
119
|
+
post '/posts/', {}
|
120
|
+
assert last_response.ok?
|
121
|
+
|
122
|
+
get '/posts/new', {}
|
123
|
+
assert last_response.ok?
|
124
|
+
|
125
|
+
get '/posts/new/', {}
|
126
|
+
assert last_response.ok?
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_it_allows_uri_access_to_update_as_put
|
130
|
+
Authorization.permission :posts do
|
131
|
+
resource :posts do
|
132
|
+
only :show, :edit, :update
|
133
|
+
end
|
134
|
+
end
|
135
|
+
Authorization.public_access :posts
|
136
|
+
|
137
|
+
post '/posts', {:_method => "put"}
|
138
|
+
assert last_response.ok?
|
139
|
+
|
140
|
+
post '/posts/', {:_method => "put"}
|
141
|
+
assert last_response.ok?
|
142
|
+
|
143
|
+
get '/posts/show', {}
|
144
|
+
assert last_response.ok?
|
145
|
+
|
146
|
+
get '/posts/show/', {}
|
147
|
+
assert last_response.ok?
|
103
148
|
end
|
104
149
|
end
|
105
150
|
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
7
|
+
- 2
|
8
8
|
- 0
|
9
|
-
version: 0.
|
9
|
+
version: 0.2.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- stonean
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-05-
|
17
|
+
date: 2010-05-19 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -48,15 +48,15 @@ files:
|
|
48
48
|
- lib/monty.rb
|
49
49
|
- lib/monty/access.rb
|
50
50
|
- lib/monty/configuration.rb
|
51
|
-
- lib/monty/
|
51
|
+
- lib/monty/delivery.rb
|
52
52
|
- lib/monty/permission.rb
|
53
|
+
- lib/monty/resource.rb
|
53
54
|
- lib/monty/watch.rb
|
54
|
-
- monty.gemspec
|
55
55
|
- test/helper.rb
|
56
56
|
- test/monty/test_access.rb
|
57
57
|
- test/monty/test_configuration.rb
|
58
|
-
- test/monty/test_controller.rb
|
59
58
|
- test/monty/test_permission.rb
|
59
|
+
- test/monty/test_resource.rb
|
60
60
|
- test/monty/test_watch.rb
|
61
61
|
- test/rcov.opts
|
62
62
|
- test/test_monty.rb
|
@@ -93,8 +93,8 @@ summary: Rack based authorization system
|
|
93
93
|
test_files:
|
94
94
|
- test/helper.rb
|
95
95
|
- test/monty/test_configuration.rb
|
96
|
-
- test/monty/test_controller.rb
|
97
96
|
- test/monty/test_access.rb
|
98
97
|
- test/monty/test_watch.rb
|
99
98
|
- test/monty/test_permission.rb
|
99
|
+
- test/monty/test_resource.rb
|
100
100
|
- test/test_monty.rb
|
data/lib/monty/controller.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Monty
|
4
|
-
class Controller
|
5
|
-
# Name of the controller
|
6
|
-
attr_accessor :name
|
7
|
-
# Regular expression pattern
|
8
|
-
attr_accessor :regex_pattern
|
9
|
-
# The only methods restricted on the controller
|
10
|
-
attr_accessor :exceptions
|
11
|
-
# The only methods allowed on the controller
|
12
|
-
attr_accessor :inclusions
|
13
|
-
|
14
|
-
|
15
|
-
# @param [String,Symbol] name controller reference.
|
16
|
-
def initialize(name)
|
17
|
-
@name = name.to_s
|
18
|
-
@regex_pattern = "\/#{@name}(\/.*)?"
|
19
|
-
end
|
20
|
-
|
21
|
-
# @param *[String,Symbol] only methods restricted on the controller
|
22
|
-
def except(*methods)
|
23
|
-
return if methods.empty?
|
24
|
-
@exceptions = methods.collect{|m| m.to_s}
|
25
|
-
@regex_pattern = "\/#{@name}(?!\/(#{@exceptions.join('|')}))(\/.*)?"
|
26
|
-
end
|
27
|
-
|
28
|
-
# @param *[String,Symbol] only methods allowed on the controller
|
29
|
-
def only(*methods)
|
30
|
-
return if methods.empty?
|
31
|
-
@inclusions = methods.collect{|m| m.to_s}
|
32
|
-
@regex_pattern = "\/#{@name}\/(#{@inclusions.join('|')})"
|
33
|
-
end
|
34
|
-
end # Controller
|
35
|
-
end # Monty
|
data/monty.gemspec
DELETED
@@ -1,68 +0,0 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
-
# -*- encoding: utf-8 -*-
|
5
|
-
|
6
|
-
Gem::Specification.new do |s|
|
7
|
-
s.name = %q{monty}
|
8
|
-
s.version = "0.1.0"
|
9
|
-
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = ["stonean"]
|
12
|
-
s.date = %q{2010-05-05}
|
13
|
-
s.description = %q{Rack based authoriztion system.}
|
14
|
-
s.email = %q{andy@stonean.com}
|
15
|
-
s.extra_rdoc_files = [
|
16
|
-
"LICENSE",
|
17
|
-
"README.md"
|
18
|
-
]
|
19
|
-
s.files = [
|
20
|
-
".gitignore",
|
21
|
-
"LICENSE",
|
22
|
-
"README.md",
|
23
|
-
"Rakefile",
|
24
|
-
"lib/monty.rb",
|
25
|
-
"lib/monty/access.rb",
|
26
|
-
"lib/monty/configuration.rb",
|
27
|
-
"lib/monty/controller.rb",
|
28
|
-
"lib/monty/permission.rb",
|
29
|
-
"lib/monty/watch.rb",
|
30
|
-
"monty.gemspec",
|
31
|
-
"test/helper.rb",
|
32
|
-
"test/monty/test_access.rb",
|
33
|
-
"test/monty/test_configuration.rb",
|
34
|
-
"test/monty/test_controller.rb",
|
35
|
-
"test/monty/test_permission.rb",
|
36
|
-
"test/monty/test_watch.rb",
|
37
|
-
"test/rcov.opts",
|
38
|
-
"test/test_monty.rb"
|
39
|
-
]
|
40
|
-
s.homepage = %q{http://github.com/stonean/monty}
|
41
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
42
|
-
s.require_paths = ["lib"]
|
43
|
-
s.rubygems_version = %q{1.3.6}
|
44
|
-
s.summary = %q{Rack based authorization system}
|
45
|
-
s.test_files = [
|
46
|
-
"test/helper.rb",
|
47
|
-
"test/monty/test_configuration.rb",
|
48
|
-
"test/monty/test_controller.rb",
|
49
|
-
"test/monty/test_access.rb",
|
50
|
-
"test/monty/test_watch.rb",
|
51
|
-
"test/monty/test_permission.rb",
|
52
|
-
"test/test_monty.rb"
|
53
|
-
]
|
54
|
-
|
55
|
-
if s.respond_to? :specification_version then
|
56
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
57
|
-
s.specification_version = 3
|
58
|
-
|
59
|
-
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
60
|
-
s.add_development_dependency(%q<mocha>, [">= 0.9.8"])
|
61
|
-
else
|
62
|
-
s.add_dependency(%q<mocha>, [">= 0.9.8"])
|
63
|
-
end
|
64
|
-
else
|
65
|
-
s.add_dependency(%q<mocha>, [">= 0.9.8"])
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
@@ -1,47 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
class TestMontyController < Test::Unit::TestCase
|
4
|
-
|
5
|
-
def setup
|
6
|
-
@controller = Monty::Controller.new(:users)
|
7
|
-
end
|
8
|
-
|
9
|
-
def test_initializer_sets_correct_state
|
10
|
-
assert_equal @controller.name, 'users'
|
11
|
-
assert_equal @controller.regex_pattern, "\/users(\/.*)?"
|
12
|
-
end
|
13
|
-
|
14
|
-
def test_except_sets_correct_regex_pattern
|
15
|
-
@controller.except(:destroy)
|
16
|
-
assert_equal @controller.regex_pattern, "\/users(?!\/(destroy))(\/.*)?"
|
17
|
-
end
|
18
|
-
|
19
|
-
def test_except_with_multiple_params_sets_correct_regex_pattern
|
20
|
-
@controller.except(:index, :destroy)
|
21
|
-
assert_equal @controller.regex_pattern, "\/users(?!\/(index|destroy))(\/.*)?"
|
22
|
-
end
|
23
|
-
|
24
|
-
def test_except_with_no_params_preserves_regex_pattern
|
25
|
-
controller = Monty::Controller.new(:users)
|
26
|
-
controller.except()
|
27
|
-
assert_equal controller.regex_pattern, "\/users(\/.*)?"
|
28
|
-
end
|
29
|
-
|
30
|
-
def test_only_sets_correct_regex_pattern
|
31
|
-
@controller.only(:index)
|
32
|
-
assert_equal @controller.regex_pattern, "\/users\/(index)"
|
33
|
-
end
|
34
|
-
|
35
|
-
def test_only_with_multiple_params_sets_correct_regex_pattern
|
36
|
-
@controller.only(:show, :edit)
|
37
|
-
assert_equal @controller.regex_pattern, "\/users\/(show|edit)"
|
38
|
-
end
|
39
|
-
|
40
|
-
def test_only_with_no_params_preserves_regex_pattern
|
41
|
-
controller = Monty::Controller.new(:users)
|
42
|
-
controller.only()
|
43
|
-
assert_equal controller.regex_pattern, "\/users(\/.*)?"
|
44
|
-
end
|
45
|
-
|
46
|
-
end
|
47
|
-
|