sudo_attr_accessibility 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +9 -0
- data/LICENSE +22 -0
- data/README.md +78 -0
- data/Rakefile +15 -0
- data/lib/sudo_attr_accessibility/version.rb +3 -0
- data/lib/sudo_attr_accessibility.rb +77 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/sudo_attr_accessibility/saa_spec.rb +31 -0
- data/sudo_attr_accessibility.gemspec +25 -0
- metadata +107 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Gert Goet
|
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,78 @@
|
|
1
|
+
# SudoAttrAccessibility
|
2
|
+
|
3
|
+
Using attr_accessible you can explicitly define what attributes of a model can be assigned.
|
4
|
+
As of Rails 3.1 this got even better as you can define different lists of attributes for different roles.
|
5
|
+
|
6
|
+
While this is all good and fine to protect your models from malicious input from outside (handled mostly in controllers), it will also make other interactions with your models somewhat harder: e.g. when testing or when in the console you always have to pass a role which can access the correct attributes.
|
7
|
+
|
8
|
+
This gem tries to solve this by letting you define roles that are allowed to access all attribites. It even makes it possible to forget all this role-stuff and only explicitly use roles in places where it matters (again: mostly in controllers).
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
gem 'sudo_attr_accessibility'
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
$ bundle
|
19
|
+
|
20
|
+
Or install it yourself as:
|
21
|
+
|
22
|
+
$ gem install sudo_attr_accessibility
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
class Person < ActiveRecord::Base
|
28
|
+
belongs_to :account
|
29
|
+
|
30
|
+
# attributes mass-assignable as role default
|
31
|
+
attr_accessible :email
|
32
|
+
|
33
|
+
# the admin-role can access all...
|
34
|
+
sudo_attr_accessible_as :admin
|
35
|
+
|
36
|
+
# ...even attributes defined later on
|
37
|
+
attr_accessor :current_step
|
38
|
+
end
|
39
|
+
|
40
|
+
p1 = Person.new(:email => 'person1@example.org', :active => true)
|
41
|
+
p1.email # => 'person1@example.org'
|
42
|
+
p1.active # => nil
|
43
|
+
p2 = Person.new({:email => 'person1@example.org', :active => true,
|
44
|
+
:account => Account.first, :current_step => 1},
|
45
|
+
:as => :admin)
|
46
|
+
p2.email # => 'person1@example.org'
|
47
|
+
p2.active # => true
|
48
|
+
p2.current_step # => 2
|
49
|
+
p2.account # => <Account ...>
|
50
|
+
```
|
51
|
+
|
52
|
+
Alternatively the default-role is passed to sudo_attr_accessible_as and
|
53
|
+
another role is used for attr_accessible. This is more convenient when
|
54
|
+
working in the console for example (no ':as => :role' is needed) though
|
55
|
+
is less secure of course.
|
56
|
+
|
57
|
+
Enabling this behaviour by default for all subclasses of AR:
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
class ActiveRecord::Base
|
61
|
+
def self.inherited(child_class)
|
62
|
+
child_class.class_eval{ sudo_attr_accessible_as :default }
|
63
|
+
super
|
64
|
+
end
|
65
|
+
end
|
66
|
+
```
|
67
|
+
|
68
|
+
## Contributing
|
69
|
+
|
70
|
+
1. Fork it
|
71
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
72
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
73
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
74
|
+
5. Create new Pull Request
|
75
|
+
|
76
|
+
## Author
|
77
|
+
|
78
|
+
Gert Goet (eval) :: gert@thinkcreate.nl :: @gertgoet
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
require "rspec/core/rake_task"
|
4
|
+
|
5
|
+
RSpec::Core::RakeTask.new do |t|
|
6
|
+
t.rspec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
|
7
|
+
end
|
8
|
+
|
9
|
+
desc "Run the specs"
|
10
|
+
task :default => :spec
|
11
|
+
|
12
|
+
desc 'Removes trailing whitespace'
|
13
|
+
task :whitespace do
|
14
|
+
sh %{find . -name '*.rb' -exec sed -i '' 's/ *$//g' {} \\;}
|
15
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
|
3
|
+
module SudoAttrAccessibility
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
# Make all attributes of an AR-model accessible to some roles.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# class Person < ActiveRecord::Base
|
11
|
+
# belongs_to :account
|
12
|
+
#
|
13
|
+
# # attributes mass-assignable as role default
|
14
|
+
# attr_accessible :email
|
15
|
+
#
|
16
|
+
# # the admin-role can access all...
|
17
|
+
# sudo_attr_accessible_as :admin
|
18
|
+
#
|
19
|
+
# # ...even attributes defined later on
|
20
|
+
# attr_accessor :current_step
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# p1 = Person.new(:email => 'person1@example.org', :active => true)
|
24
|
+
# p1.email # => 'person1@example.org'
|
25
|
+
# p1.active # => nil
|
26
|
+
# p2 = Person.new({:email => 'person1@example.org', :active => true,
|
27
|
+
# :account => Account.first, :current_step => 1},
|
28
|
+
# :as => :admin)
|
29
|
+
# p2.email # => 'person1@example.org'
|
30
|
+
# p2.active # => true
|
31
|
+
# p2.current_step # => 2
|
32
|
+
# p2.account # => <Account ...>
|
33
|
+
#
|
34
|
+
# Alternatively the default-role is passed to sudo_attr_accessible_as and
|
35
|
+
# another role is used for attr_accessible. This is more convenient when
|
36
|
+
# working in the console for example (no ':as => :role' is needed) though
|
37
|
+
# is less secure of course.
|
38
|
+
#
|
39
|
+
# Enabling this behaviour by default for all subclasses of AR:
|
40
|
+
# class ActiveRecord::Base
|
41
|
+
# def self.inherited(child_class)
|
42
|
+
# child_class.class_eval{ sudo_attr_accessible_as :default }
|
43
|
+
# super
|
44
|
+
# end
|
45
|
+
# end
|
46
|
+
def sudo_attr_accessible_as(*roles)
|
47
|
+
re_method_filter = %r{(.+)=\z}
|
48
|
+
|
49
|
+
# take care of any future attribute
|
50
|
+
unless respond_to?(:method_added_with_sudo_attr_accessibility)
|
51
|
+
class_eval %{
|
52
|
+
def self.method_added_with_sudo_attr_accessibility(m)
|
53
|
+
if attribute = m.to_s[#{re_method_filter.inspect}, 1]
|
54
|
+
attr_accessible attribute, :as => #{roles.inspect}
|
55
|
+
end
|
56
|
+
method_added_without_sudo_attr_accessibility(m)
|
57
|
+
end
|
58
|
+
|
59
|
+
class << self
|
60
|
+
alias_method_chain :method_added, :sudo_attr_accessibility
|
61
|
+
end
|
62
|
+
}, __FILE__, __LINE__ + 1
|
63
|
+
end
|
64
|
+
|
65
|
+
# handle current attributes
|
66
|
+
attributes = [].tap do |a|
|
67
|
+
a.push *self.attribute_names
|
68
|
+
a.push *self.instance_methods(false).map do |m|
|
69
|
+
m.to_s[re_method_filter, 1]
|
70
|
+
end.compact
|
71
|
+
end.each do |attr|
|
72
|
+
attr_accessible attr, :as => roles
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
ActiveRecord::Base.send(:include, SudoAttrAccessibility) if defined?(ActiveRecord)
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
require 'sqlite3'
|
4
|
+
|
5
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
6
|
+
ActiveRecord::Migration.verbose = false
|
7
|
+
ActiveRecord::Schema.define do
|
8
|
+
create_table :people do |t|
|
9
|
+
t.column :name, :string
|
10
|
+
t.column :age, :integer
|
11
|
+
|
12
|
+
t.timestamps
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class Person < ActiveRecord::Base
|
17
|
+
include SudoAttrAccessibility
|
18
|
+
|
19
|
+
attr_accessible :name
|
20
|
+
sudo_attr_accessible_as :admin
|
21
|
+
end
|
22
|
+
|
23
|
+
describe SudoAttrAccessibility do
|
24
|
+
it "let's admin assign protected attributes" do
|
25
|
+
p1 = Person.new(:age => 12)
|
26
|
+
p1.age.should be_nil
|
27
|
+
|
28
|
+
p2 = Person.new({:age => 12}, :as => :admin)
|
29
|
+
p2.age.should == 12
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/sudo_attr_accessibility/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Gert Goet"]
|
6
|
+
gem.email = ["gert@thinkcreate.nl"]
|
7
|
+
gem.description = %q{Make all attributes of an AR-model accessible to some roles}
|
8
|
+
gem.summary = %q{Make all attributes of an AR-model accessible to some roles}
|
9
|
+
gem.homepage = "https://github.com/eval/sudo_attr_accessibility"
|
10
|
+
gem.license = "MIT"
|
11
|
+
|
12
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
13
|
+
gem.files = `git ls-files`.split("\n")
|
14
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
15
|
+
gem.name = "sudo_attr_accessibility"
|
16
|
+
gem.require_paths = ["lib"]
|
17
|
+
gem.version = SudoAttrAccessibility::VERSION
|
18
|
+
gem.required_ruby_version = '>= 1.8.7'
|
19
|
+
|
20
|
+
gem.add_dependency "activesupport", ">= 3.0.0"
|
21
|
+
gem.add_dependency "activemodel", ">= 3.0.0"
|
22
|
+
|
23
|
+
gem.add_development_dependency "rspec", "~> 2.7.0"
|
24
|
+
gem.add_development_dependency "ZenTest", "~> 4.6.2"
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sudo_attr_accessibility
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Gert Goet
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-03-04 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: &70265561101560 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.0.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70265561101560
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: activemodel
|
27
|
+
requirement: &70265561097960 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 3.0.0
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70265561097960
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &70265561095480 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 2.7.0
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70265561095480
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: ZenTest
|
49
|
+
requirement: &70265561093600 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 4.6.2
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70265561093600
|
58
|
+
description: Make all attributes of an AR-model accessible to some roles
|
59
|
+
email:
|
60
|
+
- gert@thinkcreate.nl
|
61
|
+
executables: []
|
62
|
+
extensions: []
|
63
|
+
extra_rdoc_files: []
|
64
|
+
files:
|
65
|
+
- .gitignore
|
66
|
+
- Gemfile
|
67
|
+
- LICENSE
|
68
|
+
- README.md
|
69
|
+
- Rakefile
|
70
|
+
- lib/sudo_attr_accessibility.rb
|
71
|
+
- lib/sudo_attr_accessibility/version.rb
|
72
|
+
- spec/spec.opts
|
73
|
+
- spec/spec_helper.rb
|
74
|
+
- spec/sudo_attr_accessibility/saa_spec.rb
|
75
|
+
- sudo_attr_accessibility.gemspec
|
76
|
+
homepage: https://github.com/eval/sudo_attr_accessibility
|
77
|
+
licenses:
|
78
|
+
- MIT
|
79
|
+
post_install_message:
|
80
|
+
rdoc_options: []
|
81
|
+
require_paths:
|
82
|
+
- lib
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ! '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 1.8.7
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ! '>='
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
segments:
|
96
|
+
- 0
|
97
|
+
hash: -1376614183592359389
|
98
|
+
requirements: []
|
99
|
+
rubyforge_project:
|
100
|
+
rubygems_version: 1.8.10
|
101
|
+
signing_key:
|
102
|
+
specification_version: 3
|
103
|
+
summary: Make all attributes of an AR-model accessible to some roles
|
104
|
+
test_files:
|
105
|
+
- spec/spec.opts
|
106
|
+
- spec/spec_helper.rb
|
107
|
+
- spec/sudo_attr_accessibility/saa_spec.rb
|