Commit 684e9d1b authored by Valery Sizov's avatar Valery Sizov

Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ee into new_ce_upstream

parents 5e127fdb 2a8a78f7
......@@ -3,9 +3,12 @@ Please view this file on the master branch, on stable branches it's out of date.
v 8.9.0 (unreleased)
v 8.8.3
- Gracefully handle malformed DNs in LDAP group sync
- Make it clear the license overusage is visible only to admins
- Reduce load on DB for license upgrade check
- Add standard web hook headers to Jenkins CI post. !374
- Gracefully handle malformed DNs in LDAP group sync. !392
- Reduce load on DB for license upgrade check. !421
- Make it clear the license overusage message is visible only to admins. !423
- Fix Git hook validations for fast-forward merges. !427
- [Elastic] In search results, only show notes on confidential issues that the user has access to.
v 8.8.2
- Fix repository mirror updates for new imports stuck in started
......
......@@ -38,7 +38,12 @@ module Elastic
after_commit on: :update do
if Gitlab.config.elasticsearch.enabled && self.searchable?
ElasticIndexerWorker.perform_async(:update, self.class.to_s, self.id)
ElasticIndexerWorker.perform_async(
:update,
self.class.to_s,
self.id,
changed_fields: self.previous_changes.keys
)
end
end
......
......@@ -12,6 +12,12 @@ module Elastic
indexes :project_id, type: :integer
indexes :created_at, type: :date
indexes :issue do
indexes :assignee_id, type: :integer
indexes :author_id, type: :integer
indexes :confidential, type: :boolean
end
indexes :updated_at_sort, type: :string, index: 'not_analyzed'
end
......@@ -24,27 +30,36 @@ module Elastic
data[attr.to_s] = self.send(attr)
end
if noteable.is_a?(Issue)
data['issue'] = {
assignee_id: noteable.assignee_id,
author_id: noteable.author_id,
confidential: noteable.confidential
}
end
data['updated_at_sort'] = updated_at
data
end
def self.elastic_search(query, options: {})
options[:in] = ["note"]
options[:in] = ['note']
query_hash = {
query: {
bool: {
must: { match: { note: query } },
must: [{ match: { note: query } }],
},
}
}
if query.blank?
query_hash[:query][:bool][:must] = { match_all: {} }
query_hash[:query][:bool][:must] = [{ match_all: {} }]
query_hash[:track_scores] = true
end
query_hash = project_ids_filter(query_hash, options[:project_ids])
query_hash = confidentiality_filter(query_hash, options[:current_user])
query_hash[:sort] = [
{ updated_at_sort: { order: :desc, mode: :min } },
......@@ -55,6 +70,40 @@ module Elastic
self.__elasticsearch__.search(query_hash)
end
def self.confidentiality_filter(query_hash, current_user)
return query_hash if current_user && current_user.admin?
filter = {
bool: {
should: [
{ bool: { must_not: [{ exists: { field: :issue } }] } },
{ term: { "issue.confidential" => false } }
]
}
}
if current_user
filter[:bool][:should] << {
bool: {
must: [
{ term: { "issue.confidential" => true } },
{ bool: {
should: [
{ term: { "issue.author_id" => current_user.id } },
{ term: { "issue.assignee_id" => current_user.id } },
{ terms: { "issue.project_id" => current_user.authorized_projects.pluck(:id) } }
]
}
}
]
}
}
end
query_hash[:query][:bool][:must] << filter
query_hash
end
end
end
end
......@@ -3,6 +3,8 @@ class ElasticIndexerWorker
sidekiq_options queue: :elasticsearch
ISSUE_TRACKED_FIELDS = %w(assignee_id author_id confidential)
Client = Elasticsearch::Client.new(host: Gitlab.config.elasticsearch.host,
port: Gitlab.config.elasticsearch.port)
......@@ -14,6 +16,8 @@ class ElasticIndexerWorker
record = klass.find(record_id)
record.__elasticsearch__.client = Client
record.__elasticsearch__.__send__ "#{operation}_document"
update_issue_notes(record, options["changed_fields"]) if klass == Issue
when /delete/
Client.delete index: klass.index_name, type: klass.document_type, id: record_id
......@@ -23,6 +27,12 @@ class ElasticIndexerWorker
true # Less work to do!
end
def update_issue_notes(record, changed_fields)
if changed_fields && (changed_fields & ISSUE_TRACKED_FIELDS).any?
Note.import query: -> { where(noteable: record) }
end
end
def clear_project_indexes(record_id)
# Remove repository index
Client.delete_by_query({
......
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class MakeRemoteMirrorsDisabledByDefault < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
# When using the methods "add_concurrent_index" or "add_column_with_default"
# you must disable the use of transactions as these methods can not run in an
# existing transaction. When using "add_concurrent_index" make sure that this
# method is the _only_ method called in the migration, any other changes
# should go in a separate migration. This ensures that upon failure _only_ the
# index creation fails and can be retried or reverted easily.
#
# To disable transactions uncomment the following line and remove these
# comments:
# disable_ddl_transaction!
def up
change_column :remote_mirrors, :enabled, :boolean, default: false
end
def down
change_column :remote_mirrors, :enabled, :boolean, default: true
end
end
......@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20160530150109) do
ActiveRecord::Schema.define(version: 20160601102211) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
......@@ -44,7 +44,7 @@ ActiveRecord::Schema.define(version: 20160530150109) do
t.datetime "created_at"
t.datetime "updated_at"
t.string "home_page_url"
t.integer "default_branch_protection", default: 2
t.integer "default_branch_protection", default: 2
t.text "help_text"
t.text "restricted_visibility_levels"
t.boolean "version_check_enabled", default: true
......@@ -61,15 +61,7 @@ ActiveRecord::Schema.define(version: 20160530150109) do
t.boolean "shared_runners_enabled", default: true, null: false
t.integer "max_artifacts_size", default: 100, null: false
t.string "runners_registration_token"
t.integer "max_pages_size", default: 100, null: false
t.boolean "require_two_factor_authentication", default: false
t.integer "two_factor_grace_period", default: 48
t.boolean "metrics_enabled", default: false
t.string "metrics_host", default: "localhost"
t.integer "metrics_pool_size", default: 16
t.integer "metrics_timeout", default: 10
t.integer "metrics_method_call_threshold", default: 10
t.boolean "recaptcha_enabled", default: false
t.integer "max_pages_size", default: 100, null: false
t.boolean "require_two_factor_authentication", default: false
t.integer "two_factor_grace_period", default: 48
t.boolean "metrics_enabled", default: false
......@@ -94,6 +86,10 @@ ActiveRecord::Schema.define(version: 20160530150109) do
t.text "disabled_oauth_sign_in_sources"
t.string "health_check_access_token"
t.boolean "send_user_confirmation_email", default: false
t.boolean "es_indexing", default: false, null: false
t.boolean "es_search", default: false, null: false
t.string "es_host", default: "localhost"
t.string "es_port", default: "9200"
t.integer "container_registry_token_expire_delay", default: 5
end
......@@ -821,6 +817,18 @@ ActiveRecord::Schema.define(version: 20160530150109) do
add_index "pages_domains", ["domain"], name: "index_pages_domains_on_domain", unique: true, using: :btree
create_table "path_locks", force: :cascade do |t|
t.string "path", null: false
t.integer "project_id"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "path_locks", ["path"], name: "index_path_locks_on_path", using: :btree
add_index "path_locks", ["project_id"], name: "index_path_locks_on_project_id", using: :btree
add_index "path_locks", ["user_id"], name: "index_path_locks_on_user_id", using: :btree
create_table "project_group_links", force: :cascade do |t|
t.integer "project_id", null: false
t.integer "group_id", null: false
......@@ -845,7 +853,6 @@ ActiveRecord::Schema.define(version: 20160530150109) do
t.datetime "updated_at"
t.integer "creator_id"
t.boolean "issues_enabled", default: true, null: false
t.boolean "wall_enabled", default: true, null: false
t.boolean "merge_requests_enabled", default: true, null: false
t.boolean "wiki_enabled", default: true, null: false
t.integer "namespace_id"
......@@ -884,7 +891,6 @@ ActiveRecord::Schema.define(version: 20160530150109) do
t.boolean "mirror_trigger_builds", default: false, null: false
t.boolean "pending_delete", default: false
t.boolean "public_builds", default: true, null: false
t.string "main_language"
t.integer "pushes_since_gc", default: 0
t.boolean "last_repository_check_failed"
t.datetime "last_repository_check_at"
......@@ -932,7 +938,7 @@ ActiveRecord::Schema.define(version: 20160530150109) do
create_table "remote_mirrors", force: :cascade do |t|
t.integer "project_id"
t.string "url"
t.boolean "enabled", default: true
t.boolean "enabled", default: false
t.string "update_status"
t.datetime "last_update_at"
t.datetime "last_successful_update_at"
......@@ -940,8 +946,8 @@ ActiveRecord::Schema.define(version: 20160530150109) do
t.text "encrypted_credentials"
t.string "encrypted_credentials_iv"
t.string "encrypted_credentials_salt"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "remote_mirrors", ["project_id"], name: "index_remote_mirrors_on_project_id", using: :btree
......@@ -1174,7 +1180,6 @@ ActiveRecord::Schema.define(version: 20160530150109) do
t.boolean "note_events", default: false, null: false
t.boolean "enable_ssl_verification", default: true
t.boolean "build_events", default: false, null: false
t.string "token"
t.boolean "wiki_page_events", default: false, null: false
t.string "token"
end
......@@ -1182,5 +1187,7 @@ ActiveRecord::Schema.define(version: 20160530150109) do
add_index "web_hooks", ["created_at", "id"], name: "index_web_hooks_on_created_at_and_id", using: :btree
add_index "web_hooks", ["project_id"], name: "index_web_hooks_on_project_id", using: :btree
add_foreign_key "path_locks", "projects"
add_foreign_key "path_locks", "users"
add_foreign_key "remote_mirrors", "projects"
end
......@@ -86,7 +86,8 @@ module Gitlab
def notes
opt = {
project_ids: limit_project_ids
project_ids: limit_project_ids,
current_user: @current_user
}
Note.elastic_search(query, options: opt)
......
......@@ -48,4 +48,33 @@ describe "Note", elastic: true do
create :note, :system, project: project
create :note, :award, project: project
end
context 'notes to confidential issues' do
it "does not find note" do
issue = create :issue, :confidential
create :note, note: 'bla-bla term', project: issue.project, noteable: issue
create :note, project: issue.project, noteable: issue
Note.__elasticsearch__.refresh_index!
options = { project_ids: [issue.project.id] }
expect(Note.elastic_search('term', options: options).total_count).to eq(0)
end
it "finds note when user is authorized to see it" do
user = create :user
issue = create :issue, :confidential, author: user
create :note, note: 'bla-bla term', project: issue.project, noteable: issue
create :note, project: issue.project, noteable: issue
Note.__elasticsearch__.refresh_index!
options = { project_ids: [issue.project.id], current_user: user }
expect(Note.elastic_search('term', options: options).total_count).to eq(1)
end
end
end
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