BigW Consortium Gitlab
Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
gitlab-ce
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Forest Godfrey
gitlab-ce
Commits
01275667
Commit
01275667
authored
May 17, 2018
by
🙈 jacopo beschi 🙉
Committed by
Douwe Maan
May 17, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Resolve "Opening Project with invite but without accepting leads to 404 error page"
parent
bbd8d5b2
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
157 additions
and
15 deletions
+157
-15
accepts_pending_invitations.rb
app/controllers/concerns/accepts_pending_invitations.rb
+15
-0
confirmations_controller.rb
app/controllers/confirmations_controller.rb
+4
-0
registrations_controller.rb
app/controllers/registrations_controller.rb
+3
-1
user.rb
app/models/user.rb
+10
-0
member_invited_email.html.haml
app/views/notify/member_invited_email.html.haml
+1
-1
42531-open-invite-404.yml
changelogs/unreleased/42531-open-invite-404.yml
+5
-0
invites_spec.rb
spec/features/invites_spec.rb
+100
-12
notify_spec.rb
spec/mailers/notify_spec.rb
+1
-1
user_spec.rb
spec/models/user_spec.rb
+18
-0
No files found.
app/controllers/concerns/accepts_pending_invitations.rb
0 → 100644
View file @
01275667
module
AcceptsPendingInvitations
extend
ActiveSupport
::
Concern
def
accept_pending_invitations
return
unless
resource
.
active_for_authentication?
clear_stored_location_for_resource
if
resource
.
accept_pending_invitations!
.
any?
end
def
clear_stored_location_for_resource
session_key
=
stored_location_key_for
(
resource
)
session
.
delete
(
session_key
)
end
end
app/controllers/confirmations_controller.rb
View file @
01275667
class
ConfirmationsController
<
Devise
::
ConfirmationsController
include
AcceptsPendingInvitations
def
almost_there
flash
[
:notice
]
=
nil
render
layout:
"devise_empty"
...
...
@@ -11,6 +13,8 @@ class ConfirmationsController < Devise::ConfirmationsController
end
def
after_confirmation_path_for
(
resource_name
,
resource
)
accept_pending_invitations
# incoming resource can either be a :user or an :email
if
signed_in?
(
:user
)
after_sign_in
(
resource
)
...
...
app/controllers/registrations_controller.rb
View file @
01275667
class
RegistrationsController
<
Devise
::
RegistrationsController
include
Recaptcha
::
Verify
include
AcceptsPendingInvitations
before_action
:whitelist_query_limiting
,
only:
[
:destroy
]
...
...
@@ -16,6 +17,7 @@ class RegistrationsController < Devise::RegistrationsController
end
if
!
Gitlab
::
Recaptcha
.
load_configurations!
||
verify_recaptcha
accept_pending_invitations
super
else
flash
[
:alert
]
=
'There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.'
...
...
@@ -60,7 +62,7 @@ class RegistrationsController < Devise::RegistrationsController
def
after_sign_up_path_for
(
user
)
Gitlab
::
AppLogger
.
info
(
"User Created: username=
#{
user
.
username
}
email=
#{
user
.
email
}
ip=
#{
request
.
remote_ip
}
confirmed:
#{
user
.
confirmed?
}
"
)
user
.
confirmed?
?
dashboard_projects_path
:
users_almost_there_path
user
.
confirmed?
?
stored_location_for
(
user
)
||
dashboard_projects_path
:
users_almost_there_path
end
def
after_inactive_sign_up_path_for
(
resource
)
...
...
app/models/user.rb
View file @
01275667
...
...
@@ -860,6 +860,16 @@ class User < ActiveRecord::Base
confirmed?
&&
!
temp_oauth_email?
end
def
accept_pending_invitations!
pending_invitations
.
select
do
|
member
|
member
.
accept_invite!
(
self
)
end
end
def
pending_invitations
Member
.
where
(
invite_email:
verified_emails
).
invite
end
def
all_emails
all_emails
=
[]
all_emails
<<
email
unless
temp_oauth_email?
...
...
app/views/notify/member_invited_email.html.haml
View file @
01275667
...
...
@@ -4,7 +4,7 @@
by
=
link_to
member
.
created_by
.
name
,
user_url
(
member
.
created_by
)
to join the
=
link_to
member_source
.
human_name
,
member_source
.
web_url
=
link_to
member_source
.
human_name
,
member_source
.
public?
?
member_source
.
web_url
:
invite_url
(
@token
)
#{
member_source
.
model_name
.
singular
}
as
#{
member
.
human_access
}
.
%p
...
...
changelogs/unreleased/42531-open-invite-404.yml
0 → 100644
View file @
01275667
---
title
:
Automatically accepts project/group invite by email after user signup
merge_request
:
17634
author
:
Jacopo Beschi @jacopo-beschi
type
:
changed
spec/features/invites_spec.rb
View file @
01275667
...
...
@@ -5,18 +5,41 @@ describe 'Invites' do
let
(
:owner
)
{
create
(
:user
,
name:
'John Doe'
)
}
let
(
:group
)
{
create
(
:group
,
name:
'Owned'
)
}
let
(
:project
)
{
create
(
:project
,
:repository
,
namespace:
group
)
}
let
(
:invite
)
{
group
.
group_members
.
invite
.
last
}
let
(
:
group_
invite
)
{
group
.
group_members
.
invite
.
last
}
before
do
project
.
add_master
(
owner
)
group
.
add_user
(
owner
,
Gitlab
::
Access
::
OWNER
)
group
.
add_developer
(
'user@example.com'
,
owner
)
invite
.
generate_invite_token!
group_invite
.
generate_invite_token!
end
def
confirm_email_and_sign_in
(
new_user
)
new_user_token
=
User
.
find_by_email
(
new_user
.
email
).
confirmation_token
visit
user_confirmation_path
(
confirmation_token:
new_user_token
)
fill_in_sign_in_form
(
new_user
)
end
def
fill_in_sign_up_form
(
new_user
)
fill_in
'new_user_name'
,
with:
new_user
.
name
fill_in
'new_user_username'
,
with:
new_user
.
username
fill_in
'new_user_email'
,
with:
new_user
.
email
fill_in
'new_user_email_confirmation'
,
with:
new_user
.
email
fill_in
'new_user_password'
,
with:
new_user
.
password
click_button
"Register"
end
def
fill_in_sign_in_form
(
user
)
fill_in
'user_login'
,
with:
user
.
email
fill_in
'user_password'
,
with:
user
.
password
check
'user_remember_me'
click_button
'Sign in'
end
context
'when signed out'
do
before
do
visit
invite_path
(
invite
.
raw_invite_token
)
visit
invite_path
(
group_
invite
.
raw_invite_token
)
end
it
'renders sign in page with sign in notice'
do
...
...
@@ -25,12 +48,9 @@ describe 'Invites' do
end
it
'sign in and redirects to invitation page'
do
fill_in
'user_login'
,
with:
user
.
email
fill_in
'user_password'
,
with:
user
.
password
check
'user_remember_me'
click_button
'Sign in'
fill_in_sign_in_form
(
user
)
expect
(
current_path
).
to
eq
(
invite_path
(
invite
.
raw_invite_token
))
expect
(
current_path
).
to
eq
(
invite_path
(
group_
invite
.
raw_invite_token
))
expect
(
page
).
to
have_content
(
'You have been invited by John Doe to join group Owned as Developer.'
)
...
...
@@ -45,7 +65,7 @@ describe 'Invites' do
end
it
'shows message user already a member'
do
visit
invite_path
(
invite
.
raw_invite_token
)
visit
invite_path
(
group_
invite
.
raw_invite_token
)
expect
(
page
).
to
have_content
(
'However, you are already a member of this group.'
)
end
end
...
...
@@ -53,7 +73,7 @@ describe 'Invites' do
describe
'accepting the invitation'
do
before
do
sign_in
(
user
)
visit
invite_path
(
invite
.
raw_invite_token
)
visit
invite_path
(
group_
invite
.
raw_invite_token
)
end
it
'grants access and redirects to group page'
do
...
...
@@ -69,7 +89,7 @@ describe 'Invites' do
context
'when signed in'
do
before
do
sign_in
(
user
)
visit
invite_path
(
invite
.
raw_invite_token
)
visit
invite_path
(
group_
invite
.
raw_invite_token
)
end
it
'declines application and redirects to dashboard'
do
...
...
@@ -83,7 +103,7 @@ describe 'Invites' do
context
'when signed out'
do
before
do
visit
decline_invite_path
(
invite
.
raw_invite_token
)
visit
decline_invite_path
(
group_
invite
.
raw_invite_token
)
end
it
'declines application and redirects to sign in page'
do
...
...
@@ -94,4 +114,72 @@ describe 'Invites' do
end
end
end
describe
'invite an user using their email address'
do
let
(
:new_user
)
{
build_stubbed
(
:user
)
}
let
(
:invite_email
)
{
new_user
.
email
}
let
(
:group_invite
)
{
create
(
:group_member
,
:invited
,
group:
group
,
invite_email:
invite_email
)
}
let!
(
:project_invite
)
{
create
(
:project_member
,
:invited
,
project:
project
,
invite_email:
invite_email
)
}
before
do
stub_application_setting
(
send_user_confirmation_email:
send_email_confirmation
)
visit
invite_path
(
group_invite
.
raw_invite_token
)
end
context
'email confirmation disabled'
do
let
(
:send_email_confirmation
)
{
false
}
it
'signs up and redirects to the dashboard page with all the projects/groups invitations automatically accepted'
do
fill_in_sign_up_form
(
new_user
)
expect
(
current_path
).
to
eq
(
dashboard_projects_path
)
expect
(
page
).
to
have_content
(
project
.
full_name
)
visit
group_path
(
group
)
expect
(
page
).
to
have_content
(
group
.
full_name
)
end
context
'the user sign-up using a different email address'
do
let
(
:invite_email
)
{
build_stubbed
(
:user
).
email
}
it
'signs up and redirects to the invitation page'
do
fill_in_sign_up_form
(
new_user
)
expect
(
current_path
).
to
eq
(
invite_path
(
group_invite
.
raw_invite_token
))
end
end
end
context
'email confirmation enabled'
do
let
(
:send_email_confirmation
)
{
true
}
it
'signs up and redirects to root page with all the project/groups invitation automatically accepted'
do
fill_in_sign_up_form
(
new_user
)
confirm_email_and_sign_in
(
new_user
)
expect
(
current_path
).
to
eq
(
root_path
)
expect
(
page
).
to
have_content
(
project
.
full_name
)
visit
group_path
(
group
)
expect
(
page
).
to
have_content
(
group
.
full_name
)
end
it
"doesn't accept invitations until the user confirm his email"
do
fill_in_sign_up_form
(
new_user
)
sign_in
(
owner
)
visit
project_project_members_path
(
project
)
expect
(
page
).
to
have_content
'Invited'
end
context
'the user sign-up using a different email address'
do
let
(
:invite_email
)
{
build_stubbed
(
:user
).
email
}
it
'signs up and redirects to the invitation page'
do
fill_in_sign_up_form
(
new_user
)
confirm_email_and_sign_in
(
new_user
)
expect
(
current_path
).
to
eq
(
invite_path
(
group_invite
.
raw_invite_token
))
end
end
end
end
end
spec/mailers/notify_spec.rb
View file @
01275667
...
...
@@ -594,7 +594,7 @@ describe Notify do
it
'contains all the useful information'
do
is_expected
.
to
have_subject
"Invitation to join the
#{
project
.
full_name
}
project"
is_expected
.
to
have_html_escaped_body_text
project
.
full_name
is_expected
.
to
have_body_text
project
.
web_url
is_expected
.
to
have_body_text
project
.
full_name
is_expected
.
to
have_body_text
project_member
.
human_access
is_expected
.
to
have_body_text
project_member
.
invite_token
end
...
...
spec/models/user_spec.rb
View file @
01275667
...
...
@@ -1223,6 +1223,24 @@ describe User do
end
end
describe
'#accept_pending_invitations!'
do
let
(
:user
)
{
create
(
:user
,
email:
'user@email.com'
)
}
let!
(
:project_member_invite
)
{
create
(
:project_member
,
:invited
,
invite_email:
user
.
email
)
}
let!
(
:group_member_invite
)
{
create
(
:group_member
,
:invited
,
invite_email:
user
.
email
)
}
let!
(
:external_project_member_invite
)
{
create
(
:project_member
,
:invited
,
invite_email:
'external@email.com'
)
}
let!
(
:external_group_member_invite
)
{
create
(
:group_member
,
:invited
,
invite_email:
'external@email.com'
)
}
it
'accepts all the user members pending invitations and returns the accepted_members'
do
accepted_members
=
user
.
accept_pending_invitations!
expect
(
accepted_members
).
to
match_array
([
project_member_invite
,
group_member_invite
])
expect
(
group_member_invite
.
reload
).
not_to
be_invite
expect
(
project_member_invite
.
reload
).
not_to
be_invite
expect
(
external_project_member_invite
.
reload
).
to
be_invite
expect
(
external_group_member_invite
.
reload
).
to
be_invite
end
end
describe
'#all_emails'
do
let
(
:user
)
{
create
(
:user
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment