area_51 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ doc
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in area_54.gemspec
4
+ gemspec
File without changes
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "area_51/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "area_51"
7
+ s.version = Area51::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Chad Boyd"]
10
+ s.email = ["hoverlover@gmail.com"]
11
+ s.homepage = "https://github.com/hoverlover"
12
+ s.summary = %q{Gem used for simple path-based access control.}
13
+ s.description = %q{Area51 allows you to define restricted and unrestricted sections of your application by defining paths in your controllers.}
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+ end
@@ -0,0 +1,192 @@
1
+ module Area51
2
+ autoload :AuthorizationTrigger, 'area_51/authorization_trigger'
3
+
4
+ module ApiMethod
5
+
6
+ # This is the entry point into the Area51 library. Here are some usage examples:
7
+ #
8
+ # class ApplicationController < ActionController::Base
9
+ # area_51 do
10
+ # authorization_trigger("current_user.active?", :unrestricted) do
11
+ # restricted_area "^/memers_only"
12
+ # unrestricted_area "^/$"
13
+ # end
14
+ #
15
+ # authorization_trigger(true, :restricted) do
16
+ # restricted_area "/top/secret/path"
17
+ # unrestricted_area "/anyone_allowed"
18
+ # end
19
+ #
20
+ # trigger = proc {
21
+ # # Some useful trigger condition here
22
+ # }
23
+ # authorization_trigger(trigger) do
24
+ # unrestricted_area %r{^/totally_open}
25
+ # unrestricted_area %r{^/anyone_allowed$}
26
+ # end
27
+ # end
28
+ # end
29
+ #
30
+ # See documentation for authorization_trigger for details on how to use this method.
31
+ #
32
+ def area_51(&block)
33
+ self.send :extend, ClassMethods
34
+ self.send :include, InstanceMethods
35
+
36
+ self.default_access = :restricted
37
+ self.before_filter :area_51_check_access
38
+
39
+ yield
40
+ end
41
+ end
42
+
43
+ module ClassMethods
44
+
45
+ def self.extended(klass)
46
+ klass.cattr_accessor :authorization_trigger_paths
47
+ klass.cattr_accessor :authorization_triggers
48
+ klass.cattr_accessor :safe_zone
49
+ klass.cattr_accessor :default_access
50
+ end
51
+
52
+ # Defines a trigger condition that when met, will cause authorization
53
+ # to be performed.
54
+ #
55
+ # The +trigger+ can be either a String, +lambda+, or Proc.
56
+ # If a String, it will be +eval+'d, if a +lambda+ or Proc, it will
57
+ # be called, and anything else will be returned as-is. If the result
58
+ # does not return an explicit +true+, authorization will not be performed.
59
+ #
60
+ # The +default_access+ parameter, if provided, must be one of +:restricted+ or
61
+ # +:unrestricted+. The default is +:restricted+. This specifies what type
62
+ # of access the undefined areas will have. For example:
63
+ #
64
+ # area_51 do
65
+ # authorization_trigger("current_user.active?", :unrestricted) do
66
+ # restricted_area "^/memers_only"
67
+ # unrestricted_area "^/$"
68
+ # end
69
+ # end
70
+ #
71
+ # Now if a user tries to access a path that isn't defined above, they will be granted access
72
+ # due to the +:unrestricted+ parameter.
73
+ #
74
+ def authorization_trigger(trigger, default_access = nil, &block)
75
+ trigger = AuthorizationTrigger.new(trigger, default_access)
76
+
77
+ yield
78
+
79
+ self.authorization_triggers ||= {}
80
+ self.authorization_triggers[trigger] = self.authorization_trigger_paths.dup
81
+ self.authorization_trigger_paths.clear
82
+ end
83
+
84
+ # Ties a restricted path to the authorization trigger. Must be
85
+ # called within an authorization_trigger block:
86
+ #
87
+ # authorization_trigger("current_user.signed_in?") do
88
+ # restricted_area %r{/top/secret/path/}
89
+ # end
90
+ #
91
+ # +path+ can be either a String or a Regexp. If a String, it will
92
+ # be converted to a Regexp.
93
+ #
94
+ def restricted_area(path)
95
+ add_path_to_trigger_paths path, :restricted
96
+ end
97
+
98
+ # Ties an unrestricted path to the authorization trigger. Must be
99
+ # called within an authorization_trigger block:
100
+ #
101
+ # authorization_trigger("current_user.signed_in?") do
102
+ # unrestricted_area %r{/top/secret/path/}
103
+ # end
104
+ #
105
+ # +path+ can be either a String or a Regexp. If a String, it will
106
+ # be converted to a Regexp.
107
+ #
108
+ def unrestricted_area(path)
109
+ add_path_to_trigger_paths path, :unrestricted
110
+ end
111
+
112
+ private
113
+
114
+ def add_path_to_trigger_paths(path, type)
115
+ path = Regexp.new(path) if path.is_a? String
116
+
117
+ self.authorization_trigger_paths ||= {}
118
+ (self.authorization_trigger_paths[type] ||= []) << path
119
+ end
120
+ end
121
+
122
+ # This module contains methods which will be added as instance methods
123
+ # to your controller.
124
+ #
125
+ module InstanceMethods
126
+
127
+ # A +before_filter+ that checks if authorization is needed to access
128
+ # the current path. If authorization is needed, and it fails, the user
129
+ # is redirected to the safe_zone, or to root_path if safe_zone is not defined.
130
+ # It also sets +flash#notice+ with a message, which should be defined
131
+ # in a locale file with the key +:restricted+.
132
+ #
133
+ def area_51_check_access
134
+ if entering_unauthorized_area?(request.path)
135
+ flash.notice = I18n.t(:restricted)
136
+ redirect_to self.class.safe_zone || self.root_path
137
+ end
138
+ end
139
+
140
+ # Checks to see if the user is entering a restricted zone. It does this
141
+ # by enumerating through the list of configured authorization triggers
142
+ # for this controller. If one of them returns +true+, the paths tied
143
+ # to the trigger are checked against the current path.
144
+ #
145
+ # If the current path matches one of the paths configured for the trigger, and the access type
146
+ # for the trigger is +:restricted+, the method returns +true+. If it is
147
+ # +:unrestricted+, or the current path is the same as the safe_zone, it returns +false.
148
+ #
149
+ def entering_unauthorized_area?(path)
150
+ return false if path == self.class.safe_zone
151
+
152
+ self.class.authorization_triggers.any? do |trigger, paths|
153
+ if authorization_triggered? trigger
154
+
155
+ # Now that we know an authorization should be performed, let's do it!
156
+
157
+ if path.match(combined_paths(paths[:restricted]))
158
+ true
159
+ elsif path.match(combined_paths(paths[:unrestricted]))
160
+ false
161
+ else
162
+ trigger.default_access == :restricted
163
+ end
164
+ end
165
+ end
166
+ end
167
+
168
+ private
169
+
170
+ def combined_paths(paths)
171
+ paths ||= []
172
+ Regexp.union(*(paths.compact))
173
+ end
174
+
175
+ def authorization_triggered?(trigger)
176
+ trigger = trigger.body
177
+
178
+ case
179
+ when trigger.is_a?(String)
180
+ result = eval trigger
181
+ when trigger.respond_to?(:call)
182
+ result = trigger.call
183
+ else
184
+ result = trigger
185
+ end
186
+
187
+ !!result
188
+ end
189
+ end
190
+ end
191
+
192
+ ActionController::Base.send :extend, Area51::ApiMethod
@@ -0,0 +1,16 @@
1
+ module Area51
2
+ class AuthorizationTrigger
3
+ attr_accessor :default_access
4
+ attr_accessor :body
5
+
6
+ def initialize(body, default_access = nil)
7
+ @body = body
8
+
9
+ if [:restricted, :unrestricted].include?(default_access)
10
+ @default_access = default_access
11
+ else
12
+ @default_access = :restricted
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,3 @@
1
+ module Area51
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: area_51
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Chad Boyd
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-03-04 00:00:00 -06:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description: Area51 allows you to define restricted and unrestricted sections of your application by defining paths in your controllers.
18
+ email:
19
+ - hoverlover@gmail.com
20
+ executables: []
21
+
22
+ extensions: []
23
+
24
+ extra_rdoc_files: []
25
+
26
+ files:
27
+ - .gitignore
28
+ - Gemfile
29
+ - README.md
30
+ - Rakefile
31
+ - area_51.gemspec
32
+ - lib/area_51.rb
33
+ - lib/area_51/authorization_trigger.rb
34
+ - lib/area_51/version.rb
35
+ has_rdoc: true
36
+ homepage: https://github.com/hoverlover
37
+ licenses: []
38
+
39
+ post_install_message:
40
+ rdoc_options: []
41
+
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ requirements: []
57
+
58
+ rubyforge_project:
59
+ rubygems_version: 1.5.0
60
+ signing_key:
61
+ specification_version: 3
62
+ summary: Gem used for simple path-based access control.
63
+ test_files: []
64
+