Commit 9afa4a5f authored by Douwe Maan's avatar Douwe Maan

Merge branch 'ce-to-ee-2018-10-01' into 'master'

CE upstream - 2018-10-01 21:21 UTC

Closes #2702 and #2697

See merge request gitlab-org/gitlab-ee!7743
parents f367bcc6 39a4258a
import Vue from 'vue';
import sanitize from 'sanitize-html';
import issuableApp from './components/app.vue';
import '../vue_shared/vue_resource_interceptor';
document.addEventListener('DOMContentLoaded', () => {
export default function initIssueableApp() {
const initialDataEl = document.getElementById('js-issuable-app-initial-data');
const props = JSON.parse(initialDataEl.innerHTML.replace(/"/g, '"'));
const props = JSON.parse(sanitize(initialDataEl.textContent).replace(/"/g, '"'));
return new Vue({
el: document.getElementById('js-issuable-app'),
......@@ -17,4 +18,4 @@ document.addEventListener('DOMContentLoaded', () => {
});
},
});
});
}
......@@ -3,9 +3,10 @@ import Issue from '~/issue';
import ShortcutsIssuable from '~/behaviors/shortcuts/shortcuts_issuable';
import ZenMode from '~/zen_mode';
import '~/notes/index';
import '~/issue_show/index';
import initIssueableApp from '~/issue_show';
export default function () {
initIssueableApp();
new Issue(); // eslint-disable-line no-new
new ShortcutsIssuable(); // eslint-disable-line no-new
new ZenMode(); // eslint-disable-line no-new
......
<script>
import { Link } from '@gitlab-org/gitlab-ui';
import Icon from '../../icon.vue';
import { numberToHumanSize } from '../../../../lib/utils/number_utils';
export default {
components: {
'gl-link': Link,
Icon,
},
props: {
......@@ -37,7 +39,7 @@ export default {
({{ fileSizeReadable }})
</template>
</p>
<a
<gl-link
:href="path"
class="btn btn-default"
rel="nofollow"
......@@ -49,7 +51,7 @@ export default {
css-classes="float-left append-right-8"
/>
{{ __('Download') }}
</a>
</gl-link>
</div>
</div>
</template>
......@@ -18,12 +18,14 @@
*/
import { Link } from '@gitlab-org/gitlab-ui';
import userAvatarImage from './user_avatar_image.vue';
import tooltip from '../../directives/tooltip';
export default {
name: 'UserAvatarLink',
components: {
'gl-link': Link,
userAvatarImage,
},
directives: {
......@@ -83,7 +85,7 @@ export default {
</script>
<template>
<a
<gl-link
:href="linkHref"
class="user-avatar-link">
<user-avatar-image
......@@ -99,5 +101,5 @@ export default {
:title="tooltipText"
:tooltip-placement="tooltipPlacement"
>{{ username }}</span>
</a>
</gl-link>
</template>
......@@ -59,7 +59,7 @@
}
@include media-breakpoint-up(sm) {
.btn:first-of-type {
.btn:nth-child(1) {
margin-left: auto;
}
}
......
......@@ -109,6 +109,15 @@ class ApplicationController < ActionController::Base
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
if response.content_type == 'text/html' && (400..599).cover?(response.status)
response.headers['X-GitLab-Custom-Error'] = '1'
end
end
end
protected
def append_info_to_payload(payload)
......
......@@ -12,6 +12,7 @@ class EventsFinder
# Arguments:
# source - which user or project to looks for events on
# current_user - only return events for projects visible to this user
# WARNING: does not consider project feature visibility!
# params:
# action: string
# target_type: string
......
......@@ -3,6 +3,7 @@
# Get user activity feed for projects common for a user and a logged in user
#
# - current_user: The user viewing the events
# WARNING: does not consider project feature visibility!
# - user: The user for which to load the events
# - params:
# - offset: The page of events to return
......
......@@ -33,7 +33,8 @@ module BlobViewer
end
def homepage
json_data['homepage']
url = json_data['homepage']
url if Gitlab::UrlSanitizer.valid?(url)
end
def npm_url
......
......@@ -10,5 +10,9 @@ module Ci
alias_attribute :secret_value, :value
validates :key, uniqueness: { scope: :pipeline_id }
def hook_attrs
{ key: key, value: value }
end
end
end
......@@ -154,6 +154,8 @@ class Event < ActiveRecord::Base
end
end
# rubocop:disable Metrics/CyclomaticComplexity
# rubocop:disable Metrics/PerceivedComplexity
def visible_to_user?(user = nil)
if push? || commit_note?
Ability.allowed?(user, :download_code, project)
......@@ -165,12 +167,18 @@ class Event < ActiveRecord::Base
Ability.allowed?(user, :read_issue, note? ? note_target : target)
elsif merge_request? || merge_request_note?
Ability.allowed?(user, :read_merge_request, note? ? note_target : target)
elsif personal_snippet_note?
Ability.allowed?(user, :read_personal_snippet, note_target)
elsif project_snippet_note?
Ability.allowed?(user, :read_project_snippet, note_target)
elsif milestone?
Ability.allowed?(user, :read_project, project)
Ability.allowed?(user, :read_milestone, project)
else
false # No other event types are visible
end
end
# rubocop:enable Metrics/PerceivedComplexity
# rubocop:enable Metrics/CyclomaticComplexity
def project_name
if project
......@@ -312,6 +320,10 @@ class Event < ActiveRecord::Base
note? && target && target.for_snippet?
end
def personal_snippet_note?
note? && target && target.for_personal_snippet?
end
def note_target
target.noteable
end
......
......@@ -3,6 +3,16 @@
class WebHook < ActiveRecord::Base
include Sortable
attr_encrypted :token,
mode: :per_attribute_iv,
algorithm: 'aes-256-gcm',
key: Settings.attr_encrypted_db_key_base_truncated
attr_encrypted :url,
mode: :per_attribute_iv,
algorithm: 'aes-256-gcm',
key: Settings.attr_encrypted_db_key_base_truncated
has_many :web_hook_logs, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
validates :url, presence: true, public_url: { allow_localhost: lambda(&:allow_local_requests?),
......@@ -27,4 +37,38 @@ class WebHook < ActiveRecord::Base
def allow_local_requests?
false
end
# In 11.4, the web_hooks table has both `token` and `encrypted_token` fields.
# Ensure that the encrypted version always takes precedence if present.
alias_method :attr_encrypted_token, :token
def token
attr_encrypted_token.presence || read_attribute(:token)
end
# In 11.4, the web_hooks table has both `token` and `encrypted_token` fields.
# Pending a background migration to encrypt all fields, we should just clear
# the unencrypted value whenever the new value is set.
alias_method :'attr_encrypted_token=', :'token='
def token=(value)
self.attr_encrypted_token = value
write_attribute(:token, nil)
end
# In 11.4, the web_hooks table has both `url` and `encrypted_url` fields.
# Ensure that the encrypted version always takes precedence if present.
alias_method :attr_encrypted_url, :url
def url
attr_encrypted_url.presence || read_attribute(:url)
end
# In 11.4, the web_hooks table has both `url` and `encrypted_url` fields.
# Pending a background migration to encrypt all fields, we should just clear
# the unencrypted value whenever the new value is set.
alias_method :'attr_encrypted_url=', :'url='
def url=(value)
self.attr_encrypted_url = value
write_attribute(:url, nil)
end
end
......@@ -7,7 +7,6 @@ class MergeRequest < ActiveRecord::Base
include Noteable
include Referable
include Presentable
include Elastic::MergeRequestsSearch
include IgnorableColumn
include TimeTrackable
include ManualInverseAssociation
......
......@@ -14,8 +14,8 @@ module Clusters
else
check_timeout
end
rescue Kubeclient::HttpError => ke
app.make_errored!("Kubernetes error: #{ke.message}") unless app.errored?
rescue Kubeclient::HttpError
app.make_errored!("Kubernetes error") unless app.errored?
end
private
......@@ -27,7 +27,7 @@ module Clusters
end
def on_failed
app.make_errored!(installation_errors || 'Installation silently failed')
app.make_errored!('Installation failed')
ensure
remove_installation_pod
end
......
......@@ -12,10 +12,10 @@ module Clusters
ClusterWaitForAppInstallationWorker.perform_in(
ClusterWaitForAppInstallationWorker::INTERVAL, app.name, app.id)
rescue Kubeclient::HttpError => ke
app.make_errored!("Kubernetes error: #{ke.message}")
rescue StandardError => e
app.make_errored!("Can't start installation process. #{e.message}")
rescue Kubeclient::HttpError
app.make_errored!("Kubernetes error.")
rescue StandardError
app.make_errored!("Can't start installation process.")
end
end
end
......
......@@ -9,7 +9,7 @@
.project-empty-note-panel
%div{ class: [container_class, ("limit-container-width" unless fluid_layout)] }
.prepend-top-20
%h4
%h4.append-bottom-20
= _('The repository for this project is empty')
- if @project.can_current_user_push_code?
......
---
title: Set a header for custom error pages to prevent them from being intercepted
by gitlab-workhorse
merge_request: 21870
author: David Piegza
type: fixed
---
title: Fixes modal button alignment
merge_request: 22024
author: Jacopo Beschi @jacopo-beschi
type: fixed
---
title: Encrypt webhook tokens and URLs in the database
merge_request: 21645
author:
type: security
---
title: Add link component to DownloadViewer component
merge_request: 21987
author: George Tsiolis
type: other
---
title: Add link component to UserAvatarLink component
merge_request: 21986
author: George Tsiolis
type: other
---
title: Redact confidential events in the API
merge_request:
author:
type: security
---
title: Improve empty project placeholder for non-members and members without write access
merge_request: 21977
author: George Tsiolis
type: other
---
title: Enable frozen string in lib/api and lib/backup
merge_request:
author: gfyoung
type: performance
---
title: pipeline webhook event now contain pipeline variables
merge_request: 18171
author: Pierre Tardy
type: added
---
title: Set timeout for syntax highlighting
merge_request:
author:
type: security
---
title: Sanitize JSON data properly to fix XSS on Issue details page
merge_request:
author:
type: security
---
title: Fix xss vulnerability sourced from package.json
merge_request:
author:
type: security
# frozen_string_literal: true
class AddAttrEncryptedColumnsToWebHook < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def change
add_column :web_hooks, :encrypted_token, :string
add_column :web_hooks, :encrypted_token_iv, :string
add_column :web_hooks, :encrypted_url, :string
add_column :web_hooks, :encrypted_url_iv, :string
end
end
# frozen_string_literal: true
class EncryptWebHooksColumns < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
BATCH_SIZE = 10000
RANGE_SIZE = 100
MIGRATION = 'EncryptColumns'
COLUMNS = [:token, :url]
WebHook = ::Gitlab::BackgroundMigration::Models::EncryptColumns::WebHook
disable_ddl_transaction!
def up
WebHook.each_batch(of: BATCH_SIZE) do |relation, index|
delay = index * 2.minutes
relation.each_batch(of: RANGE_SIZE) do |relation|
range = relation.pluck('MIN(id)', 'MAX(id)').first
args = [WebHook, COLUMNS, *range]
BackgroundMigrationWorker.perform_in(delay, MIGRATION, args)
end
end
end
def down
# noop
end
end
......@@ -3045,6 +3045,10 @@ ActiveRecord::Schema.define(version: 20180920043317) do
t.boolean "job_events", default: false, null: false
t.boolean "confidential_note_events"
t.text "push_events_branch_filter"
t.string "encrypted_token"
t.string "encrypted_token_iv"
t.string "encrypted_url"
t.string "encrypted_url_iv"
end
add_index "web_hooks", ["project_id"], name: "index_web_hooks_on_project_id", using: :btree
......
......@@ -968,7 +968,13 @@ X-Gitlab-Event: Pipeline Hook
],
"created_at": "2016-08-12 15:23:28 UTC",
"finished_at": "2016-08-12 15:26:29 UTC",
"duration": 63
"duration": 63,
"variables": [
{
"key": "NESTOR_PROD_ENVIRONMENT",
"value": "us-west-1"
}
]
},
"user":{
"name": "Administrator",
......
# frozen_string_literal: true
module API
class AccessRequests < Grape::API
include PaginationParams
......
# frozen_string_literal: true
module API
class API < Grape::API
include APIGuard
......
# frozen_string_literal: true
# Guard API with OAuth 2.0 Access Token
require 'rack/oauth2'
......
# frozen_string_literal: true
module API
# External applications API
class Applications < Grape::API
......
# frozen_string_literal: true
module API
class Avatar < Grape::API
resource :avatar do
......
# frozen_string_literal: true
module API
class AwardEmoji < Grape::API
include PaginationParams
......
# frozen_string_literal: true
module API
class Badges < Grape::API
include PaginationParams
......
# frozen_string_literal: true
module API
class Boards < Grape::API
include BoardsResponses
......
# frozen_string_literal: true
module API
module BoardsResponses
extend ActiveSupport::Concern
......
# frozen_string_literal: true
require 'mime/types'
module API
......
# frozen_string_literal: true
module API
class BroadcastMessages < Grape::API
include PaginationParams
......
# frozen_string_literal: true
module API
class CircuitBreakers < Grape::API
before { authenticated_as_admin! }
......
# frozen_string_literal: true
require 'mime/types'
module API
......
# frozen_string_literal: true
require 'mime/types'
module API
......
# frozen_string_literal: true
module API
module CustomAttributesEndpoints
extend ActiveSupport::Concern
......
# frozen_string_literal: true
module API
class DeployKeys < Grape::API
include PaginationParams
......
# frozen_string_literal: true
module API
# Deployments RESTful API endpoints
class Deployments < Grape::API
......
# frozen_string_literal: true
module API
class Discussions < Grape::API
include PaginationParams
......
# frozen_string_literal: true
module API
module Entities
class WikiPageBasic < Grape::Entity
......
# frozen_string_literal: true
module API
# Environments RESTfull API endpoints
class Environments < Grape::API
......
# frozen_string_literal: true
module API
class Events < Grape::API
include PaginationParams
......@@ -16,12 +18,27 @@ module API
desc: 'Return events sorted in ascending and descending order'
end
RedactedEvent = OpenStruct.new(target_title: 'Confidential event').freeze
def redact_events(events)
events.map do |event|
if event.visible_to_user?(current_user)
event
else
RedactedEvent
end
end
end
# rubocop: disable CodeReuse/ActiveRecord
def present_events(events)
def present_events(events, redact: true)
events = events.reorder(created_at: params[:sort])
.with_associations
present paginate(events), with: Entities::Event
events = paginate(events)
events = redact_events(events) if redact
present events, with: Entities::Event
end
# rubocop: enable CodeReuse/ActiveRecord
end
......@@ -44,7 +61,8 @@ module API
events = EventsFinder.new(params.merge(source: current_user, current_user: current_user)).execute.preload(:author, :target)
present_events(events)
# Since we're viewing our own events, redaction is unnecessary
present_events(events, redact: false)
end
# rubocop: enable CodeReuse/ActiveRecord
end
......
# frozen_string_literal: true
module API
class Features < Grape::API
before { authenticated_as_admin! }
......
# frozen_string_literal: true
module API
class Files < Grape::API
FILE_ENDPOINT_REQUIREMENTS = API::PROJECT_ENDPOINT_REQUIREMENTS.merge(file_path: API::NO_SLASH_URL_PART_REGEX)
......
# frozen_string_literal: true
module API
class GroupBoards < Grape::API
include BoardsResponses
......
# frozen_string_literal: true
module API
class GroupMilestones < Grape::API
include MilestoneResponses
......
# frozen_string_literal: true
module API
class GroupVariables < Grape::API
include PaginationParams
......
# frozen_string_literal: true
module API
class Groups < Grape::API
include PaginationParams
......
# frozen_string_literal: true
module API
module Helpers
prepend EE::API::Helpers
......@@ -394,9 +396,10 @@ module API
# lifted from https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb#L60
trace = exception.backtrace
message = "\n#{exception.class} (#{exception.message}):\n"
message = ["\n#{exception.class} (#{exception.message}):\n"]
message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code)
message << " " << trace.join("\n ")
message = message.join
API.logger.add Logger::FATAL, message
......
# frozen_string_literal: true
module API
module Helpers
module BadgesHelpers
......
# frozen_string_literal: true
module API
module Helpers
module CommonHelpers
......
# frozen_string_literal: true
module API
module Helpers
module CustomAttributes
......
# frozen_string_literal: true
module API
module Helpers
module CustomValidators
......
# frozen_string_literal: true
module API
module Helpers
module HeadersHelpers
......
# frozen_string_literal: true
module API
module Helpers
module InternalHelpers
......
# frozen_string_literal: true
# rubocop:disable GitlabSecurity/PublicSend
module API
......
# frozen_string_literal: true
module API
module Helpers
module NotesHelpers
......
# frozen_string_literal: true
module API
module Helpers
module Pagination
......
# frozen_string_literal: true
module API
module Helpers
module ProjectSnapshotsHelpers
......
# frozen_string_literal: true
module API
module Helpers
module ProjectsHelpers
......
# frozen_string_literal: true
module API
module Helpers
module RelatedResourcesHelpers
......
# frozen_string_literal: true
module API
module Helpers
module Runner
......
# frozen_string_literal: true
module API
# Internal access API
class Internal < Grape::API
......
# frozen_string_literal: true
module API
class Issues < Grape::API
include PaginationParams
......
# frozen_string_literal: true
module API
class JobArtifacts < Grape::API
before { authenticate_non_get! }
......
# frozen_string_literal: true
module API
class Jobs < Grape::API
include PaginationParams
......
# frozen_string_literal: true
module API
# Keys API
class Keys < Grape::API
......
# frozen_string_literal: true
module API
class Labels < Grape::API
include PaginationParams
......
# frozen_string_literal: true
module API
class Lint < Grape::API
namespace :ci do
......
# frozen_string_literal: true
module API
class Markdown < Grape::API
params do
......
# frozen_string_literal: true
module API
class Members < Grape::API
include PaginationParams
......
# frozen_string_literal: true
module API
# MergeRequestDiff API
class MergeRequestDiffs < Grape::API
......
# frozen_string_literal: true
module API
class MergeRequests < Grape::API
include PaginationParams
......
# frozen_string_literal: true
module API
module MilestoneResponses
extend ActiveSupport::Concern
......
# frozen_string_literal: true
module API
class Namespaces < Grape::API
include PaginationParams
......
# frozen_string_literal: true
module API
class Notes < Grape::API
include PaginationParams
......
# frozen_string_literal: true
module API
# notification_settings API
class NotificationSettings < Grape::API
......
# frozen_string_literal: true
module API
class PagesDomains < Grape::API
include PaginationParams
......
# frozen_string_literal: true
module API
# Concern for declare pagination params.
#
......
# frozen_string_literal: true
module API
class PipelineSchedules < Grape::API
include PaginationParams
......
# frozen_string_literal: true
module API
class Pipelines < Grape::API
include PaginationParams
......
# frozen_string_literal: true
module API
class ProjectExport < Grape::API
before do
......
# frozen_string_literal: true
module API
class ProjectHooks < Grape::API
include PaginationParams
......
# frozen_string_literal: true
module API
class ProjectImport < Grape::API
include PaginationParams
......
# frozen_string_literal: true
module API
class ProjectMilestones < Grape::API
include PaginationParams
......
# frozen_string_literal: true
module API
class ProjectSnapshots < Grape::API
helpers ::API::Helpers::ProjectSnapshotsHelpers
......
# frozen_string_literal: true
module API
class ProjectSnippets < Grape::API
include PaginationParams
......
# frozen_string_literal: true
require_dependency 'declarative_policy'
module API
......
# frozen_string_literal: true
module API
module ProjectsRelationBuilder
extend ActiveSupport::Concern
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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