alfred 0.0.1 → 0.0.2

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.
@@ -1 +1,4 @@
1
- rvm: 1.9.2
1
+ rvm:
2
+ - 1.9.2
3
+ - 1.9.3
4
+ - ruby-head
@@ -0,0 +1,120 @@
1
+ h1. Alfred - the unobtrusive butler who takes care of the uninvited guests "!https://secure.travis-ci.org/parcydo/alfred.png?branch=master!":http://travis-ci.org/parcydo/alfred
2
+
3
+ Travis is an attempt to create an open-source, distributed build system for the Ruby community that:
4
+
5
+ 1. allows open-source projects to register their repository and have their test-suites run on demand
6
+ 2. allows users to contribute build capacities by connecting a VM that runs a build agent somewhere on their underused servers
7
+
8
+ h2. Contact
9
+ * "Github":http://github.com/parcydo
10
+ * "Twitter":http://twitter.com/parcydo
11
+
12
+ h2. Documentation
13
+
14
+ * "Wiki":http://github.com/parcydo/alfred/wiki
15
+ * "YARD":http://rdoc.info/github/parcydo/alfred
16
+
17
+ h2. Preview
18
+
19
+ h3. Without Alfred, and with much mess:
20
+
21
+ <pre>
22
+ # app/models/user.rb
23
+ class User < ActiveRecord::Base
24
+ attr_accessible :email, :password, :password_confirmation
25
+ attr_accessible :email, :password, :password_confirmation, :username, as: :admin
26
+ attr_accessible :email, :password, :password_confirmation, :username, as: :on_create
27
+ end
28
+ </pre>
29
+
30
+ Have to use a special role:
31
+
32
+ <pre>
33
+ # app/controllers/users_controlelr.rb
34
+ class UsersController < ApplicationController
35
+ def create
36
+ @user = User.create(params[:user], as: :on_create)
37
+ end
38
+ end
39
+ </pre>
40
+
41
+ h3. With Alfred and no hassles:
42
+
43
+ <pre>
44
+ # app/models/user.rb
45
+ class User < ActiveRecord::Base
46
+ alfred_accessible :email, :password
47
+ alfred_accessible :username, as: :admin
48
+ alfred_accessible :username, on: :create
49
+ end
50
+ </pre>
51
+
52
+ Nothing special here:
53
+
54
+ <pre>
55
+ # app/controllers/users_controlelr.rb
56
+ class UsersController < ApplicationController
57
+ def create
58
+ @user = User.create(params[:user])
59
+ end
60
+ end
61
+ </pre>
62
+
63
+ h2. Usage
64
+
65
+ alfred_accessible and alfred_protected behaves just like attr_accessible and attr_protected on steroids.
66
+
67
+ h3. accessible and protected
68
+
69
+ <pre>
70
+ class User < ActiveRecord::Base
71
+ alfred_accessible :a, :b
72
+ alfred_protected :c, :d
73
+ end
74
+ </pre>
75
+
76
+ h3. roles
77
+
78
+ Custom inherits from default role:
79
+
80
+ <pre>
81
+ class User < ActiveRecord::Base
82
+ alfred_accessible :a, :b
83
+ alfred_accessible :c, :d, as: :custom
84
+ end
85
+ </pre>
86
+
87
+ h3. custom inheritance
88
+
89
+ <pre>
90
+ class User < ActiveRecord::Base
91
+ alfred_accessible :a, :b
92
+ alfred_accessible :c, :d, as: :custom
93
+ alfred_accessible :e, :f, as: :custom2, inherit: :custom
94
+ end
95
+ </pre>
96
+
97
+ h3. events
98
+
99
+ <pre>
100
+ class User < ActiveRecord::Base
101
+ alfred_accessible :a, :b
102
+ alfred_accessible :c, :d, on: :create
103
+ alfred_accessible :e, :f, on: :update
104
+ end
105
+ </pre>
106
+
107
+ h3. passwords
108
+
109
+ password_confirmation will automatically added by default.
110
+
111
+ <pre>
112
+ class User < ActiveRecord::Base
113
+ alfred_accessible :password
114
+ end
115
+ </pre>
116
+
117
+ h2. Requirements
118
+
119
+ * Ruby 1.9.2 (Ruby 1.9.1 is not supported).
120
+ * Rails 3.1.x (Rails 3.0.x is not supported).
@@ -13,7 +13,8 @@ Gem::Specification.new do |s|
13
13
 
