Skip to content

Commit

Permalink
Add latest changes from gitlab-org/gitlab@master
Browse files Browse the repository at this point in the history
  • Loading branch information
GitLab Bot committed Oct 18, 2019
1 parent 6d59e98 commit 4682f50
Show file tree
Hide file tree
Showing 36 changed files with 380 additions and 107 deletions.
7 changes: 7 additions & 0 deletions app/assets/javascripts/pages/registrations/welcome/index.js
@@ -0,0 +1,7 @@
import LengthValidator from '~/pages/sessions/new/length_validator';
import NoEmojiValidator from '~/emoji/no_emoji_validator';

document.addEventListener('DOMContentLoaded', () => {
new LengthValidator(); // eslint-disable-line no-new
new NoEmojiValidator(); // eslint-disable-line no-new
});
11 changes: 11 additions & 0 deletions app/controllers/application_controller.rb
Expand Up @@ -29,6 +29,7 @@ class ApplicationController < ActionController::Base
before_action :active_user_check, unless: :devise_controller?
before_action :set_usage_stats_consent_flag
before_action :check_impersonation_availability
before_action :require_role

around_action :set_locale
around_action :set_session_storage
Expand Down Expand Up @@ -547,6 +548,16 @@ def allow_gitaly_ref_name_caching
def current_user_mode
@current_user_mode ||= Gitlab::Auth::CurrentUserMode.new(current_user)
end

# A user requires a role when they are part of the experimental signup flow (executed by the Growth team). Users
# are redirected to the welcome page when their role is required and the experiment is enabled for the current user.
def require_role
return unless current_user && current_user.role_required? && experiment_enabled?(:signup_flow)

store_location_for :user, request.fullpath

redirect_to users_sign_up_welcome_path
end
end

ApplicationController.prepend_if_ee('EE::ApplicationController')
4 changes: 2 additions & 2 deletions app/controllers/concerns/invisible_captcha.rb
Expand Up @@ -8,7 +8,7 @@ module InvisibleCaptcha
end

def on_honeypot_spam_callback
return unless Feature.enabled?(:invisible_captcha)
return unless Feature.enabled?(:invisible_captcha) || experiment_enabled?(:signup_flow)

invisible_captcha_honeypot_counter.increment
log_request('Invisible_Captcha_Honeypot_Request')
Expand All @@ -17,7 +17,7 @@ def on_honeypot_spam_callback
end

def on_timestamp_spam_callback
return unless Feature.enabled?(:invisible_captcha)
return unless Feature.enabled?(:invisible_captcha) || experiment_enabled?(:signup_flow)

invisible_captcha_timestamp_counter.increment
log_request('Invisible_Captcha_Timestamp_Request')
Expand Down
1 change: 1 addition & 0 deletions app/controllers/oauth/applications_controller.rb
Expand Up @@ -5,6 +5,7 @@ class Oauth::ApplicationsController < Doorkeeper::ApplicationsController
include Gitlab::Allowable
include PageLayoutHelper
include OauthApplications
include Gitlab::Experimentation::ControllerConcern

before_action :verify_user_oauth_applications_enabled, except: :index
before_action :authenticate_user!
Expand Down
1 change: 1 addition & 0 deletions app/controllers/oauth/authorizations_controller.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true

class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController
include Gitlab::Experimentation::ControllerConcern
layout 'profile'

# Overridden from Doorkeeper::AuthorizationsController to
Expand Down
1 change: 1 addition & 0 deletions app/controllers/profiles_controller.rb
Expand Up @@ -100,6 +100,7 @@ def user_params
:avatar,
:bio,
:email,
:role,
:hide_no_password,
:hide_no_ssh_key,
:hide_project_limit,
Expand Down
54 changes: 49 additions & 5 deletions app/controllers/registrations_controller.rb
Expand Up @@ -8,13 +8,14 @@ class RegistrationsController < Devise::RegistrationsController

layout :choose_layout

skip_before_action :require_role, only: [:welcome, :update_role]
prepend_before_action :check_captcha, only: :create
before_action :whitelist_query_limiting, only: [:destroy]
before_action :ensure_terms_accepted,
if: -> { action_name == 'create' && Gitlab::CurrentSettings.current_application_settings.enforce_terms? }

def new
if helpers.use_experimental_separate_sign_up_flow?
if experiment_enabled?(:signup_flow)
@resource = build_resource
else
redirect_to new_user_session_path(anchor: 'register-pane')
Expand All @@ -26,8 +27,13 @@ def create

super do |new_user|
persist_accepted_terms_if_required(new_user)
set_role_required(new_user)
yield new_user if block_given?
end

