active_permission 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5d51048fc3edb6e14ac8f39eaf433b70371fe9f7
4
+ data.tar.gz: a6dac96c1c9df176981a6fd6ae6a157f564c3d96
5
+ SHA512:
6
+ metadata.gz: 2082819334f72c46e40522642d17542aa4aaf95d8fb690c860e6b31e2b2d1e5428e41200d584cf8a4e5e4cbc0cc73796870ef5ed859de06ba9752ff42f611ad2
7
+ data.tar.gz: 6d9e8299ea7b794178e401bb29d96ee80043741f70533671429e1eac50b8f1d83640b2e5ca5da75bc7d15a9b7c7ed2a94100214f7bdaffb4df92d92752befd0e
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in activepermission.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Evgeniy Shurmin
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.
@@ -0,0 +1,105 @@
1
+ # ActivePermission
2
+
3
+ This gem allow you load and authorize resource in Ruby on Rails inside controllers or views using rules with described permissions of user.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```
10
+ gem 'activepermission'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install activepermission
20
+
21
+ ## Usage
22
+
23
+ ### Define Abilities
24
+
25
+ Add a new class in `app/models/permissions.rb` with the following contents:
26
+
27
+ ```
28
+ class Permissions < ActivePermission::Base
29
+ def initialize(user = nil)
30
+ can 'books', 'index'
31
+ can 'books, 'show' do |catalog, book|
32
+ catalog.published? and book.published?
33
+ end
34
+ can 'books, ['edit','update','destroy'] do |book|
35
+ book.author == user
36
+ end
37
+ end
38
+ end
39
+ ```
40
+
41
+ ### Load Resource and authorization examples
42
+
43
+ ```
44
+ class BooksController < ApplicationController
45
+ resource :book, object: 'Book'
46
+ end
47
+ ```
48
+
49
+ ```
50
+ class BooksController < ApplicationController
51
+ resource :book do
52
+ Book.find(params[:id])
53
+ end
54
+ end
55
+ ```
56
+
57
+ ```
58
+ class BooksController < ApplicationController
59
+ resource :catalog, object: 'Catalog', key: :catalog_id, parent: true
60
+ resource :book, through: :catalog, association: :books
61
+ authorize :catalog, :book, only: :show
62
+ authorize :book, only: [ :edit, :update, :destroy ]
63
+ end
64
+ ```
65
+
66
+ ```
67
+ class BooksController < ApplicationController
68
+ resource :book, object: 'Book', only: [ :show, :destroy ]
69
+ def show
70
+ @book = Book.find(params[:id])
71
+ authorize! @book
72
+ end
73
+ def destroy
74
+ @book = Book.find(params[:id])
75
+ if authorize @book, :destroy
76
+ @book.destroy
77
+ else
78
+ flash[:warning] = 'Can't delete book'
79
+ end
80
+ end
81
+ end
82
+ ```
83
+
84
+ ### Check Abilities
85
+
86
+ ```
87
+ <% if can? 'books', 'show', @book %>
88
+ <%= render 'book', book: @book %>
89
+ <% end %>
90
+ ```
91
+
92
+ ```
93
+ <% if can? 'books', ['edit', 'update'], @book %>
94
+ <%= render 'links', book: @book %>
95
+ <% end %>
96
+ ```
97
+
98
+
99
+ ## Contributing
100
+
101
+ 1. Fork it ( https://github.com/[my-github-username]/activepermission/fork )
102
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
103
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
104
+ 4. Push to the branch (`git push origin my-new-feature`)
105
+ 5. Create a new Pull Request
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'bundler/gem_tasks'
3
+ require 'rake'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new do |t|
7
+ t.verbose = false
8
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
3
+
4
+ require 'active_permission/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'active_permission'
8
+ spec.version = ActivePermission::VERSION
9
+ spec.platform = Gem::Platform::RUBY
10
+ spec.authors = ['Evgeniy Shurmin']
11
+ spec.email = ['eshurmin@gmail.com']
12
+ spec.summary = %q{This gem allow you load and authorize resource in Ruby on Rails inside controllers or views using rules with described permissions of user.}
13
+ spec.homepage = 'http://github.com/jpascal/active_permission'
14
+ spec.license = 'MIT'
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_path = 'lib'
19
+
20
+ spec.required_ruby_version = '>= 1.9.2'
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.7'
23
+ spec.add_development_dependency 'rake', '~> 10.0'
24
+ spec.add_development_dependency 'rspec'
25
+
26
+ spec.add_dependency 'activesupport'
27
+ end
@@ -0,0 +1,13 @@
1
+ require 'active_permission/version'
2
+ require 'active_permission/controller_additions'
3
+ require 'active_permission/base'
4
+
5
+ module ActivePermission
6
+ class AccessDenied < RuntimeError
7
+ attr_reader :secure
8
+ def initialize(message, secure = true)
9
+ super(message)
10
+ @secure = secure
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,39 @@
1
+ module ActivePermission
2
+ # class UserPermission < ActivePermission::Base
3
+ # def initialize(user)
4
+ # if user.admin?
5
+ # can 'manage/root', :index
6
+ # else
7
+ # can 'root', :all
8
+ # end
9
+ # end
10
+ # end
11
+ class Base
12
+ def can(controllers, actions, &block)
13
+ @allowed_actions ||= {}
14
+ Array(controllers).each do |controller|
15
+ Array(actions).each do |action|
16
+ @allowed_actions[[controller.to_s, action.to_s]] = block || true
17
+ end
18
+ end
19
+ end
20
+ def can?(controllers, actions, *resource)
21
+ @allowed_actions ||= {}
22
+ Array(controllers).each do |controller|
23
+ Array(actions).each do |action|
24
+ allowed = @allowed_actions[[controller.to_s, action.to_s]]
25
+ result = allowed && (allowed == true || resource && allowed.call(*resource))
26
+ return result if result == true
27
+ end
28
+ end
29
+ false
30
+ end
31
+ def can!(controllers, actions, *resource)
32
+ if can?(controllers, actions, *resource)
33
+ true
34
+ else
35
+ raise AccessDenied.new("Access denied by #{self.class.name} to #{resource.inspect}")
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,108 @@
1
+ module ActivePermission
2
+ module ControllerAdditions
3
+ module ClassMethods
4
+ # Sets up a before filter which loads the model resource into an instance variable by name.
5
+ #
6
+ # class BooksController < ApplicationController
7
+ # resource :book, object: 'Book'
8
+ # end
9
+ #
10
+ # class BooksController < ApplicationController
11
+ # resource :book do
12
+ # Book.find(params[:id])
13
+ # end
14
+ # end
15
+ #
16
+ # Options:
17
+ # [:+only+]
18
+ # Work as before filter parameter.
19
+ #
20
+ # [:+except+]
21
+ # Work as before filter parameter.
22
+ #
23
+ # [:+if+]
24
+ # Work as before filter parameter.
25
+ #
26
+ # [:+unless+]
27
+ # Work as before filter parameter.
28
+ #
29
+ # [:+object+]
30
+ # Object used to fetch record (string, symbol or class).
31
+ #
32
+ # [:+through+]
33
+ # Load this resource through another one.
34
+ #
35
+ # [:+association+]
36
+ # The name of the association to fetch the child records through the parent resource.
37
+ #
38
+ # [:+key+]
39
+ # The name of parameters from params.
40
+ #
41
+ # [:+parent+]
42
+ # Fetch first record from scope.
43
+
44
+ def resource(name, options = {}, &block)
45
+ send(:before_action, options.slice(:only, :except, :if, :unless)) do |controller|
46
+ if block_given?
47
+ instance_variable_set "@#{name}", controller.instance_eval(&block)
48
+ else
49
+ if options[:through] and options[:association]
50
+ object = instance_variable_get("@#{options[:through]}").send(options[:association])
51
+ elsif options[:object].nil?
52
+ raise AccessDenied.new("Access denied in #{controller.params[:controller]}::#{controller.params[:action]}. Required set a option :object.")
53
+ elsif options[:object].kind_of? Symbol
54
+ object = send(options[:object])
55
+ elsif options[:object].kind_of? String
56
+ object = options[:object].camelize.constantize
57
+ else
58
+ object = options[:object]
59
+ end
60
+
61
+ if options[:parent]
62
+ object = object.where(:id => controller.params[(options[:key] || :id).to_sym]).first!
63
+ else
64
+ if controller.params[:action].to_sym == :new
65
+ object = object.new
66
+ elsif not [:create, :index].include?(controller.params[:action].to_sym)
67
+ object = object.where(:id => controller.params[(options[:key] || :id).to_sym]).first!
68
+ end
69
+ end
70
+ instance_variable_set "@#{name}", object
71
+ end
72
+ end
73
+ end
74
+
75
+ def authorize(resources = nil, options = {})
76
+ send(:before_action, options.slice(:only, :except, :if, :unless)) do |controller|
77
+ objects = Array(resources).map {|resource| instance_variable_get("@#{resource.to_s}") }
78
+ current_permissions.can!(controller.params[:controller], controller.params[:action], *objects)
79
+ end
80
+ end
81
+
82
+ def current_permissions
83
+ @permissions ||= ActivePermission::Base.new
84
+ end
85
+ end
86
+
87
+ module InstanceMethods
88
+ def authorize!(resource, options = {})
89
+ options = params.merge(options)
90
+ current_permissions.can!(options[:controller], options[:action], resource)
91
+ end
92
+
93
+ def authorize?(resource, options = {})
94
+ options = params.merge(options)
95
+ current_permissions.can?(options[:controller], options[:action], resource)
96
+ end
97
+ end
98
+
99
+ def self.included(base)
100
+ base.extend ClassMethods
101
+ base.include InstanceMethods
102
+ base.delegate :can?, :can!, :to => :current_permissions
103
+ base.helper_method :can?, :can!
104
+ end
105
+
106
+ end
107
+ end
108
+
@@ -0,0 +1,3 @@
1
+ module ActivePermission
2
+ VERSION = '0.1.1'
3
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ class Permissions < ActivePermission::Base
4
+ def initialize
5
+ can 'manage/root', :index
6
+ can 'manage/root', :show
7
+ can 'manage/root1', [:index, :show]
8
+ can %w(manage/root2 manage/root3), :index
9
+ can %w(manage/root4 manage/root5), [:index, :show]
10
+ end
11
+ end
12
+
13
+ describe ActivePermission::Base do
14
+ let(:permissions) { Permissions.new }
15
+ it 'abilities on manage/root' do
16
+ expect(permissions.can?('manage/root', 'index')).to eql(true)
17
+ expect(permissions.can?('manage/root', 'edit')).to eql(false)
18
+ expect(permissions.can?('manage/root', 'show')).to eql(true)
19
+ end
20
+ it 'abilities on manage/root1' do
21
+ expect(permissions.can?('manage/root1', 'index')).to eql(true)
22
+ expect(permissions.can?('manage/root1', 'edit')).to eql(false)
23
+ expect(permissions.can?('manage/root1', 'show')).to eql(true)
24
+ end
25
+ it 'abilities on manage/{root2, root3}' do
26
+ expect(permissions.can?('manage/root2', 'index')).to eql(true)
27
+ expect(permissions.can?('manage/root2', 'edit')).to eql(false)
28
+ expect(permissions.can?('manage/root2', 'show')).to eql(false)
29
+ expect(permissions.can?('manage/root3', 'index')).to eql(true)
30
+ expect(permissions.can?('manage/root3', 'edit')).to eql(false)
31
+ expect(permissions.can?('manage/root3', 'show')).to eql(false)
32
+ end
33
+ it 'abilities on manage/{root2, root3}' do
34
+ expect(permissions.can?('manage/root4', 'index')).to eql(true)
35
+ expect(permissions.can?('manage/root4', 'edit')).to eql(false)
36
+ expect(permissions.can?('manage/root4', 'show')).to eql(true)
37
+ expect(permissions.can?('manage/root5', 'index')).to eql(true)
38
+ expect(permissions.can?('manage/root5', 'edit')).to eql(false)
39
+ expect(permissions.can?('manage/root5', 'show')).to eql(true)
40
+ end
41
+ it 'default to deny' do
42
+ expect(permissions.can?('manage/unknown', 'show')).to eql(false)
43
+ end
44
+ end
@@ -0,0 +1,7 @@
1
+ require 'bundler/setup'
2
+ Bundler.setup
3
+
4
+ require 'active_permission'
5
+
6
+ RSpec.configure do |config|
7
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: active_permission
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Evgeniy Shurmin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activesupport
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description:
70
+ email:
71
+ - eshurmin@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - Gemfile
78
+ - LICENSE.txt
79
+ - README.md
80
+ - Rakefile
81
+ - activepermission.gemspec
82
+ - lib/active_permission.rb
83
+ - lib/active_permission/base.rb
84
+ - lib/active_permission/controller_additions.rb
85
+ - lib/active_permission/version.rb
86
+ - spec/permissions_spec.rb
87
+ - spec/spec_helper.rb
88
+ homepage: http://github.com/jpascal/active_permission
89
+ licenses:
90
+ - MIT
91
+ metadata: {}
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: 1.9.2
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 2.2.2
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: This gem allow you load and authorize resource in Ruby on Rails inside controllers
112
+ or views using rules with described permissions of user.
113
+ test_files:
114
+ - spec/permissions_spec.rb
115
+ - spec/spec_helper.rb