14
14
  s.rubyforge_project = "alfred"
15
15
 
16
- s.add_dependency "rails", "~> 3.1.0.rc"
16
+ s.add_dependency "rails", ">= 3.1.0"
17
+ s.add_development_dependency "activemodel"
17
18
  s.add_development_dependency "activerecord"
18
19
  s.add_development_dependency "rr"
19
20
  s.add_development_dependency "rspec"
@@ -22,4 +23,4 @@ Gem::Specification.new do |s|
22
23
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
23
24
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
24
25
  s.require_paths = ["lib"]
25
- end
26
+ end
@@ -1,8 +1,6 @@
1
1
  require 'rails'
2
2
 
3
3
  module Alfred
4
- autoload :Models, 'alfred/models'
5
-
6
4
  # Automaticly add password_confirmation if password exists.
7
5
  mattr_accessor :auto_password_confirmation
8
6
  @@auto_password_confirmation = true
@@ -15,4 +13,5 @@ module Alfred
15
13
  end
16
14
 
17
15
  require 'alfred/engine'
16
+ require 'alfred/mass_assignment_security'
18
17
  require 'alfred/orm/active_record' if defined?(ActiveRecord)
@@ -0,0 +1,150 @@
1
+ require 'active_model'
2
+
3
+ module Alfred
4
+ module ActiveModel
5
+ module MassAssignmentSecurity
6
+ module ClassMethods
7
+ # Attributes named in this macro are protected from mass-assignment
8
+ # whenever attributes are sanitized before assignment. A role for the
9
+ # attributes is optional, if no role is provided then :default is used.
10
+ # A role can be defined by using the :as option.
11
+ #
12
+ # Mass-assignment to these attributes will simply be ignored, to assign
13
+ # to them you can use direct writer methods. This is meant to protect
14
+ # sensitive attributes from being overwritten by malicious users
15
+ # tampering with URLs or forms. Example:
16
+ #
17
+ # class Customer
18
+ # include ActiveModel::MassAssignmentSecurity
19
+ # extend Alfred::ActiveModel::MassAssignmentSecurity
20
+ #
21
+ # attr_accessor :name, :credit_rating
22
+ #
23
+ # alfred_protected :credit_rating
24
+ # alfred_protected :last_login, as: :trainee
25
+ #
26
+ # def assign_attributes(values, options = {})
27
+ # sanitize_for_mass_assignment(values, options[:as]).each do |k, v|
28
+ # send("#{k}=", v)
29
+ # end
30
+ # end
31
+ # end
32
+ #
33
+ # When using the :default role :
34
+ #
35
+ # customer = Customer.new
36
+ # customer.assign_attributes({ name: "Daniel", credit_rating: "Excellent", last_login: 1.day.ago }, as: :default)
37
+ # customer.name # => "Daniel"
38
+ # customer.credit_rating # => nil
39
+ # customer.last_login # => nil
40
+ #
41
+ # customer.credit_rating = "Average"
42
+ # customer.credit_rating # => "Average"
43
+ #
44
+ # And using the :admin role :
45
+ #
46
+ # customer = Customer.new
47
+ # customer.assign_attributes({ name: "Daniel", credit_rating: "Excellent", last_login: 1.day.ago }, as: :trainee)
48
+ # customer.name # => "Daniel"
49
+ # customer.credit_rating # => "Excellent"
50
+ # customer.last_login # => nil
51
+ #
52
+ # To start from an all-closed default and enable attributes as needed,
53
+ # have a look at +alfred_accessible+.
54
+ #
55
+ # Note that using <tt>Hash#except</tt> or <tt>Hash#slice</tt> in place of +alfred_protected+
56
+ # to sanitize attributes won't provide sufficient protection.
57
+ def alfred_protected(*args)
58
+ alfred(:protected, *args)
59
+ end
60
+
61
+ # Specifies a white list of model attributes that can be set via
62
+ # mass-assignment.
63
+ #
64
+ # Like +alfred_protected+, a role for the attributes is optional,
65
+ # if no role is provided then :default is used. A role can be defined by
66
+ # using the :as option.
67
+ #
68
+ # This is the opposite of the +alfred_protected+ macro: Mass-assignment
69
+ # will only set attributes in this list, to assign to the rest of
70
+ # attributes you can use direct writer methods. This is meant to protect
71
+ # sensitive attributes from being overwritten by malicious users
72
+ # tampering with URLs or forms. If you'd rather start from an all-open
73
+ # default and restrict attributes as needed, have a look at
74
+ # +alfred_protected+.
75
+ #
76
+ # class Customer
77
+ # include ActiveModel::MassAssignmentSecurity
78
+ # extend Alfred::ActiveModel::MassAssignmentSecurity
79
+ #
80
+ # attr_accessor :name, :credit_rating
81
+ #
82
+ # alfred_accessible :name
83
+ # alfred_accessible :credit_rating, as: :admin
84
+ #
85
+ # def assign_attributes(values, options = {})
86
+ # sanitize_for_mass_assignment(values, options[:as]).each do |k, v|
87
+ # send("#{k}=", v)
88
+ # end
89
+ # end
90
+ # end
91
+ #
92
+ # When using the :default role :
93
+ #
94
+ # customer = Customer.new
95
+ # customer.assign_attributes({ name: "Daniel", credit_rating: "Excellent", last_login: 1.day.ago }, as: :default)
96
+ # customer.name # => "Daniel"
97
+ # customer.credit_rating # => nil
98
+ #
99
+ # customer.credit_rating = "Average"
100
+ # customer.credit_rating # => "Average"
101
+ #
102
+ # And using the :admin role :
103
+ #
104
+ # customer = Customer.new
105
+ # customer.assign_attributes({ name: "Daniel", credit_rating: "Excellent", last_login: 1.day.ago }, as: :admin)
106
+ # customer.name # => "Daniel"
107
+ # customer.credit_rating # => "Excellent"
108
+ #
109
+ # Note that using <tt>Hash#except</tt> or <tt>Hash#slice</tt> in place of +alfred_accessible+
110
+ # to sanitize attributes won't provide sufficient protection.
111
+ def alfred_accessible(*args)
112
+ alfred(:accessible, *args)
113
+ end
114
+
115
+ private
116
+ def alfred(method, *args)
117
+ options = args.extract_options!
118
+
119
+ if args.include?(:password) && Alfred.auto_password_confirmation
120
+ args = args + [:password_confirmation]
121
+ end
122
+
123
+ [nil, :create, :update].each do |action|
124
+ if options[:on]
125
+ next unless options[:on] == action
126
+ end
127
+
128
+ action_args = args.dup
129
+
130
+ role = (options[:as] || :default).to_s
131
+ role << "_#{action}" if action
132
+ role = role.to_sym
133
+
134
+ action_args = action_args + [{ as: role }]
135
+
136
+ action_args = action_args + send("#{method}_attributes", role).to_a.compact.reject { |s| s.blank? }
137
+
138
+ send("attr_#{method}", *action_args)
139
+ end
140
+ end
141
+ end
142
+
143
+ include ClassMethods
144
+ end
145
+ end
146
+ end
147
+
148
+ module ActiveModel::MassAssignmentSecurity::ClassMethods
149
+ include Alfred::ActiveModel::MassAssignmentSecurity
150
+ end
@@ -1,3 +1,32 @@
1
1
  require 'active_record'
2
2
 
3
- ActiveRecord::Base.extend Alfred::Models
3
+ module Alfred
4
+ module ActiveRecord
5
+ module Base
6
+ def assign_attributes(new_attributes, options = {})
7
+ role = (options[:as] || :default).to_s
8
+ role << "_#{options[:action]}" if options[:action]
9
+
10
+ options[:as] = role.to_sym
11
+
12
+ super
13
+ end
14
+
15
+ def initialize(attributes = nil, options = {})
16
+ options[:action] = :create
17
+
18
+ super
19
+ end
20
+
21
+ def update_attributes(attributes, options = {})
22
+ options[:action] = :update
23
+
24
+ super
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ class ActiveRecord::Base
31
+ include Alfred::ActiveRecord::Base
32
+ end
@@ -1,3 +1,3 @@
1
1
  module Alfred
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alfred
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,22 +9,43 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-08-11 00:00:00.000000000Z
12
+ date: 2012-04-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
- requirement: &70320733483060 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ~>
19
+ - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: 3.1.0.rc
21
+ version: 3.1.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70320733483060
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 3.1.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: activemodel
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
25
46
  - !ruby/object:Gem::Dependency
26
47
  name: activerecord
27
- requirement: &70320733482640 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
28
49
  none: false
29
50
  requirements:
