devise_invitable 1.0.2 → 1.1.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/README.rdoc CHANGED
@@ -96,6 +96,8 @@ or directly as parameters to the <tt>devise</tt> method:
96
96
 
97
97
  * resend_invitation: resend invitation if user with invited status is invited again. Enabled by default.
98
98
 
99
+ * invited_by_class_name: The class name of the inviting model. If this is nil, polymorphic association is used.
100
+
99
101
  For more details, see <tt>config/initializers/devise.rb</tt> (after you invoked the "devise_invitable:install" generator described above).
100
102
 
101
103
  == Configuring views
@@ -153,6 +155,15 @@ You can add :skip_invitation to attributes hash if skip_invitation is added to a
153
155
  User.invite!(:email => "new_user@example.com", :name => "John Doe", :skip_invitation => true)
154
156
  # => the record will be created, but the invitation email will not be sent
155
157
 
158
+ You can send an invitation to an existing user if your workflow creates them separately:
159
+
160
+ user = User.find(42)
161
+ user.invite!(current_user) # current user is optional to set the invited_by attribute
162
+
163
+ You can also set <tt>invited_by</tt> when using the <tt>invite!</tt> class method:
164
+
165
+ User.invite!({:email => "new_user@example.com"}, current_user) # current_user will be set as invited_by
166
+
156
167
  === Accept an invitation
157
168
 
158
169
  To accept an invitation with a token use the <tt>accept_invitation!</tt> class method. <tt>:invitation_token</tt> must be present in the parameters hash. You can also include other attributes in the hash.
@@ -171,6 +182,13 @@ A callback event is fired before and after an invitation is accepted (User#accep
171
182
 
172
183
  The callbacks support all options and arguments available to the standard callbacks provided by AR.
173
184
 
185
+ === Scopes
186
+
187
+ A pair of scopes to find those users that have accepted, and those that have not accepted, invitations are defined:
188
+
189
+ User.invitation_accepted # => returns all Users for whom the invitation_accepted_at attribute is not nil
190
+ User.invitation_not_accepted # => returns all Users for whom the invitation_accepted_at attribute is nil
191
+
174
192
  == Integration in a Rails application
175
193
 
176
194
  Since the invitations controller take care of all the creation/acceptation of an invitation, in most cases you wouldn't call the <tt>invite!</tt> and <tt>accept_invitation!</tt> methods directly.
@@ -13,7 +13,7 @@ class Devise::InvitationsController < DeviseController
13
13
 
14
14
  # POST /resource/invitation
15
15
  def create
16
- self.resource = resource_class.invite!(params[resource_name], current_inviter)
16
+ self.resource = resource_class.invite!(resource_params, current_inviter)
17
17
 
18
18
  if resource.errors.empty?
19
19
  set_flash_message :notice, :send_instructions, :email => self.resource.email
@@ -35,7 +35,7 @@ class Devise::InvitationsController < DeviseController
35
35
 
36
36
  # PUT /resource/invitation
37
37
  def update
38
- self.resource = resource_class.accept_invitation!(params[resource_name])
38
+ self.resource = resource_class.accept_invitation!(resource_params)
39
39
 
40
40
  if resource.errors.empty?
41
41
  set_flash_message :notice, :updated
@@ -1,4 +1,4 @@
1
- <h2>Set your password</h2>
1
+ <h2><%= t 'devise.invitations.edit.header' %></h2>
2
2
 
3
3
  <%= form_for resource, :as => resource_name, :url => invitation_path(resource_name), :html => { :method => :put } do |f| %>
4
4
  <%= devise_error_messages! %>
@@ -10,5 +10,5 @@
10
10
  <p><%= f.label :password_confirmation %><br />
11
11
  <%= f.password_field :password_confirmation %></p>
12
12
 
13
- <p><%= f.submit "Set my password" %></p>
13
+ <p><%= f.submit t("devise.invitations.edit.submit_button") %></p>
14
14
  <% end %>
@@ -1,4 +1,4 @@
1
- <h2>Send invitation</h2>
1
+ <h2><%= t "devise.invitations.new.header" %></h2>
2
2
 
3
3
  <%= form_for resource, :as => resource_name, :url => invitation_path(resource_name), :html => {:method => :post} do |f| %>
4
4
  <%= devise_error_messages! %>
@@ -8,7 +8,5 @@
8
8
  <%= f.text_field field %></p>
9
9
  <% end -%>
10
10
 
11
- <p><%= f.submit "Send an invitation" %></p>
11
+ <p><%= f.submit t("devise.invitations.new.submit_button") %></p>
12
12
  <% end %>
13
-
14
- <%= link_to "Home", after_sign_in_path_for(resource_name) %><br />
@@ -5,6 +5,12 @@ en:
5
5
  invitation_token_invalid: 'The invitation token provided is not valid!'
6
6
  updated: 'Your password was set successfully. You are now signed in.'
7
7
  no_invitations_remaining: "No invitations remaining"
8
+ new:
9
+ header: "Send invitation"
10
+ submit_button: "Send an invitation"
11
+ edit:
12
+ header: "Set your password"
13
+ submit_button: "Set my password"
8
14
  mailer:
9
15
  invitation_instructions:
10
16
  subject: 'Invitation instructions'
@@ -10,30 +10,29 @@ module DeviseInvitable::Controllers::Registrations
10
10
  if hash && hash[:email]
11
11
  resource = resource_class.where(:email => hash[:email], :encrypted_password => '').first
12
12
  if resource
13
- @invitation_info = {}
14
- @invitation_info[:invitation_sent_at] = resource[:invitation_sent_at]
15
- @invitation_info[:invited_by_id] = resource[:invited_by_id]
16
- @invitation_info[:invited_by_type] = resource[:invited_by_type]
13
+ @invitation_info = Hash[resource.invitation_fields.map {|field|
14
+ [field, resource[field]]
15
+ }]
17
16
  resource.destroy
18
17
  end
19
18
  end
20
19
  end
21
-
20
+
22
21
  def keep_invitation_info
23
22
  resource_invitable = resource_class.devise_modules.include?(:invitable)
24
23
  destroy_if_previously_invited if resource_invitable
25
24
  yield
26
25
  reset_invitation_info if resource_invitable
27
26
  end
28
-
27
+
29
28
  def reset_invitation_info
30
29
  # Restore info about the last invitation (for later reference)
31
30
  # Reset the invitation_info only, if invited_by_id is still nil at this stage:
32
31
  resource = resource_class.where(:email => params[resource_name][:email], :invited_by_id => nil).first
33
32
  if resource && @invitation_info
34
- resource[:invitation_sent_at] = @invitation_info[:invitation_sent_at]
35
- resource[:invited_by_id] = @invitation_info[:invited_by_id]
36
- resource[:invited_by_type] = @invitation_info[:invited_by_type]
33
+ resource.invitation_fields.each do |field|
34
+ resource[field] = @invitation_info[field]
35
+ end
37
36
  resource.save!
38
37
  end
39
38
  end
@@ -1,42 +1,35 @@
1
1
  module DeviseInvitable::Controllers::Registrations
2
2
  def self.included(controller)
3
- controller.send :around_filter, :keep_invitation_info, :only => :create
3
+ controller.send :around_filter, :destroy_if_previously_invited, :only => :create
4
4
  end
5
5
 
6
6
  protected
7
7
 
8
8
  def destroy_if_previously_invited
9
- @invitation_info = {}
9
+ invitation_info = {}
10
10
 
11
11
  hash = params[resource_name]
12
- if hash && hash[:email]
12
+ if resource_class.modules.include?(:invitable) && hash && hash[:email]
13
13
  resource = resource_class.where(:email => hash[:email], :encrypted_password => '').first
14
14
  if resource
15
- @invitation_info[:invitation_sent_at] = resource[:invitation_sent_at]
16
- @invitation_info[:invited_by_id] = resource[:invited_by_id]
17
- @invitation_info[:invited_by_type] = resource[:invited_by_type]
15
+ invitation_info[:invitation_sent_at] = resource[:invitation_sent_at]
16
+ invitation_info[:invited_by_id] = resource[:invited_by_id]
17
+ invitation_info[:invited_by_type] = resource[:invited_by_type]
18
18
  resource.destroy
19
19
  end
20
20
  end
21
- end
22
-
23
- def keep_invitation_info
24
- resource_invitable = resource_class.devise_modules.include?(:invitable)
25
- destroy_if_previously_invited if resource_invitable
21
+
22
+ # execute the action (create)
26
23
  yield
27
- reset_invitation_info if resource_invitable
28
- end
29
-
30
- def reset_invitation_info
31
- puts @invitation_info.inspect
24
+ # Note that the after_filter is executed at THIS position !
25
+
32
26
  # Restore info about the last invitation (for later reference)
33
27
  # Reset the invitation_info only, if invited_by_id is still nil at this stage:
34
- resource = resource_class.where(:email => params[resource_name][:email], :invited_by_id => nil).first
35
- puts resource.inspect
28
+ resource = resource_class.where(:email => hash[:email], :invited_by_id => nil).first
36
29
  if resource
37
- resource[:invitation_sent_at] = @invitation_info[:invitation_sent_at]
38
- resource[:invited_by_id] = @invitation_info[:invited_by_id]
39
- resource[:invited_by_type] = @invitation_info[:invited_by_type]
30
+ resource[:invitation_sent_at] = invitation_info[:invitation_sent_at]
31
+ resource[:invited_by_id] = invitation_info[:invited_by_id]
32
+ resource[:invited_by_type] = invitation_info[:invited_by_type]
40
33
  resource.save!
41
34
  end
42
35
  end
@@ -1,6 +1,6 @@
1
1
  module DeviseInvitable
2
2
  module Mailer
3
-
3
+
4
4
  # Deliver an invitation email
5
5
  def invitation_instructions(record)
6
6
  devise_mail(record, :invitation_instructions)
@@ -27,55 +27,99 @@ module Devise
27
27
  attr_accessor :completing_invite
28
28
 
29
29
  included do
30
- include ::DeviseInvitable::Inviter
31
- belongs_to :invited_by, :polymorphic => true
32
-
30
+ include ::DeviseInvitable::Inviter
31
+ if Devise.invited_by_class_name
32
+ belongs_to :invited_by, :class_name => Devise.invited_by_class_name
33
+ else
34
+ belongs_to :invited_by, :polymorphic => true
35
+ end
36
+
33
37
  include ActiveSupport::Callbacks
34
38
  define_callbacks :invitation_accepted
35
-
39
+
36
40
  attr_writer :skip_password
41
+
42
+ scope :invitation_not_accepted, where(:invitation_accepted_at => nil)
43
+ if defined?(Mongoid) && self < Mongoid::Document
44
+ scope :invitation_accepted, where(:invitation_accepted_at.ne => nil)
45
+ else
46
+ scope :invitation_accepted, where(arel_table[:invitation_accepted_at].not_eq(nil))
47
+
48
+ [:before_invitation_accepted, :after_invitation_accepted].each do |callback_method|
49
+ send callback_method do
50
+ notify_observers callback_method
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ def self.required_fields(klass)
57
+ fields = [:invitation_token, :invitation_sent_at, :invitation_accepted_at,
58
+ :invitation_limit, :invited_by_id, :invited_by_type]
59
+ if Devise.invited_by_class_name
60
+ fields -= :invited_by_type
61
+ end
62
+ fields
63
+ end
64
+
65
+ def invitation_fields
66
+ fields = [:invitation_sent_at, :invited_by_id, :invited_by_type]
67
+ if Devise.invited_by_class_name
68
+ fields -= :invited_by_type
69
+ end
70
+ fields
37
71
  end
38
72
 
39
73
  # Accept an invitation by clearing invitation token and and setting invitation_accepted_at
40
74
  # Confirms it if model is confirmable
41
75
  def accept_invitation!
42
- self.completing_invite = true
76
+ self.invitation_accepted_at = Time.now.utc
43
77
  if self.invited_to_sign_up? && self.valid?
44
78
  run_callbacks :invitation_accepted do
45
79
  self.invitation_token = nil
46
- self.invitation_accepted_at = Time.now.utc if respond_to? :"invitation_accepted_at="
47
- self.completing_invite = false
48
80
  self.save(:validate => false)
49
81
  end
50
82
  end
51
83
  end
52
84
 
53
- # Verifies whether a user has accepted an invite, was never invited, or is in the process of accepting an invitation, or not
85
+ # Verifies whether a user has accepted an invitation (or is accepting it), or was never invited
54
86
  def accepting_or_not_invited?
55
- !!completing_invite || !invited_to_sign_up?
87
+ ActiveSupport::Deprecation.warn "accepting_or_not_invited? is deprecated and will be removed from DeviseInvitable 1.1.0 (use accepted_or_not_invited? instead)"
88
+ accepted_or_not_invited?
56
89
  end
57
90
 
58
91
  # Verifies whether a user has been invited or not
59
92
  def invited_to_sign_up?
60
93
  persisted? && invitation_token.present?
61
94
  end
62
-
95
+
96
+ # Verifies whether a user accepted an invitation (or is accepting it)
97
+ def invitation_accepted?
98
+ invitation_accepted_at.present?
99
+ end
100
+
101
+ # Verifies whether a user has accepted an invitation (or is accepting it), or was never invited
102
+ def accepted_or_not_invited?
103
+ invitation_accepted? || !invited_to_sign_up?
104
+ end
105
+
63
106
  def invited?
107
+ ActiveSupport::Deprecation.warn "invited? is deprecated and will be removed from DeviseInvitable 1.1.0 (use invited_to_sign_up? instead)"
64
108
  invited_to_sign_up?
65
109
  end
66
- deprecate :invited?
67
110
 
68
111
  # Reset invitation token and send invitation again
69
- def invite!
112
+ def invite!(invited_by = nil)
70
113
  was_invited = invited_to_sign_up?
71
114
  self.skip_confirmation! if self.new_record? && self.respond_to?(:skip_confirmation!)
72
115
  generate_invitation_token if self.invitation_token.nil?
73
116
  self.invitation_sent_at = Time.now.utc
74
-
117
+ self.invited_by = invited_by if invited_by
118
+
75
119
  # Call these before_validate methods since we aren't validating on save
76
120
  self.downcase_keys if self.new_record? && self.respond_to?(:downcase_keys)
77
121
  self.strip_whitespace if self.new_record? && self.respond_to?(:strip_whitespace)
78
-
122
+
79
123
  if save(:validate => false)
80
124
  self.invited_by.decrement_invitation_limit! if !was_invited and self.invited_by.present?
81
125
  deliver_invitation unless @skip_invitation
@@ -93,12 +137,12 @@ module Devise
93
137
  def valid_password?(password)
94
138
  super unless invited_to_sign_up?
95
139
  end
96
-
140
+
97
141
  def reset_password!(new_password, new_password_confirmation)
98
142
  super
99
143
  accept_invitation!
100
144
  end
101
-
145
+
102
146
  def invite_key_valid?
103
147
  return true unless self.class.invite_key.is_a? Hash # FIXME: remove this line when deprecation is removed
104
148
  self.class.invite_key.all? do |key, regexp|
@@ -114,7 +158,7 @@ module Devise
114
158
 
115
159
  # Deliver the invitation email
116
160
  def deliver_invitation
117
- ::Devise.mailer.invitation_instructions(self).deliver
161
+ send_devise_notification(:invitation_instructions)
118
162
  end
119
163
 
120
164
  # Checks if the invitation for the user is within the limit time.
@@ -156,7 +200,7 @@ module Devise
156
200
  Array(invite_key)
157
201
  end
158
202
  end
159
-
203
+
160
204
  # Attempt to find a user by it's email. If a record is not found, create a new
161
205
  # user and send invitation to it. If user is found, returns the user with an
162
206
  # email already exists error.
@@ -190,7 +234,7 @@ module Devise
190
234
  end
191
235
  [invitable, mail]
192
236
  end
193
-
237
+
194
238
  # Override this method if the invitable is using Mass Assignment Security
195
239
  # and the inviter has a non-default role.
196
240
  def inviter_role(inviter)
@@ -226,16 +270,16 @@ module Devise
226
270
  def invitation_token
227
271
  generate_token(:invitation_token)
228
272
  end
229
-
273
+
230
274
  # Callback convenience methods
231
275
  def before_invitation_accepted(*args, &blk)
232
276
  set_callback(:invitation_accepted, :before, *args, &blk)
233
277
  end
234
-
278
+
235
279
  def after_invitation_accepted(*args, &blk)
236
280
  set_callback(:invitation_accepted, :after, *args, &blk)
237
281
  end
238
-
282
+
239
283
 
240
284
  Devise::Models.config(self, :invite_for)
241
285
  Devise::Models.config(self, :validate_on_invite)
@@ -52,7 +52,7 @@ module Devise
52
52
 
53
53
  # Verifies whether a user has accepted an invite, was never invited, or is in the process of accepting an invitation, or not
54
54
  def accepting_or_not_invited?
55
- !!completing_invite || !invited_to_sign_up?
55
+ !!completing_invite || invited_to_sign_up?
56
56
  end
57
57
 
58
58
  # Verifies whether a user has been invited or not
@@ -98,13 +98,6 @@ module Devise
98
98
  super
99
99
  accept_invitation!
100
100
  end
101
-
102
- def invite_key_valid?
103
- return true unless self.class.invite_key.is_a? Hash # FIXME: remove this line when deprecation is removed
104
- self.class.invite_key.all? do |key, regexp|
105
- regexp.nil? || self.send(key).try(:match, regexp)
106
- end
107
- end
108
101
 
109
102
  protected
110
103
  # Overriding the method in Devise's :validatable module so password is not required on inviting
@@ -147,16 +140,6 @@ module Devise
147
140
  end
148
141
 
149
142
  module ClassMethods
150
- # Return fields to invite
151
- def invite_key_fields
152
- if invite_key.is_a? Hash
153
- invite_key.keys
154
- else
155
- ActiveSupport::Deprecation.warn("invite_key should be a hash like {#{invite_key.inspect} => /.../}")
156
- Array(invite_key)
157
- end
158
- end
159
-
160
143
  # Attempt to find a user by it's email. If a record is not found, create a new
161
144
  # user and send invitation to it. If user is found, returns the user with an
162
145
  # email already exists error.
@@ -164,24 +147,16 @@ module Devise
164
147
  # resend_invitation is set to false
165
148
  # Attributes must contain the user email, other attributes will be set in the record
166
149
  def _invite(attributes={}, invited_by=nil, &block)
167
- invite_key_array = invite_key_fields
168
- attributes_hash = {}
169
- invite_key_array.each do |k,v|
170
- attributes_hash[k] = attributes.delete(k)
171
- end
172
-
173
- invitable = find_or_initialize_with_errors(invite_key_array, attributes_hash)
150
+ invitable = find_or_initialize_with_error_by(invite_key, attributes.delete(invite_key))
174
151
  invitable.assign_attributes(attributes, :as => inviter_role(invited_by))
175
152
  invitable.invited_by = invited_by
176
153
 
177
154
  invitable.skip_password = true
178
155
  invitable.valid? if self.validate_on_invite
179
156
  if invitable.new_record?
180
- invitable.errors.clear if !self.validate_on_invite and invitable.invite_key_valid?
181
- elsif !invitable.invited_to_sign_up? || !self.resend_invitation
182
- invite_key_fields.each do |key|
183
- invitable.errors.add(key, :taken)
184
- end
157
+ invitable.errors.clear if !self.validate_on_invite and invitable.email.try(:match, Devise.email_regexp)
158
+ else
159
+ invitable.errors.add(invite_key, :taken) unless invitable.invited_to_sign_up? && self.resend_invitation
185
160
  end
186
161
 
187
162
  if invitable.errors.empty?
@@ -1,6 +1,6 @@
1
1
  module ActionDispatch::Routing
2
2
  class Mapper
3
-
3
+
4
4
  protected
5
5
  def devise_invitation(mapping, controllers)
6
6
  resource :invitation, :only => [:new, :create, :update],
@@ -8,6 +8,6 @@ module ActionDispatch::Routing
8
8
  get :edit, :path => mapping.path_names[:accept], :as => :accept
9
9
  end
10
10
  end
11
-
11
+
12
12
  end
13
13
  end
@@ -1,3 +1,3 @@
1
1
  module DeviseInvitable
2
- VERSION = '1.0.2'
2
+ VERSION = '1.1.0'
3
3
  end
@@ -54,6 +54,11 @@ module Devise
54
54
  # config.resend_invitation = false
55
55
  mattr_accessor :resend_invitation
56
56
  @@resend_invitation = true
57
+
58
+ # Public: The class name of the inviting model. If this is nil,
59
+ # the #invited_by association is declared to be polymorphic. (default: nil)
60
+ mattr_accessor :invited_by_class_name
61
+ @@invited_by_class_name = nil
57
62
  end
58
63
 
59
64
  Devise.add_module :invitable, :controller => :invitations, :model => 'devise_invitable/model', :route => :invitation
@@ -3,16 +3,16 @@ module DeviseInvitable
3
3
  class InstallGenerator < Rails::Generators::Base
4
4
  source_root File.expand_path("../../templates", __FILE__)
5
5
  desc "Add DeviseInvitable config variables to the Devise initializer and copy DeviseInvitable locale files to your application."
6
-
6
+
7
7
  # def devise_install
8
8
  # invoke "devise:install"
9
9
  # end
10
-
10
+
11
11
  def add_config_options_to_initializer
12
12
  devise_initializer_path = "config/initializers/devise.rb"
13
13
  if File.exist?(devise_initializer_path)
14
14
  old_content = File.read(devise_initializer_path)
15
-
15
+
16
16
  if old_content.match(Regexp.new(/^\s# ==> Configuration for :invitable\n/))
17
17
  false
18
18
  else
@@ -23,20 +23,20 @@ module DeviseInvitable
23
23
  # this period, the invited resource won't be able to accept the invitation.
24
24
  # When invite_for is 0 (the default), the invitation won't expire.
25
25
  # config.invite_for = 2.weeks
26
-
26
+
27
27
  # Number of invitations users can send.
28
28
  # If invitation_limit is nil, users can send unlimited invitations.
29
29
  # If invitation_limit is 0, users can't send invitations.
30
30
  # If invitation_limit n > 0, users can send n invitations.
31
31
  # Default: nil
32
32
  # config.invitation_limit = 5
33
-
33
+
34
34
  # The key to be used to check existing users when sending an invitation
35
35
  # and the regexp used to test it when validate_on_invite is not set.
36
36
  # config.invite_key = {:email => /\A[^@]+@[^@]+\z/}
37
37
  # config.invite_key = {:email => /\A[^@]+@[^@]+\z/, :username => nil}
38
-
39
- # Flag that force a record to be valid before being actually invited
38
+
39
+ # Flag that force a record to be valid before being actually invited
40
40
  # Default: false
41
41
  # config.validate_on_invite = true
42
42
 
@@ -45,11 +45,11 @@ CONTENT
45
45
  end
46
46
  end
47
47
  end
48
-
48
+
49
49
  def copy_locale
50
50
  copy_file "../../../config/locales/en.yml", "config/locales/devise_invitable.en.yml"
51
51
  end
52
-
52
+
53
53
  end
54
54
  end
55
55
  end
@@ -0,0 +1,11 @@
1
+ <h2><%= t 'devise.invitations.edit.header' %></h2>
2
+
3
+ <%= simple_form_for resource, :as => resource_name, :url => invitation_path(resource_name), :html => { :method => :put } do |f| %>
4
+ <%= devise_error_messages! %>
5
+ <%= f.hidden_field :invitation_token %>
6
+
7
+ <%= f.input :password %>
8
+ <%= f.input :password_confirmation %>
9
+
10
+ <%= f.submit t("devise.invitations.edit.submit_button") %>
11
+ <% end %>
@@ -0,0 +1,11 @@
1
+ <h2><%= t "devise.invitations.new.header" %></h2>
2
+
3
+ <%= simple_form_for resource, :as => resource_name, :url => invitation_path(resource_name), :html => {:method => :post} do |f| %>
4
+ <%= devise_error_messages! %>
5
+
6
+ <% resource.class.invite_key_fields.each do |field| -%>
7
+ <%= f.input field %>
8
+ <% end -%>
9
+
10
+ <%= f.submit t("devise.invitations.new.submit_button") %>
11
+ <% end %>
@@ -2,18 +2,40 @@ require 'generators/devise/views_generator'
2
2
 
3
3
  module DeviseInvitable
4
4
  module Generators
5
- class ViewsGenerator < Rails::Generators::Base
6
- desc 'Copies all DeviseInvitable views to your application.'
5
+ class InvitationViewsGenerator < Rails::Generators::Base
6
+ include ::Devise::Generators::ViewPathTemplates
7
+
8
+ def copy_views
9
+ view_directory :invitations
10
+ end
11
+ end
12
+
13
+ class SimpleFormForGenerator < InvitationViewsGenerator
14
+ source_root File.expand_path("../templates/simple_form_for", __FILE__)
15
+ end
7
16
 
8
- argument :scope, :required => false, :default => nil,
9
- :desc => "The scope to copy views to"
17
+ class FormForGenerator < InvitationViewsGenerator
18
+ source_root File.expand_path("../../../../app/views/devise", __FILE__)
19
+ end
10
20
 
21
+ class MailerViewsGenerator < Rails::Generators::Base
11
22
  include ::Devise::Generators::ViewPathTemplates
12
23
  source_root File.expand_path("../../../../app/views/devise", __FILE__)
24
+ desc "Copies Devise mail erb views to your application."
25
+ hide!
26
+
13
27
  def copy_views
14
- view_directory :invitations
15
28
  view_directory :mailer
16
29
  end
17
30
  end
31
+
32
+ class ViewsGenerator < Rails::Generators::Base
33
+ desc 'Copies all DeviseInvitable views to your application.'
34
+ argument :scope, :required => false, :default => nil, :desc => "The scope to copy views to"
35
+
36
+ invoke MailerViewsGenerator
37
+
38
+ hook_for :form_builder, :aliases => "-b", :desc => "Form builder to be used", :default => defined?(SimpleForm) ? "simple_form_for" : "form_for"
39
+ end
18
40
  end
19
41
  end
metadata CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
+ - 1
8
9
  - 0
9
- - 2
10
- version: 1.0.2
10
+ version: 1.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Sergio Cambra
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-05-26 00:00:00 Z
18
+ date: 2012-08-20 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: bundler
@@ -23,7 +23,7 @@ dependencies:
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
24
  none: false
25
25
  requirements:
26
- - - ~>
26
+ - - ">="
27
27
  - !ruby/object:Gem::Version
28
28
  hash: 19
29
29
  segments:
@@ -34,7 +34,7 @@ dependencies:
34
34
  type: :development
35
35
  version_requirements: *id001
36
36
  - !ruby/object:Gem::Dependency
37
- name: rails
37
+ name: railties
38
38
  prerelease: false
39
39
  requirement: &id002 !ruby/object:Gem::Requirement
40
40
  none: false
@@ -49,21 +49,36 @@ dependencies:
49
49
  type: :runtime
50
50
  version_requirements: *id002
51
51
  - !ruby/object:Gem::Dependency
52
- name: devise
52
+ name: actionmailer
53
53
  prerelease: false
54
54
  requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ~>
58
+ - !ruby/object:Gem::Version
59
+ hash: 7
60
+ segments:
61
+ - 3
62
+ - 0
63
+ version: "3.0"
64
+ type: :runtime
65
+ version_requirements: *id003
66
+ - !ruby/object:Gem::Dependency
67
+ name: devise
68
+ prerelease: false
69
+ requirement: &id004 !ruby/object:Gem::Requirement
55
70
  none: false
56
71
  requirements:
57
72
  - - ">="
58
73
  - !ruby/object:Gem::Version
59
- hash: 15
74
+ hash: 11
60
75
  segments:
61
76
  - 2
77
+ - 1
62
78
  - 0
63
- - 0
64
- version: 2.0.0
79
+ version: 2.1.0
65
80
  type: :runtime
66
- version_requirements: *id003
81
+ version_requirements: *id004
67
82
  description: It adds support for send invitations by email (it requires to be authenticated) and accept the invitation by setting a password.
68
83
  email:
69
84
  - sergio@entrecables.com
@@ -74,33 +89,31 @@ extensions: []
74
89
  extra_rdoc_files: []
75
90
 
76
91
  files:
77
- - app/views/devise/mailer/invitation_instructions.html.erb
78
- - app/views/devise/invitations/new.html.erb~
92
+ - app/controllers/devise/invitations_controller.rb
79
93
  - app/views/devise/invitations/edit.html.erb
80
94
  - app/views/devise/invitations/new.html.erb
81
- - app/controllers/devise/invitations_controller.rb
82
- - app/controllers/devise/invitations_controller.rb~
95
+ - app/views/devise/mailer/invitation_instructions.html.erb
83
96
  - config/locales/en.yml
84
97
  - lib/devise_invitable.rb
85
- - lib/devise_invitable.rb~
86
- - lib/devise_invitable/routes.rb
98
+ - lib/devise_invitable/mailer.rb
87
99
  - lib/devise_invitable/model.rb
88
100
  - lib/devise_invitable/rails.rb
89
- - lib/devise_invitable/mailer.rb
101
+ - lib/devise_invitable/routes.rb
90
102
  - lib/devise_invitable/version.rb
91
- - lib/devise_invitable/model.rb~
92
- - lib/devise_invitable/inviter.rb
93
- - lib/devise_invitable/controllers/url_helpers.rb
94
103
  - lib/devise_invitable/controllers/helpers.rb
95
- - lib/devise_invitable/controllers/registrations.rb~
104
+ - lib/devise_invitable/controllers/url_helpers.rb
96
105
  - lib/devise_invitable/controllers/registrations.rb
97
- - lib/generators/active_record/templates/migration.rb
106
+ - lib/devise_invitable/controllers/registrations.rb~
107
+ - lib/devise_invitable/inviter.rb
108
+ - lib/devise_invitable/model.rb~
98
109
  - lib/generators/active_record/devise_invitable_generator.rb
99
- - lib/generators/mongoid/devise_invitable_generator.rb
100
- - lib/generators/devise_invitable/install_generator.rb
110
+ - lib/generators/active_record/templates/migration.rb
101
111
  - lib/generators/devise_invitable/views_generator.rb
102
112
  - lib/generators/devise_invitable/devise_invitable_generator.rb
103
- - lib/generators/devise_invitable/install_generator.rb~
113
+ - lib/generators/devise_invitable/install_generator.rb
114
+ - lib/generators/devise_invitable/templates/simple_form_for/invitations/edit.html.erb
115
+ - lib/generators/devise_invitable/templates/simple_form_for/invitations/new.html.erb
116
+ - lib/generators/mongoid/devise_invitable_generator.rb
104
117
  - LICENSE
105
118
  - README.rdoc
106
119
  homepage: https://github.com/scambra/devise_invitable
@@ -138,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
138
151
  requirements: []
139
152
 
140
153
  rubyforge_project:
141
- rubygems_version: 1.8.10
154
+ rubygems_version: 1.8.23
142
155
  signing_key:
143
156
  specification_version: 3
144
157
  summary: An invitation strategy for Devise
@@ -1,48 +0,0 @@
1
- class Devise::InvitationsController < ApplicationController
2
- include Devise::Controllers::InternalHelpers
3
-
4
- before_filter :authenticate_inviter!, :only => [:new, :create]
5
- before_filter :require_no_authentication, :only => [:edit, :update]
6
- helper_method :after_sign_in_path_for
7
-
8
- # GET /resource/invitation/new
9
- def new
10
- build_resource
11
- render_with_scope :new
12
- end
13
-
14
- # POST /resource/invitation
15
- def create
16
- self.resource = resource_class.invite!(params[resource_name])
17
-
18
- if resource.errors.empty?
19
- puts params.inspect
20
- set_flash_message :notice, :send_instructions, :email => self.resource.email
21
- redirect_to after_sign_in_path_for(resource_name)
22
- else
23
- render_with_scope :new
24
- end
25
- end
26
-
27
- # GET /resource/invitation/accept?invitation_token=abcdef
28
- def edit
29
- if params[:invitation_token] && self.resource = resource_class.first(:conditions => { :invitation_token => params[:invitation_token] })
30
- render_with_scope :edit
31
- else
32
- set_flash_message(:alert, :invitation_token_invalid)
33
- redirect_to after_sign_out_path_for(resource_name)
34
- end
35
- end
36
-
37
- # PUT /resource/invitation
38
- def update
39
- self.resource = resource_class.accept_invitation!(params[resource_name])
40
-
41
- if resource.errors.empty?
42
- set_flash_message :notice, :updated
43
- sign_in_and_redirect(resource_name, resource)
44
- else
45
- render_with_scope :edit
46
- end
47
- end
48
- end
@@ -1,14 +0,0 @@
1
- <h2>Send invitation</h2>
2
-
3
- <%= form_for resource, :as => resource_name, :url => invitation_path(resource_name), :html => {:method => :post} do |f| %>
4
- <%= devise_error_messages! %>
5
-
6
- <% Array(resource.class.invite_key).each do |field| -%>
7
- <p><%= f.label field %><br />
8
- <%= f.text_field field %></p>
9
- <% end -%>
10
-
11
- <p><%= f.submit "Send an invitation" %></p>
12
- <% end %>
13
-
14
- <%= link_to "Home", after_sign_in_path_for(resource_name) %><br />
@@ -1,68 +0,0 @@
1
- require 'devise'
2
-
3
- module DeviseInvitable
4
- autoload :Inviter, 'devise_invitable/inviter'
5
- end
6
-
7
- require 'devise_invitable/mailer'
8
- require 'devise_invitable/routes'
9
- require 'devise_invitable/controllers/url_helpers'
10
- require 'devise_invitable/controllers/registrations'
11
- require 'devise_invitable/controllers/helpers'
12
- require 'devise_invitable/rails'
13
-
14
- module Devise
15
- # Public: Validity period of the invitation token (default: 0). If
16
- # invite_for is 0 or nil, the invitation will never expire.
17
- # Set invite_for in the Devise configuration file (in config/initializers/devise.rb).
18
- #
19
- # config.invite_for = 2.weeks # => The invitation token will be valid 2 weeks
20
- mattr_accessor :invite_for
21
- @@invite_for = 0
22
-
23
- # Public: Flag that force a record to be valid before being actually invited
24
- # (default: false).
25
- #
26
- # Examples (in config/initializers/devise.rb)
27
- #
28
- # config.validate_on_invite = true
29
- mattr_accessor :validate_on_invite
30
- @@validate_on_invite = false
31
-
32
- # Public: number of invitations the user is allowed to send
33
- #
34
- # Examples (in config/initializers/devise.rb)
35
- #
36
- # config.invitation_limit = nil
37
- mattr_accessor :invitation_limit
38
- @@invitation_limit = nil
39
-
40
- # Public: The key to be used to check existing users when sending an invitation.
41
- # It can be an array.
42
- #
43
- # Examples (in config/initializers/devise.rb)
44
- #
45
- # config.invite_key = :email
46
- mattr_accessor :invite_key
47
- @@invite_key = :email
48
-
49
- # Public: The regexp to be used to test invite key when sending an invitation.
50
- # It must be a hash indexed by invite_key
51
- #
52
- # Examples (in config/initializers/devise.rb)
53
- #
54
- # config.invite_key = :email
55
- mattr_accessor :invite_key_validation_regexp
56
- @@invite_key_validation_regexp = {:email => Devise.email_regexp}
57
-
58
- # Public: Resend invitation if user with invited status is invited again
59
- # (default: true)
60
- #
61
- # Example (in config/initializers/devise.rb)
62
- #
63
- # config.resend_invitation = false
64
- mattr_accessor :resend_invitation
65
- @@resend_invitation = true
66
- end
67
-
68
- Devise.add_module :invitable, :controller => :invitations, :model => 'devise_invitable/model', :route => :invitation
@@ -1,54 +0,0 @@
1
- module DeviseInvitable
2
- module Generators
3
- class InstallGenerator < Rails::Generators::Base
4
- source_root File.expand_path("../../templates", __FILE__)
5
- desc "Add DeviseInvitable config variables to the Devise initializer and copy DeviseInvitable locale files to your application."
6
-
7
- # def devise_install
8
- # invoke "devise:install"
9
- # end
10
-
11
- def add_config_options_to_initializer
12
- devise_initializer_path = "config/initializers/devise.rb"
13
- if File.exist?(devise_initializer_path)
14
- old_content = File.read(devise_initializer_path)
15
-
16
- if old_content.match(Regexp.new(/^\s# ==> Configuration for :invitable\n/))
17
- false
18
- else
19
- inject_into_file(devise_initializer_path, :before => " # ==> Configuration for :confirmable\n") do
20
- <<-CONTENT
21
- # ==> Configuration for :invitable
22
- # The period the generated invitation token is valid, after
23
- # this period, the invited resource won't be able to accept the invitation.
24
- # When invite_for is 0 (the default), the invitation won't expire.
25
- # config.invite_for = 2.weeks
26
-
27
- # Number of invitations users can send.
28
- # If invitation_limit is nil, users can send unlimited invitations.
29
- # If invitation_limit is 0, users can't send invitations.
30
- # If invitation_limit n > 0, users can send n invitations.
31
- # Default: nil
32
- # config.invitation_limit = 5
33
-
34
- # The key to be used to check existing users when sending an invitation.
35
- # config.invite_key = {:email => /\A[^@]+@[^@]+\z/}
36
- # config.invite_key = {:email => /\A[^@]+@[^@]+\z/, :username => nil}
37
-
38
- # Flag that force a record to be valid before being actually invited
39
- # Default: false
40
- # config.validate_on_invite = true
41
-
42
- CONTENT
43
- end
44
- end
45
- end
46
- end
47
-
48
- def copy_locale
49
- copy_file "../../../config/locales/en.yml", "config/locales/devise_invitable.en.yml"
50
- end
51
-
52
- end
53
- end
54
- end