# Do not show the signed_up notice message when the signup_flow experiment is enabled.
# Instead, show it after succesfully updating the role.
flash[:notice] = nil if experiment_enabled?(:signup_flow)
rescue Gitlab::Access::AccessDeniedError
redirect_to(new_user_session_path)
end
Expand All @@ -42,6 +48,26 @@ def destroy
end
end

def welcome
return redirect_to new_user_registration_path unless current_user
return redirect_to stored_location_or_dashboard_or_almost_there_path(current_user) if current_user.role.present?

current_user.name = nil
render layout: 'devise_experimental_separate_sign_up_flow'
end

def update_role
user_params = params.require(:user).permit(:name, :role)
result = ::Users::UpdateService.new(current_user, user_params.merge(user: current_user)).execute

if result[:status] == :success
set_flash_message! :notice, :signed_up
redirect_to stored_location_or_dashboard_or_almost_there_path(current_user)
else
redirect_to users_sign_up_welcome_path, alert: result[:message]
end
end

protected

def persist_accepted_terms_if_required(new_user)
Expand All @@ -54,6 +80,10 @@ def persist_accepted_terms_if_required(new_user)
end
end

def set_role_required(new_user)
new_user.set_role_required! if new_user.persisted? && experiment_enabled?(:signup_flow)
end

def destroy_confirmation_valid?
if current_user.confirm_deletion_with_password?
current_user.valid_password?(params[:password])
Expand All @@ -76,7 +106,10 @@ def build_resource(hash = nil)

def after_sign_up_path_for(user)
Gitlab::AppLogger.info(user_created_message(confirmed: user.confirmed?))
confirmed_or_unconfirmed_access_allowed(user) ? stored_location_or_dashboard(user) : users_almost_there_path

return users_sign_up_welcome_path if experiment_enabled?(:signup_flow)

stored_location_or_dashboard_or_almost_there_path(user)
end

def after_inactive_sign_up_path_for(resource)
Expand All @@ -103,6 +136,7 @@ def check_captcha
ensure_correct_params!

return unless Feature.enabled?(:registrations_recaptcha, default_enabled: true) # reCAPTCHA on the UI will still display however
return if experiment_enabled?(:signup_flow) # when the experimental signup flow is enabled for the current user, disable the reCAPTCHA check
return unless show_recaptcha_sign_up?
return unless Gitlab::Recaptcha.load_configurations!

Expand All @@ -114,7 +148,13 @@ def check_captcha
end

def sign_up_params
params.require(:user).permit(:username, :email, :email_confirmation, :name, :password)
clean_params = params.require(:user).permit(:username, :email, :email_confirmation, :name, :password)

if experiment_enabled?(:signup_flow)
clean_params[:name] = clean_params[:username]
end

clean_params
end

def resource_name
Expand Down Expand Up @@ -144,17 +184,21 @@ def terms_accepted?
end

def confirmed_or_unconfirmed_access_allowed(user)
user.confirmed? || Feature.enabled?(:soft_email_confirmation)
user.confirmed? || Feature.enabled?(:soft_email_confirmation) || experiment_enabled?(:signup_flow)
end

def stored_location_or_dashboard(user)
stored_location_for(user) || dashboard_projects_path
end

def stored_location_or_dashboard_or_almost_there_path(user)
confirmed_or_unconfirmed_access_allowed(user) ? stored_location_or_dashboard(user) : users_almost_there_path
end

# Part of an experiment to build a new sign up flow. Will be resolved
# with https://gitlab.com/gitlab-org/growth/engineering/issues/64
def choose_layout
if helpers.use_experimental_separate_sign_up_flow?
if experiment_enabled?(:signup_flow)
'devise_experimental_separate_sign_up_flow'
else
'devise'
Expand Down
4 changes: 0 additions & 4 deletions app/helpers/sessions_helper.rb
Expand Up @@ -4,8 +4,4 @@ module SessionsHelper
def unconfirmed_email?
flash[:alert] == t(:unconfirmed, scope: [:devise, :failure])
end

def use_experimental_separate_sign_up_flow?
::Gitlab.dev_env_or_com? && Feature.enabled?(:experimental_separate_sign_up_flow)
end
end
18 changes: 18 additions & 0 deletions app/models/user.rb
Expand Up @@ -231,6 +231,10 @@ def update_tracked_fields!(request)
# Note: When adding an option, it MUST go on the end of the array.
enum project_view: [:readme, :activity, :files]

# User's role
# Note: When adding an option, it MUST go on the end of the array.
enum role: [:software_developer, :development_team_lead, :devops_engineer, :systems_administrator, :security_analyst, :data_analyst, :product_manager, :product_designer, :other], _suffix: true

delegate :path, to: :namespace, allow_nil: true, prefix: true
delegate :notes_filter_for, to: :user_preference
delegate :set_notes_filter, to: :user_preference
Expand Down Expand Up @@ -1571,6 +1575,20 @@ def last_active_at
[last_activity, last_sign_in].compact.max
end

