safety_patrol 0.5.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 ADDED
@@ -0,0 +1,18 @@
1
+ .DS_Store
2
+ *.gem
3
+ *.rbc
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in safety_patrol.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Thomas Brewer
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,91 @@
1
+ # SafetyPatrol (BETA)
2
+ Simple framework agnostic Authorization gem. It was heavily (start the copiers) influenced by the Authority gem, but I wanted a core authorization gem that was not tied to a specific web framework.
3
+
4
+ ## Installation
5
+
6
+ Add this line to your application's Gemfile:
7
+
8
+ gem 'safety_patrol'
9
+
10
+ And then execute:
11
+
12
+ $ bundle
13
+
14
+ Or install it yourself as:
15
+
16
+ $ gem install safety_patrol
17
+
18
+ ## Usage
19
+
20
+ #configure it
21
+ SafetyPatrol.configure |config|
22
+ #verb #adjective
23
+ config.abilities[:send] = :sendable
24
+
25
+ #the default abilities are:
26
+ #:create => :creatable
27
+ #:read => :readable
28
+ #:update => :updatable
29
+ #:delete => :deletable
30
+ end
31
+
32
+ #define a User class and include the SafetyPatrol::UserAbilities module
33
+ class User
34
+ include SafetyPatrol::UserAbilities
35
+ attr_accessor :role
36
+ def admin?
37
+ role == 'admin'
38
+ # or whatever logic fits your apps needs
39
+ end
40
+ end
41
+
42
+
43
+ #define a class that you want to provide authorization logic for
44
+ #and include SafetyPatrol::Abilities module and declare the authorizer class
45
+ class Article
46
+ include SafetyPatrol::Abilities
47
+ authorizer 'ArticleAuthorizer'
48
+ end
49
+
50
+ #define you authorizer class that contains the authorization logic
51
+ class ArticleAuthorizer
52
+
53
+ #define methods that follow the convention of adjective_by?(user, resource)
54
+
55
+ #these methods with receive the user and resource
56
+ def creatable_by?(user, article)
57
+ user.admin?
58
+ end
59
+ end
60
+
61
+ #check for a user's authorization
62
+ admin = User.new
63
+ admin.role = 'admin'
64
+
65
+ guest = User.new
66
+ guest.role = 'guest'
67
+
68
+ article = Article.new
69
+
70
+ guest.can_create?(article) # return false
71
+ admin.can_create?(article) # return true
72
+
73
+ article.creatable_by(admin) #return true
74
+ article.creatable_by(guest) #return false
75
+
76
+ #What everything boils down to is SafetyPatrol is just providing sugar on top of this:
77
+ authorizer = ArticleAuthorizer.new
78
+ authorizer.creatable_by?(admin, article) #return true
79
+
80
+
81
+ ##Todos
82
+ 1. Add more specs
83
+ 2. Repeat #1
84
+
85
+ ## Contributing
86
+
87
+ 1. Fork it
88
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
89
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
90
+ 4. Push to the branch (`git push origin my-new-feature`)
91
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,32 @@
1
+ require "safety_patrol/version"
2
+ require "safety_patrol/configuration"
3
+
4
+ module SafetyPatrol
5
+
6
+ class << self
7
+
8
+ def abilities
9
+ configuration.abilities.freeze
10
+ end
11
+
12
+ def verbs
13
+ abilities.keys
14
+ end
15
+
16
+ def adjectives
17
+ abilities.values
18
+ end
19
+
20
+ attr_accessor :configuration
21
+
22
+ def configure
23
+ self.configuration ||= Configuration.new
24
+ yield(configuration) if block_given?
25
+ require 'safety_patrol/user_abilities'
26
+ require 'safety_patrol/abilities'
27
+ configuration
28
+ end
29
+
30
+ end
31
+
32
+ end
@@ -0,0 +1,36 @@
1
+ module SafetyPatrol
2
+
3
+ module Abilities
4
+
5
+ def self.included(base)
6
+ base.extend ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+
11
+ attr_accessor :_authorizer
12
+
13
+ def authorizer(object = nil)
14
+ if object.nil?
15
+ self._authorizer
16
+ else
17
+ self._authorizer = (object.is_a?(String)) ? Kernel.const_get(object).new : object.new
18
+ end
19
+ end
20
+
21
+ end
22
+
23
+ SafetyPatrol.adjectives.each do |adjective|
24
+ define_method(("#{adjective}_by?").intern) do |user|
25
+ self.authorizer.send(("#{adjective}_by?").intern, user, self)
26
+ end
27
+ end
28
+
29
+ def authorizer
30
+ self.class.authorizer
31
+ end
32
+
33
+ end
34
+
35
+ end
36
+
@@ -0,0 +1,22 @@
1
+ module SafetyPatrol
2
+
3
+ class Configuration
4
+
5
+ attr_accessor :abilities
6
+
7
+ def initialize
8
+
9
+ @abilities = {
10
+ #verb #adjective
11
+ :create => :creatable,
12
+ :read => :readable,
13
+ :update => :updatable,
14
+ :delete => :deletable
15
+ }
16
+
17
+ end
18
+
19
+ end
20
+
21
+
22
+ end
@@ -0,0 +1,19 @@
1
+ module SafetyPatrol
2
+
3
+ module UserAbilities
4
+
5
+ #define some method on the user for convenience
6
+ SafetyPatrol.verbs.each do |verb|
7
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
8
+ def can_#{verb}?(resource)
9
+ resource.#{SafetyPatrol.abilities[verb]}_by?(self)
10
+ end
11
+ RUBY
12
+ end
13
+
14
+ end
15
+
16
+ end
17
+
18
+
19
+
@@ -0,0 +1,3 @@
1
+ module SafetyPatrol
2
+ VERSION = "0.5.0"
3
+ end
@@ -0,0 +1,18 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/safety_patrol/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Thomas Brewer"]
6
+ gem.email = ["tom@21purple.com"]
7
+ gem.description = %q{Simple framework agnostic Authorization gem}
8
+ gem.summary = gem.description
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "safety_patrol"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = SafetyPatrol::VERSION
17
+ gem.add_development_dependency('rspec')
18
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ class ArticleAuthorizer
4
+
5
+ def creatable_by?(user, resource)
6
+ true
7
+ end
8
+
9
+ end
10
+
11
+ class Article
12
+ include SafetyPatrol::Abilities
13
+ authorizer 'ArticleAuthorizer'
14
+ end
15
+
16
+ describe SafetyPatrol::Abilities do
17
+
18
+ it "should define methods on a class based upon the abilities hash" do
19
+ article = Article.new
20
+ lambda {
21
+ article.creatable_by?
22
+ }.should_not raise_exception(NoMethodError)
23
+ end
24
+
25
+ it "should have an associated Authorizer" do
26
+ Article.authorizer.should be_instance_of(ArticleAuthorizer)
27
+ end
28
+
29
+ it "should receive a creatable_by? call and return true or false" do
30
+ article = Article.new
31
+ user = double("User")
32
+ article.creatable_by?(user).should eq(true)
33
+ end
34
+
35
+ describe ArticleAuthorizer do
36
+
37
+ it "should receive a creatable_by?" do
38
+ article = Article.new
39
+ article.authorizer.should_receive(:creatable_by?)
40
+ user = double("User")
41
+ article.creatable_by?(user)
42
+ end
43
+ end
44
+
45
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ describe SafetyPatrol::Configuration do
5
+
6
+ it "should all you to set abilities" do
7
+ configuration = SafetyPatrol::Configuration.new
8
+ configuration.abilities[:send] = 'sendable'
9
+ configuration.abilities[:send].should eq('sendable')
10
+ end
11
+
12
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ class User
4
+ include SafetyPatrol::UserAbilities
5
+ end
6
+
7
+ class UserItemAuthorizer
8
+
9
+ def creatable_by?(user, resource)
10
+ true
11
+ end
12
+
13
+ def deletable_by?(user, resource)
14
+ false
15
+ end
16
+
17
+ end
18
+
19
+ class UserItem
20
+ include SafetyPatrol::Abilities
21
+ authorizer UserItemAuthorizer
22
+ end
23
+
24
+ describe SafetyPatrol::UserAbilities do
25
+
26
+ it "should define methods on a User class based upon the abilities hash" do
27
+ user = User.new
28
+ article = double("article")
29
+ article.should_receive(:creatable_by?)
30
+ lambda {
31
+ user.can_create? article
32
+ }.should_not raise_exception(NoMethodError)
33
+ end
34
+
35
+ it "#can_create? should return true" do
36
+ user = User.new
37
+ user_item = UserItem.new
38
+ user.can_create?(user_item).should eq(true)
39
+ end
40
+
41
+ it "#can_delete? should return false" do
42
+ user = User.new
43
+ user_item = UserItem.new
44
+ user.can_delete?(user_item).should eq(false)
45
+ end
46
+
47
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ describe SafetyPatrol do
5
+
6
+ it "should present a configuration object via a block" do
7
+ configuration = nil
8
+ SafetyPatrol.configure do |config|
9
+ configuration = config
10
+ end
11
+ configuration.should be_instance_of(SafetyPatrol::Configuration)
12
+ end
13
+
14
+
15
+ describe "Abilities" do
16
+
17
+ before do
18
+ SafetyPatrol.configure do |config|
19
+ end
20
+ end
21
+
22
+ it "should provide a list of ability verbs" do
23
+ SafetyPatrol.verbs.should eq([:create, :read, :update, :delete])
24
+ end
25
+
26
+ it "should provide a list of ability verbs" do
27
+ SafetyPatrol.adjectives.should eq([:creatable, :readable, :updatable, :deletable])
28
+ end
29
+
30
+ end
31
+
32
+
33
+ end
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'rspec'
3
+ require 'safety_patrol'
4
+
5
+ SafetyPatrol.configure
6
+
7
+ RSpec.configure do |config|
8
+ config.mock_with :rspec
9
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: safety_patrol
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Thomas Brewer
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-09-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &70299455803640 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70299455803640
25
+ description: Simple framework agnostic Authorization gem
26
+ email:
27
+ - tom@21purple.com
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - .gitignore
33
+ - Gemfile
34
+ - LICENSE
35
+ - README.md
36
+ - Rakefile
37
+ - lib/safety_patrol.rb
38
+ - lib/safety_patrol/abilities.rb
39
+ - lib/safety_patrol/configuration.rb
40
+ - lib/safety_patrol/user_abilities.rb
41
+ - lib/safety_patrol/version.rb
42
+ - safety_patrol.gemspec
43
+ - spec/safety_patrol/abilities_spec.rb
44
+ - spec/safety_patrol/configuration_spec.rb
45
+ - spec/safety_patrol/user_abilities_spec.rb
46
+ - spec/safety_patrol_spec.rb
47
+ - spec/spec_helper.rb
48
+ homepage: ''
49
+ licenses: []
50
+ post_install_message:
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ requirements: []
67
+ rubyforge_project:
68
+ rubygems_version: 1.8.10
69
+ signing_key:
70
+ specification_version: 3
71
+ summary: Simple framework agnostic Authorization gem
72
+ test_files:
73
+ - spec/safety_patrol/abilities_spec.rb
74
+ - spec/safety_patrol/configuration_spec.rb
75
+ - spec/safety_patrol/user_abilities_spec.rb
76
+ - spec/safety_patrol_spec.rb
77
+ - spec/spec_helper.rb