Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-09-26 15:06:00 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2019-09-26 15:06:00 +0300
commit5707f305f4b961e24369fcdaecf0b8ce1c34bad8 (patch)
tree3b291653b83b3e6c2bffc77c54527fbe6f6373be /app
parent759cd6c2985088d187ed519f2a881c2c690b34ec (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/jobs/store/utils.js65
-rw-r--r--app/assets/stylesheets/framework/card.scss3
-rw-r--r--app/controllers/admin/sessions_controller.rb33
-rw-r--r--app/controllers/application_controller.rb5
-rw-r--r--app/controllers/concerns/enforces_admin_authentication.rb12
-rw-r--r--app/controllers/concerns/sessionless_authentication.rb10
-rw-r--r--app/controllers/health_controller.rb4
-rw-r--r--app/helpers/nav_helper.rb6
-rw-r--r--app/policies/base_policy.rb8
-rw-r--r--app/services/projects/container_repository/delete_tags_service.rb2
-rw-r--r--app/views/admin/sessions/_new_base.html.haml7
-rw-r--r--app/views/admin/sessions/_signin_box.html.haml11
-rw-r--r--app/views/admin/sessions/_tabs_normal.html.haml3
-rw-r--r--app/views/admin/sessions/new.html.haml15
-rw-r--r--app/views/layouts/nav/_dashboard.html.haml20
15 files changed, 187 insertions, 17 deletions
diff --git a/app/assets/javascripts/jobs/store/utils.js b/app/assets/javascripts/jobs/store/utils.js
index fd2af0e421b..4a7d870674b 100644
--- a/app/assets/javascripts/jobs/store/utils.js
+++ b/app/assets/javascripts/jobs/store/utils.js
@@ -24,6 +24,46 @@ export const parseHeaderLine = (line = {}, lineNumber) => ({
});
/**
+ * Finds the matching header section
+ * for the section_duration object and adds it to it
+ *
+ * {
+ * isHeader: true,
+ * line: {
+ * content: [],
+ * lineNumber: 0,
+ * section_duration: "",
+ * },
+ * lines: []
+ * }
+ *
+ * @param Array data
+ * @param Object durationLine
+ */
+export function addDurationToHeader(data, durationLine) {
+ data.forEach(el => {
+ if (el.line && el.line.section === durationLine.section) {
+ el.line.section_duration = durationLine.section_duration;
+ }
+ });
+}
+
+/**
+ * Check is the current section belongs to a collapsible section
+ *
+ * @param Array acc
+ * @param Object last
+ * @param Object section
+ *
+ * @returns Boolean
+ */
+export const isCollapsibleSection = (acc = [], last = {}, section = {}) =>
+ acc.length > 0 &&
+ last.isHeader === true &&
+ !section.section_duration &&
+ section.section === last.line.section;
+
+/**
* Parses the job log content into a structure usable by the template
*
* For collaspible lines (section_header = true):
@@ -32,28 +72,35 @@ export const parseHeaderLine = (line = {}, lineNumber) => ({
* - adds a isHeader property to handle template logic
* - adds the section_duration
* For each line:
- * - adds the index as lineNumber
+ * - adds the index as lineNumber
*
- * @param {Array} lines
- * @returns {Array}
+ * @param Array lines
+ * @param Number lineNumberStart
+ * @param Array accumulator
+ * @returns Array parsed log lines
*/
-export const logLinesParser = (lines = [], lineNumberStart) =>
+export const logLinesParser = (lines = [], lineNumberStart, accumulator = []) =>
lines.reduce((acc, line, index) => {
const lineNumber = lineNumberStart ? lineNumberStart + index : index;
const last = acc[acc.length - 1];
+ // If the object is an header, we parse it into another structure
if (line.section_header) {
acc.push(parseHeaderLine(line, lineNumber));
- } else if (acc.length && last.isHeader && !line.section_duration && line.content.length) {
+ } else if (isCollapsibleSection(acc, last, line)) {
+ // if the object belongs to a nested section, we append it to the new `lines` array of the
+ // previously formated header
last.lines.push(parseLine(line, lineNumber));
- } else if (acc.length && last.isHeader && line.section_duration) {
- last.section_duration = line.section_duration;
- } else if (line.content.length) {
+ } else if (line.section_duration) {
+ // if the line has section_duration, we look for the correct header to add it
+ addDurationToHeader(acc, line);
+ } else {
+ // otherwise it's a regular line
acc.push(parseLine(line, lineNumber));
}
return acc;
- }, []);
+ }, accumulator);
/**
* Finds the repeated offset, removes the old one
diff --git a/app/assets/stylesheets/framework/card.scss b/app/assets/stylesheets/framework/card.scss
index 1e51d28bba2..9911b926cbb 100644
--- a/app/assets/stylesheets/framework/card.scss
+++ b/app/assets/stylesheets/framework/card.scss
@@ -1,8 +1,7 @@
.card-header {
&:first-child {
// intended use case: card with only a header (for example empty related issues)
- &.border-0,
- &.border-bottom-0 {
+ &:last-child {
@include border-radius($card-inner-border-radius);
}
}
diff --git a/app/controllers/admin/sessions_controller.rb b/app/controllers/admin/sessions_controller.rb
new file mode 100644
index 00000000000..1f946e41995
--- /dev/null
+++ b/app/controllers/admin/sessions_controller.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+class Admin::SessionsController < ApplicationController
+ include InternalRedirect
+
+ before_action :user_is_admin!
+
+ def new
+ # Renders a form in which the admin can enter their password
+ end
+
+ def create
+ if current_user_mode.enable_admin_mode!(password: params[:password])
+ redirect_location = stored_location_for(:redirect) || admin_root_path
+ redirect_to safe_redirect_path(redirect_location)
+ else
+ flash.now[:alert] = _('Invalid Login or password')
+ render :new
+ end
+ end
+
+ def destroy
+ current_user_mode.disable_admin_mode!
+
+ redirect_to root_path, status: :found, notice: _('Admin mode disabled')
+ end
+
+ private
+
+ def user_is_admin!
+ render_404 unless current_user&.admin?
+ end
+end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 9a7859fc687..0d0384ba52f 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -36,6 +36,7 @@ class ApplicationController < ActionController::Base
protect_from_forgery with: :exception, prepend: true
helper_method :can?
+ helper_method :current_user_mode
helper_method :import_sources_enabled?, :github_import_enabled?,
:gitea_import_enabled?, :github_import_configured?,
:gitlab_import_enabled?, :gitlab_import_configured?,
@@ -533,6 +534,10 @@ class ApplicationController < ActionController::Base
yield
end
end
+
+ def current_user_mode
+ @current_user_mode ||= Gitlab::Auth::CurrentUserMode.new(current_user)
+ end
end
ApplicationController.prepend_if_ee('EE::ApplicationController')
diff --git a/app/controllers/concerns/enforces_admin_authentication.rb b/app/controllers/concerns/enforces_admin_authentication.rb
index 3ef92730df6..e731211f423 100644
--- a/app/controllers/concerns/enforces_admin_authentication.rb
+++ b/app/controllers/concerns/enforces_admin_authentication.rb
@@ -14,6 +14,16 @@ module EnforcesAdminAuthentication
end
def authenticate_admin!
- render_404 unless current_user.admin?
+ return render_404 unless current_user.admin?
+ return unless Feature.enabled?(:user_mode_in_session)
+
+ unless current_user_mode.admin_mode?
+ store_location_for(:redirect, request.fullpath) if storable_location?
+ redirect_to(new_admin_session_path, notice: _('Re-authentication required'))
+ end
+ end
+
+ def storable_location?
+ request.path != new_admin_session_path
end
end
diff --git a/app/controllers/concerns/sessionless_authentication.rb b/app/controllers/concerns/sessionless_authentication.rb
index ba06384a37a..f644923443b 100644
--- a/app/controllers/concerns/sessionless_authentication.rb
+++ b/app/controllers/concerns/sessionless_authentication.rb
@@ -5,6 +5,12 @@
# Controller concern to handle PAT, RSS, and static objects token authentication methods
#
module SessionlessAuthentication
+ extend ActiveSupport::Concern
+
+ included do
+ before_action :enable_admin_mode!, if: :sessionless_user?
+ end
+
# This filter handles personal access tokens, atom requests with rss tokens, and static object tokens
def authenticate_sessionless_user!(request_format)
user = Gitlab::Auth::RequestAuthenticator.new(request).find_sessionless_user(request_format)
@@ -25,4 +31,8 @@ module SessionlessAuthentication
sign_in(user, store: false, message: :sessionless_sign_in)
end
end
+
+ def enable_admin_mode!
+ current_user_mode.enable_admin_mode!(skip_password_validation: true) if Feature.enabled?(:user_mode_in_session)
+ end
end
diff --git a/app/controllers/health_controller.rb b/app/controllers/health_controller.rb
index dc9a52f8da5..c97057c08cb 100644
--- a/app/controllers/health_controller.rb
+++ b/app/controllers/health_controller.rb
@@ -20,9 +20,7 @@ class HealthController < ActionController::Base
end
def liveness
- results = CHECKS.map { |check| [check.name, check.liveness] }
-
- render_check_results(results)
+ render json: { status: 'ok' }, status: :ok
end
private
diff --git a/app/helpers/nav_helper.rb b/app/helpers/nav_helper.rb
index c6e9a20c5b2..2ce45cec878 100644
--- a/app/helpers/nav_helper.rb
+++ b/app/helpers/nav_helper.rb
@@ -86,6 +86,12 @@ module NavHelper
links << :admin_impersonation
end
+ if Feature.enabled?(:user_mode_in_session)
+ if current_user&.admin? && current_user_mode&.admin_mode?
+ links << :admin_mode
+ end
+ end
+
links
end
end
diff --git a/app/policies/base_policy.rb b/app/policies/base_policy.rb
index 78379516062..2305c55033f 100644
--- a/app/policies/base_policy.rb
+++ b/app/policies/base_policy.rb
@@ -5,7 +5,13 @@ require_dependency 'declarative_policy'
class BasePolicy < DeclarativePolicy::Base
desc "User is an instance admin"
with_options scope: :user, score: 0
- condition(:admin) { @user&.admin? }
+ condition(:admin) do
+ if Feature.enabled?(:user_mode_in_session)
+ Gitlab::Auth::CurrentUserMode.new(@user).admin_mode?
+ else
+ @user&.admin?
+ end
+ end
desc "User is blocked"
with_options scope: :user, score: 0
diff --git a/app/services/projects/container_repository/delete_tags_service.rb b/app/services/projects/container_repository/delete_tags_service.rb
index 21dc1621e5c..22656b29c58 100644
--- a/app/services/projects/container_repository/delete_tags_service.rb
+++ b/app/services/projects/container_repository/delete_tags_service.rb
@@ -32,7 +32,7 @@ module Projects
# This is a hack as the registry doesn't support deleting individual
# tags. This code effectively pushes a dummy image and assigns the tag to it.
# This way when the tag is deleted only the dummy image is affected.
- # See https://gitlab.com/gitlab-org/gitlab-ce/issues/21405 for a discussion
+ # See https://gitlab.com/gitlab-org/gitlab/issues/15737 for a discussion
def smart_delete(container_repository, tag_names)
# generates the blobs for the dummy image
dummy_manifest = container_repository.client.generate_empty_manifest(container_repository.path)
diff --git a/app/views/admin/sessions/_new_base.html.haml b/app/views/admin/sessions/_new_base.html.haml
new file mode 100644
index 00000000000..55aea0296e7
--- /dev/null
+++ b/app/views/admin/sessions/_new_base.html.haml
@@ -0,0 +1,7 @@
+= form_tag(admin_session_path, method: :post, html: { class: 'new_user gl-show-field-errors', 'aria-live': 'assertive'}) do
+ .form-group
+ = label_tag :password, _('Password'), class: 'label-bold'
+ = password_field_tag :password, nil, class: 'form-control', required: true, title: _('This field is required.'), data: { qa_selector: 'password_field' }
+
+ .submit-container.move-submit-down
+ = submit_tag _('Enter admin mode'), class: 'btn btn-success', data: { qa_selector: 'sign_in_button' }
diff --git a/app/views/admin/sessions/_signin_box.html.haml b/app/views/admin/sessions/_signin_box.html.haml
new file mode 100644
index 00000000000..69baa76060e
--- /dev/null
+++ b/app/views/admin/sessions/_signin_box.html.haml
@@ -0,0 +1,11 @@
+- if form_based_providers.any?
+
+ - if password_authentication_enabled_for_web?
+ .login-box.tab-pane{ id: 'login-pane', role: 'tabpanel' }
+ .login-body
+ = render 'admin/sessions/new_base'
+
+- elsif password_authentication_enabled_for_web?
+ .login-box.tab-pane.active{ id: 'login-pane', role: 'tabpanel' }
+ .login-body
+ = render 'admin/sessions/new_base'
diff --git a/app/views/admin/sessions/_tabs_normal.html.haml b/app/views/admin/sessions/_tabs_normal.html.haml
new file mode 100644
index 00000000000..f5dedb5ad76
--- /dev/null
+++ b/app/views/admin/sessions/_tabs_normal.html.haml
@@ -0,0 +1,3 @@
+%ul.nav-links.new-session-tabs.nav-tabs.nav{ role: 'tablist' }
+ %li.nav-item{ role: 'presentation' }
+ %a.nav-link.active{ href: '#login-pane', data: { toggle: 'tab', qa_selector: 'sign_in_tab' }, role: 'tab' }= _('Enter admin mode')
diff --git a/app/views/admin/sessions/new.html.haml b/app/views/admin/sessions/new.html.haml
new file mode 100644
index 00000000000..ee06b4a1741
--- /dev/null
+++ b/app/views/admin/sessions/new.html.haml
@@ -0,0 +1,15 @@
+- @hide_breadcrumbs = true
+- page_title _('Enter admin mode')
+
+.row.justify-content-center
+ .col-6.new-session-forms-container
+ .login-page
+ #signin-container
+ = render 'admin/sessions/tabs_normal'
+ .tab-content
+ - if password_authentication_enabled_for_web?
+ = render 'admin/sessions/signin_box'
+ - else
+ -# Show a message if none of the mechanisms above are enabled
+ .prepend-top-default.center
+ = _('No authentication methods configured.')
diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml
index 4b83239dfbd..015ba13be05 100644
--- a/app/views/layouts/nav/_dashboard.html.haml
+++ b/app/views/layouts/nav/_dashboard.html.haml
@@ -68,6 +68,15 @@
= nav_link(controller: 'admin/dashboard') do
= link_to admin_root_path, class: 'd-lg-none admin-icon qa-admin-area-link' do
= _('Admin Area')
+ - if Feature.enabled?(:user_mode_in_session)
+ - if header_link?(:admin_mode)
+ = nav_link(controller: 'admin/sessions') do
+ = link_to destroy_admin_session_path, class: 'd-lg-none lock-open-icon' do
+ = _('Leave admin mode')
+ - elsif current_user.admin?
+ = nav_link(controller: 'admin/sessions') do
+ = link_to new_admin_session_path, class: 'd-lg-none lock-icon' do
+ = _('Enter admin mode')
- if Gitlab::Sherlock.enabled?
%li
= link_to sherlock_transactions_path, class: 'd-lg-none admin-icon' do
@@ -95,6 +104,17 @@
= nav_link(controller: 'admin/dashboard', html_options: { class: "d-none d-lg-block d-xl-block"}) do
= link_to admin_root_path, class: 'admin-icon qa-admin-area-link', title: _('Admin Area'), aria: { label: _('Admin Area') }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= sprite_icon('admin', size: 18)
+
+ - if Feature.enabled?(:user_mode_in_session)
+ - if header_link?(:admin_mode)
+ = nav_link(controller: 'admin/sessions', html_options: { class: "d-none d-lg-block d-xl-block"}) do
+ = link_to destroy_admin_session_path, title: _('Leave admin mode'), aria: { label: _('Leave admin mode') }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
+ = sprite_icon('lock-open', size: 18)
+ - elsif current_user.admin?
+ = nav_link(controller: 'admin/sessions', html_options: { class: "d-none d-lg-block d-xl-block"}) do
+ = link_to new_admin_session_path, title: _('Enter admin mode'), aria: { label: _('Enter admin mode') }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
+ = sprite_icon('lock', size: 18)
+
- if Gitlab::Sherlock.enabled?
%li
= link_to sherlock_transactions_path, class: 'admin-icon d-none d-lg-block d-xl-block', title: _('Sherlock Transactions'),