30
51
  - - ! '>='
@@ -32,10 +53,15 @@ dependencies:
32
53
  version: '0'
33
54
  type: :development
34
55
  prerelease: false
35
- version_requirements: *70320733482640
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
36
62
  - !ruby/object:Gem::Dependency
37
63
  name: rr
38
- requirement: &70320733482180 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
39
65
  none: false
40
66
  requirements:
41
67
  - - ! '>='
@@ -43,10 +69,15 @@ dependencies:
43
69
  version: '0'
44
70
  type: :development
45
71
  prerelease: false
46
- version_requirements: *70320733482180
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
47
78
  - !ruby/object:Gem::Dependency
48
79
  name: rspec
49
- requirement: &70320733481760 !ruby/object:Gem::Requirement
80
+ requirement: !ruby/object:Gem::Requirement
50
81
  none: false
51
82
  requirements:
52
83
  - - ! '>='
@@ -54,7 +85,12 @@ dependencies:
54
85
  version: '0'
55
86
  type: :development
56
87
  prerelease: false
57
- version_requirements: *70320733481760
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
58
94
  description: Alfred provides better attr_accessor handling on your application.
59
95
  email:
60
96
  - daniel.spangenberg@parcydo.com
@@ -64,16 +100,16 @@ extra_rdoc_files: []
64
100
  files:
65
101
  - .gitignore
66
102
  - .rspec
67
- - .rvmrc
68
103
  - .travis.yml
69
104
  - Gemfile
105
+ - README.textile
70
106
  - Rakefile
71
107
  - alfred.gemspec
72
108
  - lib/alfred.rb
73
109
  - lib/alfred/engine.rb
74
110
  - lib/alfred/generators/alfred/install_generator.rb
75
111
  - lib/alfred/generators/templates/alfred.rb
76
- - lib/alfred/models.rb
112
+ - lib/alfred/mass_assignment_security.rb
77
113
  - lib/alfred/orm/active_record.rb
78
114
  - lib/alfred/version.rb
79
115
  - spec/models_spec.rb
@@ -98,7 +134,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
98
134
  version: '0'
99
135
  requirements: []
100
136
  rubyforge_project: alfred
101
- rubygems_version: 1.8.8
137
+ rubygems_version: 1.8.21
102
138
  signing_key:
103
139
  specification_version: 3
104
140
  summary: Alfred is the unobtrusive butler who takes care of the uninvited guests.
data/.rvmrc DELETED
@@ -1 +0,0 @@
1
- rvm 1.9.2@alfred --create
@@ -1,53 +0,0 @@
1
- module Alfred
2
- module Models
3
- def alfred_accessible(*args)
4
- alfred(:accessible, *args)
5
- end
6
-
7
- def alfred_protected(*args)
8
- alfred(:protected, *args)
9
- end
10
-
11
- private
12
-
13
- def alfred(method, *args)
14
- options = args.extract_options!
15
-
16
- if options[:as]
17
- if method == :accessible
18
- args = args + accessible_attributes(options[:inherit] || :default).to_a
19
- else
20
- args = args + protected_attributes(options[:inherit] || :default).to_a
21
- end
22
- args = args + [{ as: options[:as] }]
23
- end
24
-
25
- if args.include?(:password) && Alfred.auto_password_confirmation
26
- args = args + [:password_confirmation]
27
- end
28
-
29
- if options[:on] && [:create, :update].include?(options[:on])
30
- if options[:on] == :create
31
- before = :before_create
32
- else
33
- before = :before_update
34
- end
35
- if method == :accessible
36
- self.class.send(:define_method, before) do
37
- attr_accessible(*args)
38
- end
39
- else
40
- self.class.send(:define_method, before) do
41
- attr_protected(*args)
42
- end
43
- end
44
- else
45
- if method == :accessible
46
- attr_accessible(*args)
47
- else
48
- attr_protected(*args)
49
- end
50
- end
51
- end
52
- end
53
- end