# Below is used for the signup_flow experiment. Should be removed
# when experiment finishes.
# See https://gitlab.com/gitlab-org/growth/engineering/issues/64
REQUIRES_ROLE_VALUE = 99

def role_required?
role_before_type_cast == REQUIRES_ROLE_VALUE
end

def set_role_required!
update_column(:role, REQUIRES_ROLE_VALUE)
end
# End of signup_flow experiment methods

# @deprecated
alias_method :owned_or_masters_groups, :owned_or_maintainers_groups

Expand Down
2 changes: 1 addition & 1 deletion app/views/devise/registrations/new.html.haml
@@ -1,5 +1,5 @@
- page_title "Sign up"
- if use_experimental_separate_sign_up_flow?
- if experiment_enabled?(:signup_flow)
= render 'devise/shared/experimental_separate_sign_up_flow_box'
- else
= render 'devise/shared/signup_box'
Expand Down
2 changes: 1 addition & 1 deletion app/views/devise/sessions/new.html.haml
Expand Up @@ -4,7 +4,7 @@
- if form_based_providers.any?
= render 'devise/shared/tabs_ldap'
- else
- unless use_experimental_separate_sign_up_flow?
- unless experiment_enabled?(:signup_flow)
= render 'devise/shared/tabs_normal'
.tab-content
- if password_authentication_enabled_for_web? || ldap_enabled? || crowd_enabled?
Expand Down
@@ -1,14 +1,11 @@
- max_name_length = 128
- content_for(:page_title, _('Register for GitLab'))
- max_username_length = 255
.signup-box.p-3.mb-2
.signup-body
= form_for(resource, as: "new_#{resource_name}", url: registration_path(resource_name), html: { class: "new_new_user gl-show-field-errors", "aria-live" => "assertive" }) do |f|
.devise-errors.mt-0
= render "devise/shared/error_messages", resource: resource
= invisible_captcha
.name.form-group
= f.label :name, _('Full name'), class: 'label-bold'
= f.text_field :name, class: "form-control top js-block-emoji js-validate-length", :data => { :max_length => max_name_length, :max_length_message => s_("SignUp|Name is too long (maximum is %{max_length} characters).") % { max_length: max_name_length }, :qa_selector => 'new_user_name_field' }, required: true, title: _("This field is required.")
.username.form-group
= f.label :username, class: 'label-bold'
= f.text_field :username, class: "form-control middle js-block-emoji js-validate-length js-validate-username", :data => { :max_length => max_username_length, :max_length_message => s_("SignUp|Username is too long (maximum is %{max_length} characters).") % { max_length: max_username_length }, :qa_selector => 'new_user_username_field' }, pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, required: true, title: _("Please create a username with only alphanumeric characters.")
Expand Down
2 changes: 1 addition & 1 deletion app/views/devise/shared/_signin_box.html.haml
Expand Up @@ -23,7 +23,7 @@
.login-body
= render 'devise/sessions/new_base'

