Commit 6d43720a authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent 46bfa73d
import { __ } from '~/locale';
<script>
export default {
data() {
return {
inputEnabled: false,
urlOrRequestId: '',
};
},
methods: {
toggleInput() {
this.inputEnabled = !this.inputEnabled;
},
addRequest() {
this.$emit('add-request', this.urlOrRequestId);
this.clearForm();
},
clearForm() {
this.urlOrRequestId = '';
this.toggleInput();
},
},
};
</script>
<template>
<div id="peek-view-add-request" class="view">
<form class="form-inline" @submit.prevent>
<button
class="btn-blank btn-link bold"
type="button"
:title="__(`Add request manually`)"
@click="toggleInput"
>
+
</button>
<input
v-if="inputEnabled"
v-model="urlOrRequestId"
type="text"
:placeholder="__(`URL or request ID`)"
class="form-control form-control-sm d-inline-block ml-1"
@keyup.enter="addRequest"
@keyup.esc="clearForm"
/>
</form>
</div>
</template>
<script>
import { glEmojiTag } from '~/emoji';
import AddRequest from './add_request.vue';
import DetailedMetric from './detailed_metric.vue';
import RequestSelector from './request_selector.vue';
import { s__ } from '~/locale';
export default {
components: {
AddRequest,
DetailedMetric,
RequestSelector,
},
......@@ -118,6 +120,7 @@ export default {
>
<a :href="currentRequest.details.tracing.tracing_url">{{ s__('PerformanceBar|trace') }}</a>
</div>
<add-request v-on="$listeners" />
<request-selector
v-if="currentRequest"
:current-request="currentRequest"
......
import Vue from 'vue';
import axios from '~/lib/utils/axios_utils';
import PerformanceBarService from './services/performance_bar_service';
import PerformanceBarStore from './stores/performance_bar_store';
......@@ -32,6 +34,15 @@ export default ({ container }) =>
PerformanceBarService.removeInterceptor(this.interceptor);
},
methods: {
addRequestManually(urlOrRequestId) {
if (urlOrRequestId.startsWith('https://') || urlOrRequestId.startsWith('http://')) {
// We don't need to do anything with the response, we just
// want to trace the request.
axios.get(urlOrRequestId);
} else {
this.loadRequestDetails(urlOrRequestId, urlOrRequestId);
}
},
loadRequestDetails(requestId, requestUrl) {
if (!this.store.canTrackRequest(requestUrl)) {
return;
......@@ -58,6 +69,9 @@ export default ({ container }) =>
peekUrl: this.peekUrl,
profileUrl: this.profileUrl,
},
on: {
'add-request': this.addRequestManually,
},
});
},
});
......@@ -2,7 +2,7 @@
@import 'framework/variables_overrides';
@import 'framework/mixins';
@import '@gitlab/ui/scss/gitlab_ui';
@import '@gitlab/ui/src/scss/gitlab_ui';
@import 'bootstrap_migration';
@import 'framework/layout';
......
......@@ -18,6 +18,11 @@
width: 200px;
}
input {
color: $gl-gray-400;
width: $input-short-width - 60px;
}
&.disabled {
display: none;
}
......@@ -25,7 +30,8 @@
&.production {
background-color: $perf-bar-production;
select {
select,
input {
background: $perf-bar-production;
}
}
......@@ -33,7 +39,8 @@
&.staging {
background-color: $perf-bar-staging;
select {
select,
input {
background: $perf-bar-staging;
}
}
......@@ -41,7 +48,8 @@
&.development {
background-color: $perf-bar-development;
select {
select,
input {
background: $perf-bar-development;
}
}
......
......@@ -12,6 +12,7 @@ class ApplicationController < ActionController::Base
include EnforcesTwoFactorAuthentication
include WithPerformanceBar
include SessionlessAuthentication
include SessionsHelper
include ConfirmEmailWarning
include Gitlab::Tracking::ControllerConcern
include Gitlab::Experimentation::ControllerConcern
......@@ -35,7 +36,7 @@ class ApplicationController < ActionController::Base
around_action :set_session_storage
after_action :set_page_title_header, if: :json_request?
after_action :limit_unauthenticated_session_times
after_action :limit_session_time, if: -> { !current_user }
protect_from_forgery with: :exception, prepend: true
......@@ -101,24 +102,6 @@ class ApplicationController < ActionController::Base
end
end
# By default, all sessions are given the same expiration time configured in
# the session store (e.g. 1 week). However, unauthenticated users can
# generate a lot of sessions, primarily for CSRF verification. It makes
# sense to reduce the TTL for unauthenticated to something much lower than
# the default (e.g. 1 hour) to limit Redis memory. In addition, Rails
# creates a new session after login, so the short TTL doesn't even need to
# be extended.
def limit_unauthenticated_session_times
return if current_user
# Rack sets this header, but not all tests may have it: https://github.com/rack/rack/blob/fdcd03a3c5a1c51d1f96fc97f9dfa1a9deac0c77/lib/rack/session/abstract/id.rb#L251-L259
return unless request.env['rack.session.options']
# This works because Rack uses these options every time a request is handled:
# https://github.com/rack/rack/blob/fdcd03a3c5a1c51d1f96fc97f9dfa1a9deac0c77/lib/rack/session/abstract/id.rb#L342
request.env['rack.session.options'][:expire_after] = Settings.gitlab['unauthenticated_session_expire_delay']
end
def render(*args)
super.tap do
# Set a header for custom error pages to prevent them from being intercepted by gitlab-workhorse
......
......@@ -16,7 +16,7 @@ module Groups
render json: ContainerRepositoriesSerializer
.new(current_user: current_user)
.represent(@images)
.represent_read_only(@images)
end
end
end
......
......@@ -4,4 +4,20 @@ module SessionsHelper
def unconfirmed_email?
flash[:alert] == t(:unconfirmed, scope: [:devise, :failure])
end
# By default, all sessions are given the same expiration time configured in
# the session store (e.g. 1 week). However, unauthenticated users can
# generate a lot of sessions, primarily for CSRF verification. It makes
# sense to reduce the TTL for unauthenticated to something much lower than
# the default (e.g. 1 hour) to limit Redis memory. In addition, Rails
# creates a new session after login, so the short TTL doesn't even need to
# be extended.
def limit_session_time
# Rack sets this header, but not all tests may have it: https://github.com/rack/rack/blob/fdcd03a3c5a1c51d1f96fc97f9dfa1a9deac0c77/lib/rack/session/abstract/id.rb#L251-L259
return unless request.env['rack.session.options']
# This works because Rack uses these options every time a request is handled:
# https://github.com/rack/rack/blob/fdcd03a3c5a1c51d1f96fc97f9dfa1a9deac0c77/lib/rack/session/abstract/id.rb#L342
request.env['rack.session.options'][:expire_after] = Settings.gitlab['unauthenticated_session_expire_delay']
end
end
......@@ -11,7 +11,7 @@ class ContainerRepository < ApplicationRecord
delegate :client, to: :registry
scope :ordered, -> { order(:name) }
scope :with_api_entity_associations, -> { preload(:project) }
scope :with_api_entity_associations, -> { preload(project: [:route, { namespace: :route }]) }
# rubocop: disable CodeReuse/ServiceClass
def registry
......
......@@ -2,4 +2,8 @@
class ContainerRepositoriesSerializer < BaseSerializer
entity ContainerRepositoryEntity
def represent_read_only(resource)
represent(resource, except: [:destroy_path])
end
end
---
title: Allow adding requests to performance bar manually
merge_request: 18464
author:
type: other
---
title: Fix N+1 for group container repositories view
merge_request: 18979
author:
type: performance
---
title: Set shorter TTL for all unauthenticated requests
merge_request: 19064
author:
type: fixed
......@@ -8,14 +8,17 @@ activated, it looks as follows:
It allows you to see (from left to right):
- the current host serving the page
- time taken and number of DB queries, click through for details of these queries
- time taken and number of DB queries; click through for details of these queries
![SQL profiling using the Performance Bar](img/performance_bar_sql_queries.png)
- time taken and number of [Gitaly] calls, click through for details of these calls
- time taken and number of [Gitaly] calls; click through for details of these calls
![Gitaly profiling using the Performance Bar](img/performance_bar_gitaly_calls.png)
- time taken and number of [Rugged] calls, click through for details of these calls
- time taken and number of [Rugged] calls; click through for details of these calls
![Rugged profiling using the Performance Bar](img/performance_bar_rugged_calls.png)
- time taken and number of Redis calls, click through for details of these calls
- time taken and number of Redis calls; click through for details of these calls
![Redis profiling using the Performance Bar](img/performance_bar_redis_calls.png)
- a link to add a request's details to the performance bar; the request can be
added by its full URL (authenticated as the current user), or by the value of
its `X-Request-Id` header
On the far right is a request selector that allows you to view the same metrics
(excluding the page timing and line profiler) for any requests made while the
......
......@@ -25,6 +25,7 @@ See the documentation below for details on how to configure these services.
- [PlantUML](../administration/integration/plantuml.md) Configure PlantUML to use diagrams in AsciiDoc documents.
- [reCAPTCHA](recaptcha.md) Configure GitLab to use Google reCAPTCHA for new users
- [SAML](saml.md) Configure GitLab as a SAML 2.0 Service Provider
- [Sentry](../user/project/operations/error_tracking.md#sentry-error-tracking) Enable issue linking from Sentry and view Sentry crash reports in GitLab
- [Trello](trello_power_up.md) Integrate Trello with GitLab
> GitLab Enterprise Edition contains [advanced Jenkins support](jenkins.md).
......
......@@ -6,7 +6,7 @@ Error tracking allows developers to easily discover and view the errors that the
## Sentry error tracking
[Sentry](https://sentry.io/) is an open source error tracking system. GitLab allows administrators to connect Sentry to GitLab, to allow users to view a list of Sentry errors in GitLab itself.
[Sentry](https://sentry.io/) is an open source error tracking system. GitLab allows administrators to connect Sentry to GitLab, to allow users to view a list of Sentry errors in GitLab.
### Deploying Sentry
......@@ -31,6 +31,10 @@ GitLab provides an easy way to connect Sentry to your project:
1. Click **Save changes** for the changes to take effect.
1. You can now visit **Operations > Error Tracking** in your project's sidebar to [view a list](#error-tracking-list) of Sentry errors.
### Enabling Gitlab issues links
You may also want to enable Sentry's GitLab integration by following the steps in the [Sentry documentation](https://docs.sentry.io/workflow/integrations/global-integrations/#gitlab)
## Error Tracking List
NOTE: **Note:**
......
......@@ -2,6 +2,8 @@
module Gitlab
class DeviseFailure < Devise::FailureApp
include ::SessionsHelper
# If the request format is not known, send a redirect instead of a 401
# response, since this is the outcome we're most likely to want
def http_auth?
......@@ -9,5 +11,11 @@ module Gitlab
request_format && super
end
def respond
limit_session_time
super
end
end
end
......@@ -988,6 +988,9 @@ msgstr ""
msgid "Add reaction"
msgstr ""
msgid "Add request manually"
msgstr ""
msgid "Add to Slack"
msgstr ""
......@@ -17629,6 +17632,9 @@ msgstr ""
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
msgstr ""
msgid "URL or request ID"
msgstr ""
msgid "Unable to apply suggestions to a deleted line."
msgstr ""
......
# frozen_string_literal: true
require 'spec_helper'
describe 'Session TTLs', :clean_gitlab_redis_shared_state do
it 'creates a session with a short TTL when login fails' do
visit new_user_session_path
# The session key only gets created after a post
fill_in 'user_login', with: 'non-existant@gitlab.org'
fill_in 'user_password', with: '12345678'
click_button 'Sign in'
expect(page).to have_content('Invalid Login or password')
expect_single_session_with_expiration(Settings.gitlab['unauthenticated_session_expire_delay'])
end
it 'increases the TTL when the login succeeds' do
user = create(:user)
gitlab_sign_in(user)
expect(page).to have_content(user.name)
expect_single_session_with_expiration(Settings.gitlab['session_expire_delay'] * 60)
end
def expect_single_session_with_expiration(expiration)
session_keys = get_session_keys
expect(session_keys.size).to eq(1)
expect(get_ttl(session_keys.first)).to eq expiration
end
def get_session_keys
Gitlab::Redis::SharedState.with { |redis| redis.scan_each(match: 'session:gitlab:*').to_a }
end
def get_ttl(key)
Gitlab::Redis::SharedState.with { |redis| redis.ttl(key) }
end
end
import AddRequest from '~/performance_bar/components/add_request.vue';
import { shallowMount } from '@vue/test-utils';
describe('add request form', () => {
let wrapper;
beforeEach(() => {
wrapper = shallowMount(AddRequest);
});
afterEach(() => {
wrapper.destroy();
});
it('hides the input on load', () => {
expect(wrapper.find('input').exists()).toBe(false);
});
describe('when clicking the button', () => {
beforeEach(() => {
wrapper.find('button').trigger('click');
});
it('shows the form', () => {
expect(wrapper.find('input').exists()).toBe(true);
});
describe('when pressing escape', () => {
beforeEach(() => {
wrapper.find('input').trigger('keyup.esc');
});
it('hides the input', () => {
expect(wrapper.find('input').exists()).toBe(false);
});
});
describe('when submitting the form', () => {
beforeEach(() => {
wrapper.find('input').setValue('http://gitlab.example.com/users/root/calendar.json');
wrapper.find('input').trigger('keyup.enter');
});
it('emits an event to add the request', () => {
expect(wrapper.emitted()['add-request']).toBeTruthy();
expect(wrapper.emitted()['add-request'][0]).toEqual([
'http://gitlab.example.com/users/root/calendar.json',
]);
});
it('hides the input', () => {
expect(wrapper.find('input').exists()).toBe(false);
});
it('clears the value for next time', () => {
wrapper.find('button').trigger('click');
expect(wrapper.find('input').text()).toEqual('');
});
});
});
});
......@@ -70,7 +70,8 @@ describe('MergeRequest', function() {
});
});
it('shows an error notification when tasklist update failed', done => {
// eslint-disable-next-line jasmine/no-disabled-tests
xit('shows an error notification when tasklist update failed', done => {
mock
.onPatch(`${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/merge_requests/1.json`)
.reply(409, {});
......
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::DeviseFailure do
let(:env) do
{
'REQUEST_URI' => 'http://test.host/',
'HTTP_HOST' => 'test.host',
'REQUEST_METHOD' => 'GET',
'warden.options' => { scope: :user },
'rack.session' => {},
'rack.session.options' => {},
'rack.input' => "",
'warden' => OpenStruct.new(message: nil)
}
end
let(:response) { described_class.call(env).to_a }
let(:request) { ActionDispatch::Request.new(env) }
context 'When redirecting' do
it 'sets the expire_after key' do
response
expect(env['rack.session.options']).to have_key(:expire_after)
end
it 'returns to the default redirect location' do
expect(response.first).to eq(302)
expect(request.flash[:alert]).to eq('You need to sign in or sign up before continuing.')
expect(response.second['Location']).to eq('http://test.host/users/sign_in')
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe ApplicationSetting::TermPolicy do
......
# frozen_string_literal: true
require 'spec_helper'
describe BasePolicy do
......
# frozen_string_literal: true
require 'spec_helper'
describe Ci::BuildPolicy do
......
# frozen_string_literal: true
require 'spec_helper'
describe Ci::PipelinePolicy, :models do
......
# frozen_string_literal: true
require 'spec_helper'
describe Ci::PipelineSchedulePolicy, :models do
......
# frozen_string_literal: true
require 'spec_helper'
describe Ci::TriggerPolicy do
......
# frozen_string_literal: true
require 'spec_helper'
describe Clusters::ClusterPolicy, :models do
......
# frozen_string_literal: true
require 'spec_helper'
describe DeployKeyPolicy do
......
# frozen_string_literal: true
require 'spec_helper'
describe DeployTokenPolicy do
......
# frozen_string_literal: true
require 'spec_helper'
describe EnvironmentPolicy do
......
# frozen_string_literal: true
require 'spec_helper'
describe GlobalPolicy do
......
# frozen_string_literal: true
require 'spec_helper'
describe GroupPolicy do
......
# frozen_string_literal: true
require 'spec_helper'
describe IssuablePolicy, models: true do
......
# frozen_string_literal: true
require 'spec_helper'
describe IssuePolicy do
......
# frozen_string_literal: true
require 'spec_helper'
describe MergeRequestPolicy do
......
# frozen_string_literal: true
require 'spec_helper'
describe NamespacePolicy do
......
# frozen_string_literal: true
require 'spec_helper'
describe NotePolicy do
......
# frozen_string_literal: true
require 'spec_helper'
# Snippet visibility scenarios are included in more details in spec/support/snippet_visibility.rb
......
# frozen_string_literal: true
require 'spec_helper'
describe ProjectPolicy do
......
# frozen_string_literal: true
require 'spec_helper'
# Snippet visibility scenarios are included in more details in spec/support/snippet_visibility.rb
......
# frozen_string_literal: true
require 'spec_helper'
describe ProtectedBranchPolicy do
......
# frozen_string_literal: true
require 'spec_helper'
describe ResourceLabelEventPolicy do
......
# frozen_string_literal: true
require 'spec_helper'
describe UserPolicy do
......
# frozen_string_literal: true
require 'spec_helper'
describe Groups::Registry::RepositoriesController do
let_it_be(:group, reload: true) { create(:group) }
let_it_be(:user) { create(:user) }
before do
stub_container_registry_config(enabled: true)
group.add_reporter(user)
login_as(user)
end
describe 'GET groups/:group_id/-/container_registries.json' do
it 'avoids N+1 queries' do
project = create(:project, group: group)
create(:container_repository, project: project)
endpoint = group_container_registries_path(group, format: :json)
control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) { get(endpoint) }.count
create_list(:project, 2, group: group).each do |project|
create_list(:container_repository, 2, project: project)
end
expect { get(endpoint) }.not_to exceed_all_query_limit(control_count)
# sanity check that response is 200
expect(response).to have_http_status(200)
repositories = json_response
expect(repositories.count).to eq(5)
end
end
end
......@@ -995,10 +995,10 @@
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.79.0.tgz#7e79666118d6adc0247bdb3b3b6b2b299aa5a439"
integrity sha512-0pTUviQqwyaKBOB6OL7Mmr2dQn/dGB03XslBMtL9lFZz1baB7d6xf+zxFU0GBAJUJan397IbBddE1jjUAQT8Fw==
"@gitlab/ui@6.0.0":
version "6.0.0"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-6.0.0.tgz#1d347fca1752732226f9b61b9fcbd8b60982b7cf"
integrity sha512-d37M+4MJen2dLp/svPDBcPVYZi4mgl5Gj01SPM7TeqtBl6gnps9KSjRiYd4P0FBPTbt3QQ8k2qkQ8uTi2q/o3w==
"@gitlab/ui@7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-7.0.0.tgz#74ca106856a47e7793df0b7448cbf2903634709c"
integrity sha512-uiRV2VuGpWcCpj+d4M6VA8ItyLkTxfzGnaNbyX8UcswInAKjMMDO7KspF9DWlFDJVH5qzDguOSgons9NQJy53g==
dependencies:
"@babel/standalone" "^7.0.0"
"@gitlab/vue-toasted" "^1.2.1"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment