saucy 0.4.9 → 0.4.10
Sign up to get free protection for your applications and to get access to all the features.
@@ -50,6 +50,10 @@ class InvitationsController < ApplicationController
|
|
50
50
|
flash[:error] = t("invitations.show.used",
|
51
51
|
:default => "That invitation has already been used.")
|
52
52
|
redirect_to root_url
|
53
|
+
elsif signed_in? && current_user.email == @invitation.email
|
54
|
+
if @invitation.accept({:existing_user => current_user})
|
55
|
+
redirect_to root_url
|
56
|
+
end
|
53
57
|
else
|
54
58
|
yield
|
55
59
|
end
|
data/app/models/invitation.rb
CHANGED
@@ -9,10 +9,10 @@ class Invitation < ActiveRecord::Base
|
|
9
9
|
after_create :deliver_invitation
|
10
10
|
|
11
11
|
attr_accessor :new_user_name, :new_user_password,
|
12
|
-
:new_user_password_confirmation, :
|
13
|
-
attr_writer :new_user_email, :
|
14
|
-
attr_reader :user
|
12
|
+
:new_user_password_confirmation, :authenticating_user_password, :existing_user
|
13
|
+
attr_writer :new_user_email, :authenticating_user_email
|
15
14
|
attr_protected :account_id, :used
|
15
|
+
attr_reader :user
|
16
16
|
|
17
17
|
validate :validate_accepting_user, :on => :update
|
18
18
|
|
@@ -23,7 +23,7 @@ class Invitation < ActiveRecord::Base
|
|
23
23
|
def accept(attributes)
|
24
24
|
self.attributes = attributes
|
25
25
|
self.used = true
|
26
|
-
@user = existing_user || new_user
|
26
|
+
@user = existing_user || authenticating_user || new_user
|
27
27
|
if valid?
|
28
28
|
transaction do
|
29
29
|
save!
|
@@ -39,8 +39,8 @@ class Invitation < ActiveRecord::Base
|
|
39
39
|
@new_user_email ||= email
|
40
40
|
end
|
41
41
|
|
42
|
-
def
|
43
|
-
@
|
42
|
+
def authenticating_user_email
|
43
|
+
@authenticating_user_email ||= email
|
44
44
|
end
|
45
45
|
|
46
46
|
def to_param
|
@@ -61,14 +61,18 @@ class Invitation < ActiveRecord::Base
|
|
61
61
|
InvitationMailer.invitation(self).deliver
|
62
62
|
end
|
63
63
|
|
64
|
-
def existing_user
|
65
|
-
|
66
|
-
|
64
|
+
def existing_user?
|
65
|
+
existing_user.present?
|
66
|
+
end
|
67
|
+
|
68
|
+
def authenticating_user
|
69
|
+
if authenticating_user?
|
70
|
+
User.find_by_email(authenticating_user_email)
|
67
71
|
end
|
68
72
|
end
|
69
73
|
|
70
|
-
def
|
71
|
-
|
74
|
+
def authenticating_user?
|
75
|
+
authenticating_user_password.present?
|
72
76
|
end
|
73
77
|
|
74
78
|
def new_user
|
@@ -81,8 +85,10 @@ class Invitation < ActiveRecord::Base
|
|
81
85
|
end
|
82
86
|
|
83
87
|
def validate_accepting_user
|
84
|
-
if
|
85
|
-
|
88
|
+
if authenticating_user?
|
89
|
+
validate_authenticating_user
|
90
|
+
elsif existing_user?
|
91
|
+
true
|
86
92
|
else
|
87
93
|
validate_new_user
|
88
94
|
end
|
@@ -95,11 +101,11 @@ class Invitation < ActiveRecord::Base
|
|
95
101
|
end
|
96
102
|
end
|
97
103
|
|
98
|
-
def
|
99
|
-
if
|
100
|
-
errors.add(:
|
101
|
-
elsif !
|
102
|
-
errors.add(:
|
104
|
+
def validate_authenticating_user
|
105
|
+
if authenticating_user.nil?
|
106
|
+
errors.add(:authenticating_user_email, "isn't signed up")
|
107
|
+
elsif !authenticating_user.authenticated?(authenticating_user_password)
|
108
|
+
errors.add(:authenticating_user_password, "is incorrect")
|
103
109
|
end
|
104
110
|
end
|
105
111
|
|
@@ -13,8 +13,8 @@
|
|
13
13
|
|
14
14
|
<h5 class="legend">I am an existing user</h5>
|
15
15
|
<%= form.inputs :class => 'existing_user' do -%>
|
16
|
-
<%= form.input :
|
17
|
-
<%= form.input :
|
16
|
+
<%= form.input :authenticating_user_email, :label => 'Email' %>
|
17
|
+
<%= form.input :authenticating_user_password, :label => 'Password' %>
|
18
18
|
<% end -%>
|
19
19
|
|
20
20
|
<%= form.buttons do %>
|
@@ -32,7 +32,7 @@ Feature: Managing users
|
|
32
32
|
When I go to the settings page
|
33
33
|
Then the "Name" field should contain "Billy"
|
34
34
|
|
35
|
-
Scenario: Invite existing
|
35
|
+
Scenario: Invite existing user who is not signed in
|
36
36
|
Given the following user exists:
|
37
37
|
| email | password | password confirmation |
|
38
38
|
| invitee@example.com | secret | secret |
|
@@ -48,6 +48,20 @@ Feature: Managing users
|
|
48
48
|
Then I should be signed in
|
49
49
|
And "invitee@example.com" should be a member of the "Test" account
|
50
50
|
|
51
|
+
Scenario: Invite existing user who is signed in
|
52
|
+
Given the following user exists:
|
53
|
+
| email | password | password confirmation |
|
54
|
+
| invitee@example.com | secret | secret |
|
55
|
+
When I follow "Invite user"
|
56
|
+
And I fill in "Email" with "invitee@example.com"
|
57
|
+
And I press "Invite User"
|
58
|
+
Then I should see "invited"
|
59
|
+
When I sign out
|
60
|
+
When I sign in as "invitee@example.com/secret"
|
61
|
+
And I follow the link sent to "invitee@example.com"
|
62
|
+
Then I should be signed in
|
63
|
+
And "invitee@example.com" should be a member of the "Test" account
|
64
|
+
|
51
65
|
Scenario: Fail to accept an invitation
|
52
66
|
Given the following invitation exists:
|
53
67
|
| email |
|
@@ -11,7 +11,7 @@ describe Invitation do
|
|
11
11
|
it { should_not allow_mass_assignment_of(:used) }
|
12
12
|
|
13
13
|
%w(new_user_name new_user_email new_user_password
|
14
|
-
new_user_password_confirmation
|
14
|
+
new_user_password_confirmation authenticating_user_password).each do |attribute|
|
15
15
|
it "allows assignment of #{attribute}" do
|
16
16
|
should respond_to(attribute)
|
17
17
|
should respond_to(:"#{attribute}=")
|
@@ -45,7 +45,7 @@ describe Invitation, "saved" do
|
|
45
45
|
end
|
46
46
|
|
47
47
|
it "defauls existing user email to invited email" do
|
48
|
-
subject.
|
48
|
+
subject.authenticating_user_email.should == subject.email
|
49
49
|
end
|
50
50
|
|
51
51
|
it "generates a code" do
|
@@ -129,7 +129,7 @@ describe Invitation, "invalid accept for a new user" do
|
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
132
|
-
describe Invitation, "valid accept for an existing user" do
|
132
|
+
describe Invitation, "valid accept for an existing user authenticating" do
|
133
133
|
let(:password) { 'secret' }
|
134
134
|
let(:user) { Factory(:user,
|
135
135
|
:password => password,
|
@@ -138,7 +138,7 @@ describe Invitation, "valid accept for an existing user" do
|
|
138
138
|
let(:account) { subject.account }
|
139
139
|
|
140
140
|
let!(:result) do
|
141
|
-
subject.accept(:
|
141
|
+
subject.accept(:authenticating_user_password => password)
|
142
142
|
end
|
143
143
|
|
144
144
|
it "returns true" do
|
@@ -158,10 +158,10 @@ describe Invitation, "accepting with an invalid password" do
|
|
158
158
|
let(:user) { Factory(:user) }
|
159
159
|
subject { Factory(:invitation, :email => user.email) }
|
160
160
|
let(:account) { subject.account }
|
161
|
-
let!(:result) { subject.accept(:
|
161
|
+
let!(:result) { subject.accept(:authenticating_user_password => 'wrong') }
|
162
162
|
|
163
163
|
it "adds error messages" do
|
164
|
-
subject.errors[:
|
164
|
+
subject.errors[:authenticating_user_password].should be_present
|
165
165
|
end
|
166
166
|
|
167
167
|
it "doesn't add the user to the account" do
|
@@ -173,6 +173,28 @@ describe Invitation, "accepting with an invalid password" do
|
|
173
173
|
end
|
174
174
|
end
|
175
175
|
|
176
|
+
describe Invitation, "valid accept for an existing user specifically set" do
|
177
|
+
let(:user) { Factory(:user) }
|
178
|
+
subject { Factory(:invitation, :email => user.email) }
|
179
|
+
let(:account) { subject.account }
|
180
|
+
|
181
|
+
let!(:result) do
|
182
|
+
subject.accept({:existing_user => user})
|
183
|
+
end
|
184
|
+
|
185
|
+
it "returns true" do
|
186
|
+
result.should be_true
|
187
|
+
end
|
188
|
+
|
189
|
+
it "adds the user to the account" do
|
190
|
+
account.users.should include(user)
|
191
|
+
end
|
192
|
+
|
193
|
+
it "marks the invitation as used" do
|
194
|
+
subject.reload.should be_used
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
176
198
|
describe Invitation, "saved" do
|
177
199
|
let(:mail) { stub('invitation', :deliver => true) }
|
178
200
|
subject { Factory(:invitation) }
|
@@ -199,7 +221,7 @@ describe Invitation, "saved" do
|
|
199
221
|
end
|
200
222
|
|
201
223
|
it "defauls existing user email to invited email" do
|
202
|
-
subject.
|
224
|
+
subject.authenticating_user_email.should == subject.email
|
203
225
|
end
|
204
226
|
|
205
227
|
it "generates a code" do
|
@@ -278,10 +300,10 @@ end
|
|
278
300
|
describe Invitation, "accepting with an unknown email" do
|
279
301
|
subject { Factory(:invitation, :email => 'unknown') }
|
280
302
|
let(:account) { subject.account }
|
281
|
-
let!(:result) { subject.accept(:
|
303
|
+
let!(:result) { subject.accept(:authenticating_user_password => 'secret') }
|
282
304
|
|
283
305
|
it "adds error messages" do
|
284
|
-
subject.errors[:
|
306
|
+
subject.errors[:authenticating_user_email].should be_present
|
285
307
|
end
|
286
308
|
|
287
309
|
it "returns false" do
|
@@ -298,7 +320,7 @@ describe Invitation, "accepting an admin invite" do
|
|
298
320
|
let(:account) { subject.account }
|
299
321
|
|
300
322
|
let!(:result) do
|
301
|
-
subject.accept(:
|
323
|
+
subject.accept(:authenticating_user_password => password)
|
302
324
|
end
|
303
325
|
|
304
326
|
it "adds the user as an admin" do
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: saucy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 4
|
9
|
-
-
|
10
|
-
version: 0.4.
|
9
|
+
- 10
|
10
|
+
version: 0.4.10
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- thoughtbot, inc.
|
@@ -18,11 +18,12 @@ autorequire:
|
|
18
18
|
bindir: bin
|
19
19
|
cert_chain: []
|
20
20
|
|
21
|
-
date: 2011-04-
|
21
|
+
date: 2011-04-26 00:00:00 -04:00
|
22
22
|
default_executable:
|
23
23
|
dependencies:
|
24
24
|
- !ruby/object:Gem::Dependency
|
25
|
-
|
25
|
+
name: formtastic
|
26
|
+
prerelease: false
|
26
27
|
requirement: &id001 !ruby/object:Gem::Requirement
|
27
28
|
none: false
|
28
29
|
requirements:
|
@@ -33,11 +34,11 @@ dependencies:
|
|
33
34
|
- 1
|
34
35
|
- 2
|
35
36
|
version: "1.2"
|
37
|
+
type: :runtime
|
36
38
|
version_requirements: *id001
|
37
|
-
name: formtastic
|
38
|
-
prerelease: false
|
39
39
|
- !ruby/object:Gem::Dependency
|
40
|
-
|
40
|
+
name: railties
|
41
|
+
prerelease: false
|
41
42
|
requirement: &id002 !ruby/object:Gem::Requirement
|
42
43
|
none: false
|
43
44
|
requirements:
|
@@ -49,11 +50,11 @@ dependencies:
|
|
49
50
|
- 0
|
50
51
|
- 3
|
51
52
|
version: 3.0.3
|
53
|
+
type: :runtime
|
52
54
|
version_requirements: *id002
|
53
|
-
name: railties
|
54
|
-
prerelease: false
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
|
56
|
+
name: braintree
|
57
|
+
prerelease: false
|
57
58
|
requirement: &id003 !ruby/object:Gem::Requirement
|
58
59
|
none: false
|
59
60
|
requirements:
|
@@ -65,11 +66,11 @@ dependencies:
|
|
65
66
|
- 6
|
66
67
|
- 2
|
67
68
|
version: 2.6.2
|
69
|
+
type: :runtime
|
68
70
|
version_requirements: *id003
|
69
|
-
name: braintree
|
70
|
-
prerelease: false
|
71
71
|
- !ruby/object:Gem::Dependency
|
72
|
-
|
72
|
+
name: sham_rack
|
73
|
+
prerelease: false
|
73
74
|
requirement: &id004 !ruby/object:Gem::Requirement
|
74
75
|
none: false
|
75
76
|
requirements:
|
@@ -81,11 +82,11 @@ dependencies:
|
|
81
82
|
- 3
|
82
83
|
- 3
|
83
84
|
version: 1.3.3
|
85
|
+
type: :runtime
|
84
86
|
version_requirements: *id004
|
85
|
-
name: sham_rack
|
86
|
-
prerelease: false
|
87
87
|
- !ruby/object:Gem::Dependency
|
88
|
-
|
88
|
+
name: sinatra
|
89
|
+
prerelease: false
|
89
90
|
requirement: &id005 !ruby/object:Gem::Requirement
|
90
91
|
none: false
|
91
92
|
requirements:
|
@@ -97,11 +98,11 @@ dependencies:
|
|
97
98
|
- 1
|
98
99
|
- 2
|
99
100
|
version: 1.1.2
|
101
|
+
type: :runtime
|
100
102
|
version_requirements: *id005
|
101
|
-
name: sinatra
|
102
|
-
prerelease: false
|
103
103
|
- !ruby/object:Gem::Dependency
|
104
|
-
|
104
|
+
name: aruba
|
105
|
+
prerelease: false
|
105
106
|
requirement: &id006 !ruby/object:Gem::Requirement
|
106
107
|
none: false
|
107
108
|
requirements:
|
@@ -113,9 +114,8 @@ dependencies:
|
|
113
114
|
- 2
|
114
115
|
- 6
|
115
116
|
version: 0.2.6
|
117
|
+
type: :development
|
116
118
|
version_requirements: *id006
|
117
|
-
name: aruba
|
118
|
-
prerelease: false
|
119
119
|
description: Clearance-based Rails engine for Software as a Service (Saas) that provides account and project management
|
120
120
|
email: support@thoughtbot.com
|
121
121
|
executables: []
|
@@ -296,7 +296,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
296
296
|
requirements: []
|
297
297
|
|
298
298
|
rubyforge_project:
|
299
|
-
rubygems_version: 1.
|
299
|
+
rubygems_version: 1.3.7
|
300
300
|
signing_key:
|
301
301
|
specification_version: 3
|
302
302
|
summary: Clearance-based Rails engine for SaaS
|