diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-05-13 03:08:26 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-05-13 03:08:26 +0000 |
commit | 2fc7740f3ca1ca5e5a88f9f4136d631f7650bac7 (patch) | |
tree | 7cf264cf713a0372160954b055d5b27227e5e375 /app | |
parent | 8dc1e72e2b5cb6112d5468194580edb186de4659 (diff) | |
download | gitlab-ce-2fc7740f3ca1ca5e5a88f9f4136d631f7650bac7.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/javascripts/alert_management/components/alert_management_list.vue | 27 | ||||
-rw-r--r-- | app/assets/javascripts/static_site_editor/constants.js | 2 | ||||
-rw-r--r-- | app/assets/javascripts/static_site_editor/services/submit_content_changes.js | 9 | ||||
-rw-r--r-- | app/controllers/admin/logs_controller.rb | 24 | ||||
-rw-r--r-- | app/controllers/concerns/known_sign_in.rb | 31 | ||||
-rw-r--r-- | app/controllers/omniauth_callbacks_controller.rb | 3 | ||||
-rw-r--r-- | app/controllers/sessions_controller.rb | 2 | ||||
-rw-r--r-- | app/helpers/nav_helper.rb | 2 | ||||
-rw-r--r-- | app/mailers/emails/profile.rb | 10 | ||||
-rw-r--r-- | app/mailers/previews/notify_preview.rb | 4 | ||||
-rw-r--r-- | app/services/notification_service.rb | 8 | ||||
-rw-r--r-- | app/views/admin/logs/show.html.haml | 24 | ||||
-rw-r--r-- | app/views/admin/projects/show.html.haml | 28 | ||||
-rw-r--r-- | app/views/layouts/nav/sidebar/_admin.html.haml | 6 | ||||
-rw-r--r-- | app/views/notify/unknown_sign_in_email.html.haml | 14 | ||||
-rw-r--r-- | app/views/notify/unknown_sign_in_email.text.haml | 10 | ||||
-rw-r--r-- | app/views/search/results/_blob_data.html.haml | 2 |
17 files changed, 106 insertions, 100 deletions
diff --git a/app/assets/javascripts/alert_management/components/alert_management_list.vue b/app/assets/javascripts/alert_management/components/alert_management_list.vue index a2efa6f0e0c..b4c68767ab3 100644 --- a/app/assets/javascripts/alert_management/components/alert_management_list.vue +++ b/app/assets/javascripts/alert_management/components/alert_management_list.vue @@ -5,7 +5,6 @@ import { GlLoadingIcon, GlTable, GlAlert, - GlIcon, GlNewDropdown, GlNewDropdownItem, GlTabs, @@ -15,7 +14,7 @@ import { import { s__ } from '~/locale'; import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue'; import getAlerts from '../graphql/queries/getAlerts.query.graphql'; -import { ALERTS_STATUS, ALERTS_STATUS_TABS, ALERTS_SEVERITY_LABELS } from '../constants'; +import { ALERTS_STATUS, ALERTS_STATUS_TABS } from '../constants'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; const tdClass = 'table-col d-flex d-md-table-cell align-items-center'; @@ -31,11 +30,6 @@ export default { }, fields: [ { - key: 'severity', - label: s__('AlertManagement|Severity'), - tdClass: `${tdClass} rounded-top text-capitalize`, - }, - { key: 'startedAt', label: s__('AlertManagement|Start time'), tdClass, @@ -68,7 +62,6 @@ export default { [ALERTS_STATUS.ACKNOWLEDGED]: s__('AlertManagement|Acknowledged'), [ALERTS_STATUS.RESOLVED]: s__('AlertManagement|Resolved'), }, - severityLabels: ALERTS_SEVERITY_LABELS, statusTabs: ALERTS_STATUS_TABS, components: { GlEmptyState, @@ -79,7 +72,6 @@ export default { TimeAgo, GlNewDropdown, GlNewDropdownItem, - GlIcon, GlTabs, GlTab, GlBadge, @@ -185,21 +177,6 @@ export default { fixed stacked="md" > - <template #cell(severity)="{ item }"> - <div - class="d-inline-flex align-items-center justify-content-between" - data-testid="severityField" - > - <gl-icon - class="mr-2" - :size="12" - :name="`severity-${item.severity.toLowerCase()}`" - :class="`icon-${item.severity.toLowerCase()}`" - /> - {{ $options.severityLabels[item.severity] }} - </div> - </template> - <template #cell(startedAt)="{ item }"> <time-ago v-if="item.startedAt" :time="item.startedAt" /> </template> @@ -213,7 +190,7 @@ export default { </template> <template #cell(status)="{ item }"> - <gl-new-dropdown class="w-100" :text="item.status"> + <gl-new-dropdown :text="item.status"> <gl-new-dropdown-item v-for="(label, field) in $options.statuses" :key="field"> {{ label }} </gl-new-dropdown-item> diff --git a/app/assets/javascripts/static_site_editor/constants.js b/app/assets/javascripts/static_site_editor/constants.js index 82732ab118f..4794cf5eead 100644 --- a/app/assets/javascripts/static_site_editor/constants.js +++ b/app/assets/javascripts/static_site_editor/constants.js @@ -15,3 +15,5 @@ export const LOAD_CONTENT_ERROR = __( ); export const DEFAULT_HEADING = s__('StaticSiteEditor|Static site editor'); + +export const TRACKING_ACTION_CREATE_COMMIT = 'create_commit'; diff --git a/app/assets/javascripts/static_site_editor/services/submit_content_changes.js b/app/assets/javascripts/static_site_editor/services/submit_content_changes.js index b4e4e94d4f2..49135d2141b 100644 --- a/app/assets/javascripts/static_site_editor/services/submit_content_changes.js +++ b/app/assets/javascripts/static_site_editor/services/submit_content_changes.js @@ -1,4 +1,5 @@ import Api from '~/api'; +import Tracking from '~/tracking'; import { s__, sprintf } from '~/locale'; import { convertObjectPropsToSnakeCase } from '~/lib/utils/common_utils'; import generateBranchName from '~/static_site_editor/services/generate_branch_name'; @@ -8,6 +9,7 @@ import { SUBMIT_CHANGES_BRANCH_ERROR, SUBMIT_CHANGES_COMMIT_ERROR, SUBMIT_CHANGES_MERGE_REQUEST_ERROR, + TRACKING_ACTION_CREATE_COMMIT, } from '../constants'; const createBranch = (projectId, branch) => @@ -18,8 +20,10 @@ const createBranch = (projectId, branch) => throw new Error(SUBMIT_CHANGES_BRANCH_ERROR); }); -const commitContent = (projectId, message, branch, sourcePath, content) => - Api.commitMultiple( +const commitContent = (projectId, message, branch, sourcePath, content) => { + Tracking.event(document.body.dataset.page, TRACKING_ACTION_CREATE_COMMIT); + + return Api.commitMultiple( projectId, convertObjectPropsToSnakeCase({ branch, @@ -35,6 +39,7 @@ const commitContent = (projectId, message, branch, sourcePath, content) => ).catch(() => { throw new Error(SUBMIT_CHANGES_COMMIT_ERROR); }); +}; const createMergeRequest = (projectId, title, sourceBranch, targetBranch = DEFAULT_TARGET_BRANCH) => Api.createProjectMergeRequest( diff --git a/app/controllers/admin/logs_controller.rb b/app/controllers/admin/logs_controller.rb deleted file mode 100644 index 3ae0aef0fa4..00000000000 --- a/app/controllers/admin/logs_controller.rb +++ /dev/null @@ -1,24 +0,0 @@ -# frozen_string_literal: true - -class Admin::LogsController < Admin::ApplicationController - before_action :loggers - - def show - end - - private - - def loggers - @loggers ||= [ - Gitlab::AppJsonLogger, - Gitlab::GitLogger, - Gitlab::EnvironmentLogger, - Gitlab::SidekiqLogger, - Gitlab::RepositoryCheckLogger, - Gitlab::ProjectServiceLogger, - Gitlab::Kubernetes::Logger - ] - end -end - -Admin::LogsController.prepend_if_ee('EE::Admin::LogsController') diff --git a/app/controllers/concerns/known_sign_in.rb b/app/controllers/concerns/known_sign_in.rb new file mode 100644 index 00000000000..97883d8d08c --- /dev/null +++ b/app/controllers/concerns/known_sign_in.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module KnownSignIn + include Gitlab::Utils::StrongMemoize + + private + + def verify_known_sign_in + return unless current_user + + notify_user unless known_remote_ip? + end + + def known_remote_ip? + known_ip_addresses.include?(request.remote_ip) + end + + def sessions + strong_memoize(:session) do + ActiveSession.list(current_user).reject(&:is_impersonated) + end + end + + def known_ip_addresses + [current_user.last_sign_in_ip, sessions.map(&:ip_address)].flatten + end + + def notify_user + current_user.notification_service.unknown_sign_in(current_user, request.remote_ip) + end +end diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index 534afcbab99..4c595313cb6 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -6,6 +6,9 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController include Devise::Controllers::Rememberable include AuthHelper include InitializesCurrentUserMode + include KnownSignIn + + after_action :verify_known_sign_in protect_from_forgery except: [:kerberos, :saml, :cas3, :failure], with: :exception, prepend: true diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 8a39e5257bd..9e8075d4bcc 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -7,6 +7,7 @@ class SessionsController < Devise::SessionsController include Recaptcha::ClientHelper include Recaptcha::Verify include RendersLdapServers + include KnownSignIn skip_before_action :check_two_factor_requirement, only: [:destroy] # replaced with :require_no_authentication_without_flash @@ -27,6 +28,7 @@ class SessionsController < Devise::SessionsController before_action :frontend_tracking_data, only: [:new] after_action :log_failed_login, if: :action_new_and_failed_login? + after_action :verify_known_sign_in, only: [:create] helper_method :captcha_enabled?, :captcha_on_login_required? diff --git a/app/helpers/nav_helper.rb b/app/helpers/nav_helper.rb index d7f4a4be0bf..9ea0b9cb584 100644 --- a/app/helpers/nav_helper.rb +++ b/app/helpers/nav_helper.rb @@ -59,7 +59,7 @@ module NavHelper end def admin_monitoring_nav_links - %w(system_info background_jobs logs health_check requests_profiles) + %w(system_info background_jobs health_check requests_profiles) end def group_issues_sub_menu_items diff --git a/app/mailers/emails/profile.rb b/app/mailers/emails/profile.rb index 441439444d5..4b19149a833 100644 --- a/app/mailers/emails/profile.rb +++ b/app/mailers/emails/profile.rb @@ -44,6 +44,16 @@ module Emails mail(to: @user.notification_email, subject: subject(_("Your Personal Access Tokens will expire in %{days_to_expire} days or less") % { days_to_expire: @days_to_expire })) end end + + def unknown_sign_in_email(user, ip) + @user = user + @ip = ip + @target_url = edit_profile_password_url + + Gitlab::I18n.with_locale(@user.preferred_language) do + mail(to: @user.notification_email, subject: subject(_("Unknown sign-in from new location"))) + end + end end end diff --git a/app/mailers/previews/notify_preview.rb b/app/mailers/previews/notify_preview.rb index 38e1d9532a6..c931b5a848f 100644 --- a/app/mailers/previews/notify_preview.rb +++ b/app/mailers/previews/notify_preview.rb @@ -161,6 +161,10 @@ class NotifyPreview < ActionMailer::Preview Notify.remote_mirror_update_failed_email(remote_mirror.id, user.id).message end + def unknown_sign_in_email + Notify.unknown_sign_in_email(user, '127.0.0.1').message + end + private def project diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 91e19d190bd..0a8d8e769ec 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -66,6 +66,14 @@ class NotificationService mailer.access_token_about_to_expire_email(user).deliver_later end + # Notify a user when a previously unknown IP or device is used to + # sign in to their account + def unknown_sign_in(user, ip) + return unless user.can?(:receive_notifications) + + mailer.unknown_sign_in_email(user, ip).deliver_later + end + # When create an issue we should send an email to: # # * issue assignee if their notification level is not Disabled diff --git a/app/views/admin/logs/show.html.haml b/app/views/admin/logs/show.html.haml deleted file mode 100644 index eb93f645ea6..00000000000 --- a/app/views/admin/logs/show.html.haml +++ /dev/null @@ -1,24 +0,0 @@ -- page_title "Logs" - -%ul.nav-links.log-tabs.nav.nav-tabs - - @loggers.each do |klass| - %li.nav-item - = link_to klass.file_name, "##{klass.file_name_noext}", data: { toggle: 'tab' }, class: "#{active_when(klass == @loggers.first)} nav-link" -.row-content-block - To prevent performance issues admin logs output the last 2000 lines -.tab-content - - @loggers.each do |klass| - .tab-pane{ class: active_when(klass == @loggers.first), id: klass.file_name_noext } - .file-holder#README - .js-file-title.file-title - %i.fa.fa-file - = klass.file_name - .float-right - = link_to '#', class: 'log-bottom' do - %i.fa.fa-arrow-down - Scroll down - .file-content.logs - %ol - - klass.read_latest.each do |line| - %li - %p= line diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml index 7274099806d..8abc4c37e70 100644 --- a/app/views/admin/projects/show.html.haml +++ b/app/views/admin/projects/show.html.haml @@ -14,11 +14,9 @@ .col-md-12 .card .card-header.alert.alert-danger - Last repository check - = "(#{time_ago_with_tooltip(@project.last_repository_check_at)})" - failed. See - = link_to 'repocheck.log', admin_logs_path - for error messages. + - last_check_message = _("Last repository check (%{last_check_timestamp}) failed. See the 'repocheck.log' file for error messages.") + - last_check_message = last_check_message % { last_check_timestamp: time_ago_with_tooltip(@project.last_repository_check_at) } + = last_check_message.html_safe .row .col-md-6 .card @@ -135,24 +133,18 @@ .card.repository-check .card-header - Repository check + = _("Repository check") .card-body = form_for @project, url: repository_check_admin_project_path(@project), method: :post do |f| .form-group - if @project.last_repository_check_at.nil? - This repository has never been checked. + = _("This repository has never been checked.") + - elsif @project.last_repository_check_failed? + - failed_message = _("This repository was last checked %{last_check_timestamp}. The check %{strong_start}failed.%{strong_end} See the 'repocheck.log' file for error messages.") + - failed_message = failed_message % { last_check_timestamp: @project.last_repository_check_at.to_s(:medium), strong_start: "<strong class='cred'>", strong_end: "</strong>" } + = failed_message.html_safe - else - This repository was last checked - = @project.last_repository_check_at.to_s(:medium) + '.' - The check - - if @project.last_repository_check_failed? - = succeed '.' do - %strong.cred failed - See - = link_to 'repocheck.log', admin_logs_path - for error messages. - - else - passed. + = _("This repository was last checked %{last_check_timestamp}. The check passed.") % { last_check_timestamp: @project.last_repository_check_at.to_s(:medium) } = link_to icon('question-circle'), help_page_path('administration/repository_checks') diff --git a/app/views/layouts/nav/sidebar/_admin.html.haml b/app/views/layouts/nav/sidebar/_admin.html.haml index 3151368bb3f..28e52dc85db 100644 --- a/app/views/layouts/nav/sidebar/_admin.html.haml +++ b/app/views/layouts/nav/sidebar/_admin.html.haml @@ -56,7 +56,7 @@ = _('Monitoring') %ul.sidebar-sub-level-items{ data: { qa_selector: 'admin_sidebar_monitoring_submenu_content' } } - = nav_link(controller: %w(system_info background_jobs logs health_check requests_profiles), html_options: { class: "fly-out-top-item" } ) do + = nav_link(controller: %w(system_info background_jobs health_check requests_profiles), html_options: { class: "fly-out-top-item" } ) do = link_to admin_system_info_path do %strong.fly-out-top-item-name = _('Monitoring') @@ -69,10 +69,6 @@ = link_to admin_background_jobs_path, title: _('Background Jobs') do %span = _('Background Jobs') - = nav_link(controller: :logs) do - = link_to admin_logs_path, title: _('Logs') do - %span - = _('Logs') = nav_link(controller: :health_check) do = link_to admin_health_check_path, title: _('Health Check') do %span diff --git a/app/views/notify/unknown_sign_in_email.html.haml b/app/views/notify/unknown_sign_in_email.html.haml new file mode 100644 index 00000000000..a4123fada1b --- /dev/null +++ b/app/views/notify/unknown_sign_in_email.html.haml @@ -0,0 +1,14 @@ +%p + = _('Hi %{username}!') % { username: sanitize_name(@user.name) } +%p + = _('A sign-in to your account has been made from the following IP address: %{ip}.') % { ip: @ip } +%p + - password_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: 'https://docs.gitlab.com/ee/user/profile/#changing-your-password' } + = _('If you recently signed in and recognize the IP address, you may disregard this email.') + = _('If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}.').html_safe % { password_link_start: password_link_start, password_link_end: '</a>'.html_safe } + = _('Passwords should be unique and not used for any other sites or services.') + +- unless @user.two_factor_enabled? + %p + - mfa_link_start = '<a href="https://docs.gitlab.com/ee/user/profile/account/two_factor_authentication.html" target="_blank">'.html_safe + = _('To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method.').html_safe % { mfa_link_start: mfa_link_start, mfa_link_end: '</a>'.html_safe } diff --git a/app/views/notify/unknown_sign_in_email.text.haml b/app/views/notify/unknown_sign_in_email.text.haml new file mode 100644 index 00000000000..f3efc4c4fcd --- /dev/null +++ b/app/views/notify/unknown_sign_in_email.text.haml @@ -0,0 +1,10 @@ += _('Hi %{username}!') % { username: sanitize_name(@user.name) } + += _('A sign-in to your account has been made from the following IP address: %{ip}') % { ip: @ip } + += _('If you recently signed in and recognize the IP address, you may disregard this email.') += _('If you did not recently sign in, you should immediately change your password: %{password_link}.') % { password_link: 'https://docs.gitlab.com/ee/user/profile/#changing-your-password' } += _('Passwords should be unique and not used for any other sites or services.') + +- unless @user.two_factor_enabled? + = _('To further protect your account, consider configuring a two-factor authentication method: %{mfa_link}.') % { mfa_link: 'https://docs.gitlab.com/ee/user/profile/account/two_factor_authentication.html' } diff --git a/app/views/search/results/_blob_data.html.haml b/app/views/search/results/_blob_data.html.haml index 01e42224428..218de30d707 100644 --- a/app/views/search/results/_blob_data.html.haml +++ b/app/views/search/results/_blob_data.html.haml @@ -7,4 +7,4 @@ = search_blob_title(project, path) - if blob.data .file-content.code.term{ data: { qa_selector: 'file_text_content' } } - = render 'shared/file_highlight', blob: blob, first_line_number: blob.startline + = render 'shared/file_highlight', blob: blob, first_line_number: blob.startline, blob_link: blob_link |