- if use_experimental_separate_sign_up_flow?
- if experiment_enabled?(:signup_flow)
%p.light.mt-2
= _("Don't have an account yet?")
= link_to _("Register now"), new_registration_path(:user)
2 changes: 1 addition & 1 deletion app/views/layouts/_head.html.haml
Expand Up @@ -5,7 +5,7 @@
-# anything from this page beforehand.
-# Part of an experiment to build a new sign up flow. Will be removed again with
-# https://gitlab.com/gitlab-org/growth/engineering/issues/64
- if use_experimental_separate_sign_up_flow? && current_path?("sessions#new")
- if experiment_enabled?(:signup_flow) && current_path?("sessions#new")
= javascript_tag nonce: true do
:plain
if (window.location.hash === '#register-pane') {
Expand Down
Expand Up @@ -14,7 +14,8 @@
= render_if_exists 'layouts/devise_help_text'
.text-center.signup-heading.mt-3.mb-3
= image_tag(image_url('logo.svg'), class: 'gitlab-logo', alt: 'GitLab Logo')
%h2= _('Register for GitLab.com')
- if content_for?(:page_title)
%h2= yield :page_title
= yield
%hr.footer-fixed
.footer-container
Expand Down
1 change: 1 addition & 0 deletions app/views/profiles/show.html.haml
Expand Up @@ -94,6 +94,7 @@
- else
= f.text_field :name, label: s_('Profiles|Full name'), required: true, title: s_("Profiles|Using emojis in names seems fun, but please try to set a status message instead"), wrapper: { class: 'col-md-9 qa-full-name rspec-full-name' }, help: s_("Profiles|Enter your name, so people you know can recognize you")
= f.text_field :id, readonly: true, label: s_('Profiles|User ID'), wrapper: { class: 'col-md-3' }
= f.select :role, ::User.roles.keys.map { |role| [role.titleize, role] }, {}, class: 'input-md'

= render_if_exists 'profiles/email_settings', form: f
= f.text_field :skype, class: 'input-md', placeholder: s_("Profiles|username")
Expand Down
17 changes: 17 additions & 0 deletions app/views/registrations/welcome.html.haml
@@ -0,0 +1,17 @@
- content_for(:page_title, _('Welcome to GitLab<br>%{username}!' % { username: html_escape(current_user.username) }).html_safe)
- max_name_length = 128
.text-center.mb-3
= _('In order to tailor your experience with GitLab<br>we would like to know a bit more about you.').html_safe
.signup-box.p-3.mb-2
.signup-body
= form_for(current_user, url: users_sign_up_update_role_path, html: { class: 'new_new_user gl-show-field-errors', 'aria-live' => 'assertive' }) do |f|
.devise-errors.mt-0
= render 'devise/shared/error_messages', resource: current_user
.name.form-group
= f.label :name, _('Full name'), class: 'label-bold'
= f.text_field :name, class: 'form-control top js-block-emoji js-validate-length', :data => { :max_length => max_name_length, :max_length_message => s_('Name is too long (maximum is %{max_length} characters).') % { max_length: max_name_length }, :qa_selector => 'new_user_name_field' }, required: true, title: _('This field is required.')
.form-group
= f.label :role, _('Role'), class: 'label-bold'
= f.select :role, ::User.roles.keys.map { |role| [role.titleize, role] }, {}, class: 'form-control'
.submit-container.mt-3
= f.submit _('Get started!'), class: 'btn-register btn btn-block mb-0 p-2'
5 changes: 5 additions & 0 deletions changelogs/unreleased/20-add-signup-step-2.yml
@@ -0,0 +1,5 @@
---
title: Add step 2 of the experimental signup flow
merge_request: 16583
author:
type: changed
4 changes: 4 additions & 0 deletions config/routes.rb
Expand Up @@ -55,6 +55,10 @@
get '/autocomplete/project_groups' => 'autocomplete#project_groups'
end

# Sign up
get 'users/sign_up/welcome' => 'registrations#welcome'
patch 'users/sign_up/update_role' => 'registrations#update_role'

# Search
get 'search' => 'search#show'
get 'search/autocomplete' => 'search#autocomplete', as: :search_autocomplete
Expand Down
12 changes: 12 additions & 0 deletions db/migrate/20190912223232_add_role_to_users.rb
@@ -0,0 +1,12 @@
# frozen_string_literal: true

# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.

class AddRoleToUsers < ActiveRecord::Migration[5.2]
DOWNTIME = false

def change
add_column :users, :role, :smallint
end
end
1 change: 1 addition & 0 deletions db/schema.rb
Expand Up @@ -3780,6 +3780,7 @@
t.string "first_name", limit: 255
t.string "last_name", limit: 255
t.string "static_object_token", limit: 255
t.integer "role", limit: 2
t.index "lower((name)::text)", name: "index_on_users_name_lower"
t.index ["accepted_term_id"], name: "index_users_on_accepted_term_id"
t.index ["admin"], name: "index_users_on_admin"
Expand Down
21 changes: 14 additions & 7 deletions doc/administration/high_availability/README.md
Expand Up @@ -234,14 +234,21 @@ future based on additional testing and iteration.

- **Supported Users (approximate):** 25,000
- **RPS:** 500 requests per second
- **Status:** Work-in-progress
- **Related Issue:** See the [related issue](https://gitlab.com/gitlab-org/quality/performance/issues/57) for more information.
- **Known Issues:** The slow API endpoints that were discovered during testing
the 10,000 user architecture also affect the 25,000 user architecture. For
details, see the related issues list in
[this issue](https://gitlab.com/gitlab-org/gitlab-foss/issues/64335).

The Support and Quality teams are in the process of building and performance
testing an environment that will support around 25,000 users. The specifications
below are a work-in-progress representation of the work so far. The Quality team
will be certifying this environment in late 2019. The specifications may be
adjusted prior to certification based on performance testing.
The GitLab Support and Quality teams built, performance tested, and validated an
environment that supports around 25,000 users. The specifications below are a
representation of the work so far. The specifications may be adjusted in the
future based on additional testing and iteration.

NOTE: **Note:** The specifications here were performance tested against a
specific coded workload. Your exact needs may be more, depending on your
workload. Your workload is influenced by factors such as - but not limited to -
how active your users are, how much automation you use, mirroring, and
repo/change size.

| Service | Configuration | GCP type |
| ------------------------------|-------------------------|----------------|
Expand Down

0 comments on commit 4682f50

Please sign in to comment.