devise_invitable 1.3.2 → 1.3.4

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ec084ea3f59520fb7b2cfb978cd79d53ec5c1488
4
+ data.tar.gz: 257a48340805f6bfe02bc4fd1279a8694ab24c5c
5
+ SHA512:
6
+ metadata.gz: 51c1385e5d2235ef7d3004208e489ecd241e99ade5afd8d7f5a1289e48cc7e9af6ba599b058862b82c5eb9c64ee02dc63d1be1526d692ccd86c33099bda8c8a8
7
+ data.tar.gz: 86ff8fa5e4f3990ca8c5dee25acc0e663204b671337e479fc19cfc0c5d2145d79f85f5a68c1ac53790b8a4c967050e13b0a070cf8943c6c4d639684ad68898b7
data/README.rdoc CHANGED
@@ -1,7 +1,7 @@
1
1
  = DeviseInvitable
2
2
  {<img src="https://travis-ci.org/scambra/devise_invitable.png"/>}[http://travis-ci.org/scambra/devise_invitable]
3
3
 
4
- It adds support to devise[http://github.com/plataformatec/devise] for send invitations by email (it requires to be authenticated) and accept the invitation setting the password.
4
+ It adds support to devise[http://github.com/plataformatec/devise] for sending invitations by email (it requires to be authenticated) and accept the invitation setting the password.
5
5
 
6
6
  DeviseInvitable currently supports Rails 3 and 4, if you want to use it with Rails 2.3 you must install version {0.2.3}[http://rubygems.org/gems/devise_invitable/versions/0.2.3]
7
7
 
@@ -172,6 +172,30 @@ be sure that you generate the views and put them into the controller that you ge
172
172
 
173
173
  rails generate devise_invitable:views users/invitations
174
174
 
175
+ To change behaviour of inviting or accepting users, you can simply override two methods:
176
+
177
+ class Users::InvitationsController < Devise::InvitationsController
178
+ private
179
+
180
+ # this is called when creating invitation
181
+ # should return an instance of resource class
182
+ def invite_resource
183
+ ## skip sending emails on invite
184
+ resource_class.invite!(invite_params, current_inviter) do |u|
185
+ u.skip_invitation = true
186
+ end
187
+ end
188
+
189
+ # this is called when accepting invitation
190
+ # should return an instance of resource class
191
+ def accept_resource
192
+ resource = resource_class.accept_invitation!(update_resource_params)
193
+ ## Report accepting invitation to analytics
194
+ Analytics.report('invite.accept', resource.id)
195
+ resource
196
+ end
197
+ end
198
+
175
199
  == Strong Parameters
176
200
 
177
201
  When you customize your own views, you may end up adding new attributes to forms. Rails 4 moved the parameter sanitization from the model to the controller, causing DeviseInvitable to handle this concern at the controller as well. Read about it in {devise README}[http://github.com/plataformatec/devise#strong-parameters]
@@ -17,6 +17,7 @@ class Devise::InvitationsController < DeviseController
17
17
  self.resource = invite_resource
18
18
 
19
19
  if resource.errors.empty?
20
+ yield resource if block_given?
20
21
  set_flash_message :notice, :send_instructions, :email => self.resource.email if self.resource.invitation_sent_at
21
22
  respond_with resource, :location => after_invite_path_for(resource)
22
23
  else
@@ -32,9 +33,10 @@ class Devise::InvitationsController < DeviseController
32
33
 
33
34
  # PUT /resource/invitation
34
35
  def update
35
- self.resource = resource_class.accept_invitation!(update_resource_params)
36
+ self.resource = accept_resource
36
37
 
37
38
  if resource.errors.empty?
39
+ yield resource if block_given?
38
40
  flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
39
41
  set_flash_message :notice, flash_message
40
42
  sign_in(resource_name, resource)
@@ -56,6 +58,10 @@ class Devise::InvitationsController < DeviseController
56
58
  def invite_resource
57
59
  resource_class.invite!(invite_params, current_inviter)
58
60
  end
61
+
62
+ def accept_resource
63
+ resource_class.accept_invitation!(update_resource_params)
64
+ end
59
65
 
60
66
  def current_inviter
61
67
  @current_inviter ||= authenticate_inviter!
@@ -29,11 +29,20 @@ module Devise
29
29
 
30
30
  included do
31
31
  include ::DeviseInvitable::Inviter
32
- if Devise.invited_by_class_name
33
- belongs_to :invited_by, :class_name => Devise.invited_by_class_name
32
+ belongs_to_options = if Devise.invited_by_class_name
33
+ {:class_name => Devise.invited_by_class_name}
34
34
  else
35
- belongs_to :invited_by, :polymorphic => true
35
+ {:polymorphic => true}
36
36
  end
37
+ if defined?(ActiveRecord) && self < ActiveRecord::Base
38
+ counter_cache = Devise.invited_by_counter_cache
39
+ if !counter_cache && Devise.invited_by_class_name
40
+ klass = Devise.invited_by_class_name.constantize
41
+ counter_cache = klass.table_exists? && klass.columns_hash['invitations_count'].try('name')
42
+ end
43
+ belongs_to_options.merge! :counter_cache => counter_cache if counter_cache
44
+ end
45
+ belongs_to :invited_by, belongs_to_options
37
46
 
38
47
  include ActiveSupport::Callbacks
39
48
  define_callbacks :invitation_accepted
@@ -57,9 +66,8 @@ module Devise
57
66
  def self.required_fields(klass)
58
67
  fields = [:invitation_token, :invitation_created_at, :invitation_sent_at, :invitation_accepted_at,
59
68
  :invitation_limit, :invited_by_id, :invited_by_type]
60
- if Devise.invited_by_class_name
61
- fields -= [:invited_by_type]
62
- end
69
+ fields << :invitations_count if defined?(ActiveRecord) && self < ActiveRecord::Base
70
+ fields -= [:invited_by_type] if Devise.invited_by_class_name
63
71
  fields
64
72
  end
65
73
 
@@ -81,12 +89,6 @@ module Devise
81
89
  end
82
90
  end
83
91
 
84
- # Verifies whether a user has accepted an invitation (or is accepting it), or was never invited
85
- def accepting_or_not_invited?
86
- ActiveSupport::Deprecation.warn "accepting_or_not_invited? is deprecated and will be removed from DeviseInvitable 1.1.0 (use accepted_or_not_invited? instead)"
87
- accepted_or_not_invited?
88
- end
89
-
90
92
  # Verifies whether a user has been invited or not
91
93
  def invited_to_sign_up?
92
94
  persisted? && invitation_token.present?
@@ -279,19 +281,11 @@ module Devise
279
281
  invitation_token = Devise.token_generator.digest(self, :invitation_token, original_token)
280
282
 
281
283
  invitable = find_or_initialize_with_error_by(:invitation_token, invitation_token)
282
- if !invitable.persisted? && Devise.allow_insecure_token_lookup
283
- invitable = find_or_initialize_with_error_by(:invitation_token, original_token)
284
- end
285
284
  invitable.errors.add(:invitation_token, :invalid) if invitable.invitation_token && invitable.persisted? && !invitable.valid_invitation?
286
285
  invitable.invitation_token = original_token
287
286
  invitable unless only_valid && invitable.errors.present?
288
287
  end
289
288
 
290
- # Generate a token checking if one does not already exist in the database.
291
- def invitation_token
292
- generate_token(:invitation_token)
293
- end
294
-
295
289
  # Callback convenience methods
296
290
  def before_invitation_accepted(*args, &blk)
297
291
  set_callback(:invitation_accepted, :before, *args, &blk)
@@ -1,3 +1,3 @@
1
1
  module DeviseInvitable
2
- VERSION = '1.3.2'
2
+ VERSION = '1.3.4'
3
3
  end
@@ -61,6 +61,11 @@ module Devise
61
61
  # the #invited_by association is declared to be polymorphic. (default: nil)
62
62
  mattr_accessor :invited_by_class_name
63
63
  @@invited_by_class_name = nil
64
+
65
+ # Public: The column name used for counter_cache column. If this is nil,
66
+ # the #invited_by association is declared without counter_cache. (default: nil)
67
+ mattr_accessor :invited_by_counter_cache
68
+ @@invited_by_counter_cache = nil
64
69
  end
65
70
 
66
71
  Devise.add_module :invitable, :controller => :invitations, :model => 'devise_invitable/model', :route => {:invitation => [nil, :new, :accept]}
@@ -7,6 +7,8 @@ class DeviseInvitableAddTo<%= table_name.camelize %> < ActiveRecord::Migration
7
7
  t.datetime :invitation_accepted_at
8
8
  t.integer :invitation_limit
9
9
  t.references :invited_by, :polymorphic => true
10
+ t.integer :invitations_count, default: 0
11
+ t.index :invitations_count
10
12
  t.index :invitation_token, :unique => true # for invitable
11
13
  t.index :invited_by_id
12
14
  end
@@ -21,7 +23,7 @@ class DeviseInvitableAddTo<%= table_name.camelize %> < ActiveRecord::Migration
21
23
  def down
22
24
  change_table :<%= table_name %> do |t|
23
25
  t.remove_references :invited_by, :polymorphic => true
24
- t.remove :invitation_limit, :invitation_sent_at, :invitation_accepted_at, :invitation_token, :invitation_created_at
26
+ t.remove :invitations_count, :invitation_limit, :invitation_sent_at, :invitation_accepted_at, :invitation_token, :invitation_created_at
25
27
  end
26
28
  end
27
29
  end
@@ -43,6 +43,20 @@ module DeviseInvitable
43
43
  # Default: false
44
44
  # config.validate_on_invite = true
45
45
 
46
+ # Resend invitation if user with invited status is invited again
47
+ # Default: true
48
+ # config.resend_invitation = false
49
+
50
+ # The class name of the inviting model. If this is nil,
51
+ # the #invited_by association is declared to be polymorphic.
52
+ # Default: nil
53
+ # config.invited_by_class_name = 'User'
54
+
55
+ # The column name used for counter_cache column. If this is nil,
56
+ # the #invited_by association is declared without counter_cache.
57
+ # Default: nil
58
+ # config.invited_by_counter_cache = :invitations_count
59
+
46
60
  CONTENT
47
61
  end
48
62
  end
@@ -11,6 +11,16 @@ class InvitableTest < ActiveSupport::TestCase
11
11
  assert_nil new_user.invitation_token
12
12
  end
13
13
 
14
+ test 'should update the invitations count counter cache' do
15
+ if defined?(ActiveRecord)
16
+ current_user = new_user
17
+ 2.times do |index|
18
+ User.invite!({:email => "valid#{index}@email.com"}, current_user)
19
+ end
20
+ assert_equal current_user.reload.invitations_count, 2
21
+ end
22
+ end
23
+
14
24
  test 'should not generate the raw invitation token after creating a record' do
15
25
  assert_nil new_user.raw_invitation_token
16
26
  end
@@ -538,13 +548,13 @@ class InvitableTest < ActiveSupport::TestCase
538
548
 
539
549
  test 'should pass validation before accept if field is required in post-invited instance' do
540
550
  user = User.invite!(:email => "valid@email.com")
541
- user.testing_accepting_or_not_invited = true
551
+ user.testing_accepted_or_not_invited = true
542
552
  assert_equal true, user.valid?
543
553
  end
544
554
 
545
555
  test 'should fail validation after accept if field is required in post-invited instance' do
546
556
  user = User.invite!(:email => "valid@email.com")
547
- user.testing_accepting_or_not_invited = true
557
+ user.testing_accepted_or_not_invited = true
548
558
  user.accept_invitation!
549
559
  assert_equal false, user.valid?
550
560
  end
@@ -552,7 +562,7 @@ class InvitableTest < ActiveSupport::TestCase
552
562
  test 'should pass validation after accept if field is required in post-invited instance' do
553
563
  user = User.invite!(:email => "valid@email.com")
554
564
  user.username = 'test'
555
- user.testing_accepting_or_not_invited = true
565
+ user.testing_accepted_or_not_invited = true
556
566
  user.bio = "Test"
557
567
  user.accept_invitation!
558
568
  assert_equal true, user.valid?
@@ -39,12 +39,12 @@ class User < PARENT_MODEL_CLASS
39
39
  attr_accessor :callback_works, :bio, :token
40
40
  validates :username, :length => { :maximum => 20 }
41
41
 
42
- attr_accessor :testing_accepting_or_not_invited
43
- validates :username, :presence => true, :if => :testing_accepting_or_not_invited_validator?
42
+ attr_accessor :testing_accepted_or_not_invited
43
+ validates :username, :presence => true, :if => :testing_accepted_or_not_invited_validator?
44
44
  validates :bio, :presence => true, :if => :invitation_accepted?
45
45
 
46
- def testing_accepting_or_not_invited_validator?
47
- testing_accepting_or_not_invited && accepting_or_not_invited?
46
+ def testing_accepted_or_not_invited_validator?
47
+ testing_accepted_or_not_invited && accepted_or_not_invited?
48
48
  end
49
49
 
50
50
  after_invitation_accepted do |object|
@@ -90,6 +90,45 @@ Devise.setup do |config|
90
90
  # Setup a pepper to generate the encrypted password.
91
91
  # config.pepper = "e31589192aeea8807cb7d8686b0f8484d6cbfaaa65443d45144519ed1d4ffbc6ccb73b21a69ece276d94f2cac95d83990d824f36f301d6f585ededd1bf90d67d"
92
92
 
93
+ # ==> Configuration for :invitable
94
+ # The period the generated invitation token is valid, after
95
+ # this period, the invited resource won't be able to accept the invitation.
96
+ # When invite_for is 0 (the default), the invitation won't expire.
97
+ # config.invite_for = 2.weeks
98
+
99
+ # Number of invitations users can send.
100
+ # - If invitation_limit is nil, there is no limit for invitations, users can
101
+ # send unlimited invitations, invitation_limit column is not used.
102
+ # - If invitation_limit is 0, users can't send invitations by default.
103
+ # - If invitation_limit n > 0, users can send n invitations.
104
+ # You can change invitation_limit column for some users so they can send more
105
+ # or less invitations, even with global invitation_limit = 0
106
+ # Default: nil
107
+ # config.invitation_limit = 5
108
+
109
+ # The key to be used to check existing users when sending an invitation
110
+ # and the regexp used to test it when validate_on_invite is not set.
111
+ # config.invite_key = {:email => /\\A[^@]+@[^@]+\\z/}
112
+ # config.invite_key = {:email => /\\A[^@]+@[^@]+\\z/, :username => nil}
113
+
114
+ # Flag that force a record to be valid before being actually invited
115
+ # Default: false
116
+ # config.validate_on_invite = true
117
+
118
+ # Resend invitation if user with invited status is invited again
119
+ # Default: true
120
+ # config.resend_invitation = false
121
+
122
+ # The class name of the inviting model. If this is nil,
123
+ # the #invited_by association is declared to be polymorphic.
124
+ # Default: nil
125
+ # config.invited_by_class_name = 'User'
126
+
127
+ # The column name used for counter_cache column. If this is nil,
128
+ # the #invited_by association is declared without counter_cache.
129
+ # Default: nil
130
+ config.invited_by_counter_cache = :invitations_count
131
+
93
132
  # ==> Configuration for :confirmable
94
133
  # A period that the user is allowed to access the website even without
95
134
  # confirming his account. For instance, if set to 2.days, the user will be
@@ -27,15 +27,20 @@ class CreateTables < ActiveRecord::Migration
27
27
  t.integer :invitation_limit
28
28
  t.integer :invited_by_id
29
29
  t.string :invited_by_type
30
+ t.integer :invitations_count, :default => 0
30
31
 
31
32
  t.timestamps
32
33
  end
33
34
  add_index :users, :invitation_token, :unique => true
35
+ add_index :users, :invitations_count
34
36
 
35
37
  create_table :admins do |t|
36
38
  ## Database authenticatable
37
39
  t.string :email, :null => true, :default => ""
38
40
  t.string :encrypted_password, :null => true, :default => ""
41
+
42
+ t.integer :invitations_count, :default => 0
39
43
  end
44
+ add_index :admins, :invitations_count
40
45
  end
41
46
  end
metadata CHANGED
@@ -1,38 +1,34 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devise_invitable
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.2
5
- prerelease:
4
+ version: 1.3.4
6
5
  platform: ruby
7
6
  authors:
8
7
  - Sergio Cambra
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2014-01-04 00:00:00.000000000 Z
11
+ date: 2014-02-27 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: bundler
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: 1.1.0
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - '>='
28
25
  - !ruby/object:Gem::Version
29
26
  version: 1.1.0
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: actionmailer
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - '>='
36
32
  - !ruby/object:Gem::Version
37
33
  version: 3.2.6
38
34
  - - <
@@ -41,9 +37,8 @@ dependencies:
41
37
  type: :runtime
42
38
  prerelease: false
43
39
  version_requirements: !ruby/object:Gem::Requirement
44
- none: false
45
40
  requirements:
46
- - - ! '>='
41
+ - - '>='
47
42
  - !ruby/object:Gem::Version
48
43
  version: 3.2.6
49
44
  - - <
@@ -52,19 +47,17 @@ dependencies:
52
47
  - !ruby/object:Gem::Dependency
53
48
  name: devise
54
49
  requirement: !ruby/object:Gem::Requirement
55
- none: false
56
50
  requirements:
57
- - - ! '>='
51
+ - - '>='
58
52
  - !ruby/object:Gem::Version
59
- version: 3.1.0
53
+ version: 3.2.0
60
54
  type: :runtime
61
55
  prerelease: false
62
56
  version_requirements: !ruby/object:Gem::Requirement
63
- none: false
64
57
  requirements:
65
- - - ! '>='
58
+ - - '>='
66
59
  - !ruby/object:Gem::Version
67
- version: 3.1.0
60
+ version: 3.2.0
68
61
  description: It adds support for send invitations by email (it requires to be authenticated)
69
62
  and accept the invitation by setting a password.
70
63
  email:
@@ -154,6 +147,7 @@ files:
154
147
  homepage: https://github.com/scambra/devise_invitable
155
148
  licenses:
156
149
  - MIT
150
+ metadata: {}
157
151
  post_install_message:
158
152
  rdoc_options:
159
153
  - --main
@@ -162,22 +156,20 @@ rdoc_options:
162
156
  require_paths:
163
157
  - lib
164
158
  required_ruby_version: !ruby/object:Gem::Requirement
165
- none: false
166
159
  requirements:
167
- - - ! '>='
160
+ - - '>='
168
161
  - !ruby/object:Gem::Version
169
162
  version: 1.8.6
170
163
  required_rubygems_version: !ruby/object:Gem::Requirement
171
- none: false
172
164
  requirements:
173
- - - ! '>='
165
+ - - '>='
174
166
  - !ruby/object:Gem::Version
175
167
  version: 1.3.6
176
168
  requirements: []
177
169
  rubyforge_project:
178
- rubygems_version: 1.8.23
170
+ rubygems_version: 2.1.11
179
171
  signing_key:
180
- specification_version: 3
172
+ specification_version: 4
181
173
  summary: An invitation strategy for Devise
182
174
  test_files:
183
175
  - test/functional/controller_helpers_test.rb