1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
# frozen_string_literal: true
class InvitesController < ApplicationController
include Gitlab::Utils::StrongMemoize
before_action :member
before_action :ensure_member_exists
before_action :invite_details
skip_before_action :authenticate_user!, only: :decline
helper_method :member?, :current_user_matches_invite?
respond_to :html
feature_category :authentication_and_authorization
def show
track_new_user_invite_experiment('opened')
accept if skip_invitation_prompt?
end
def accept
if member.accept_invite!(current_user)
track_new_user_invite_experiment('accepted')
track_invitation_reminders_experiment('accepted')
redirect_to invite_details[:path], notice: _("You have been granted %{member_human_access} access to %{title} %{name}.") %
{ member_human_access: member.human_access, title: invite_details[:title], name: invite_details[:name] }
else
redirect_back_or_default(options: { alert: _("The invitation could not be accepted.") })
end
end
def decline
if member.decline_invite!
return render layout: 'devise_experimental_onboarding_issues' if !current_user && member.invite_to_unknown_user? && member.created_by
path =
if current_user
dashboard_projects_path
else
new_user_session_path
end
redirect_to path, notice: _("You have declined the invitation to join %{title} %{name}.") %
{ title: invite_details[:title], name: invite_details[:name] }
else
redirect_back_or_default(options: { alert: _("The invitation could not be declined.") })
end
end
private
def skip_invitation_prompt?
!member? && current_user_matches_invite?
end
def current_user_matches_invite?
@member.invite_email == current_user.email
end
def member?
strong_memoize(:is_member) do
@member.source.users.include?(current_user)
end
end
def member
strong_memoize(:member) do
@token = params[:id]
Member.find_by_invite_token(@token)
end
end
def ensure_member_exists
return if member
render_404
end
def authenticate_user!
return if current_user
notice = ["To accept this invitation, sign in"]
notice << "or create an account" if Gitlab::CurrentSettings.allow_signup?
notice = notice.join(' ') + "."
redirect_params = member ? { invite_email: member.invite_email } : {}
store_location_for :user, request.fullpath
redirect_to new_user_session_path(redirect_params), notice: notice
end
def invite_details
@invite_details ||= case member.source
when Project
{
name: member.source.full_name,
url: project_url(member.source),
title: _("project"),
path: project_path(member.source)
}
when Group
{
name: member.source.name,
url: group_url(member.source),
title: _("group"),
path: group_path(member.source)
}
end
end
def track_new_user_invite_experiment(action)
return unless params[:new_user_invite]
property = params[:new_user_invite] == 'experiment' ? 'experiment_group' : 'control_group'
track_experiment(:invite_email, action, property)
end
def track_invitation_reminders_experiment(action)
return unless Gitlab::Experimentation.enabled?(:invitation_reminders)
property = Gitlab::Experimentation.enabled_for_attribute?(:invitation_reminders, member.invite_email) ? 'experimental_group' : 'control_group'
track_experiment(:invitation_reminders, action, property)
end
def track_experiment(experiment_key, action, property)
Gitlab::Tracking.event(
Gitlab::Experimentation.experiment(experiment_key).tracking_category,
action,
property: property,
label: Digest::MD5.hexdigest(member.to_global_id.to_s)
)
end
end
|