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:
authorStan Hu <stanhu@gmail.com>2018-02-09 23:42:02 +0300
committerIan Baum <ibaum@gitlab.com>2018-02-10 00:51:51 +0300
commit328eb762a9eb82ae59d8e63657af21256e126419 (patch)
treef2e5bc0a93d9f2cb4852dae6e2cc97e7993f6f9d /app
parentef2698915bfac9048343bb78290269c70e7d84dd (diff)
Merge branch 'rs-pick-security' into 'master'
Pick 10.4.3 fixes into master See merge request gitlab-org/gitlab-ce!17040
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/render_mermaid.js3
-rw-r--r--app/controllers/import/base_controller.rb24
-rw-r--r--app/finders/snippets_finder.rb67
-rw-r--r--app/models/project.rb5
-rw-r--r--app/models/snippet.rb21
-rw-r--r--app/policies/project_policy.rb1
-rw-r--r--app/services/groups/nested_create_service.rb10
7 files changed, 88 insertions, 43 deletions
diff --git a/app/assets/javascripts/render_mermaid.js b/app/assets/javascripts/render_mermaid.js
index 31c7a772cf4..d4f18955bd2 100644
--- a/app/assets/javascripts/render_mermaid.js
+++ b/app/assets/javascripts/render_mermaid.js
@@ -30,6 +30,9 @@ export default function renderMermaid($els) {
$els.each((i, el) => {
const source = el.textContent;
+ // Remove any extra spans added by the backend syntax highlighting.
+ Object.assign(el, { textContent: source });
+
mermaid.init(undefined, el, (id) => {
const svg = document.getElementById(id);
diff --git a/app/controllers/import/base_controller.rb b/app/controllers/import/base_controller.rb
index 9de0297ecfd..c84fc2d305d 100644
--- a/app/controllers/import/base_controller.rb
+++ b/app/controllers/import/base_controller.rb
@@ -2,26 +2,16 @@ class Import::BaseController < ApplicationController
private
def find_or_create_namespace(names, owner)
- return current_user.namespace if names == owner
- return current_user.namespace unless current_user.can_create_group?
-
names = params[:target_namespace].presence || names
- full_path_namespace = Namespace.find_by_full_path(names)
- return full_path_namespace if full_path_namespace
+ return current_user.namespace if names == owner
+
+ group = Groups::NestedCreateService.new(current_user, group_path: names).execute
- names.split('/').inject(nil) do |parent, name|
- begin
- namespace = Group.create!(name: name,
- path: name,
- owner: current_user,
- parent: parent)
- namespace.add_owner(current_user)
+ group.errors.any? ? current_user.namespace : group
+ rescue => e
+ Gitlab::AppLogger.error(e)
- namespace
- rescue ActiveRecord::RecordNotUnique, ActiveRecord::RecordInvalid
- Namespace.where(parent: parent).find_by_path_or_name(name)
- end
- end
+ current_user.namespace
end
end
diff --git a/app/finders/snippets_finder.rb b/app/finders/snippets_finder.rb
index 4450766485f..33359fa1efb 100644
--- a/app/finders/snippets_finder.rb
+++ b/app/finders/snippets_finder.rb
@@ -1,14 +1,28 @@
+# Snippets Finder
+#
+# Used to filter Snippets collections by a set of params
+#
+# Arguments.
+#
+# current_user - The current user, nil also can be used.
+# params:
+# visibility (integer) - Individual snippet visibility: Public(20), internal(10) or private(0).
+# project (Project) - Project related.
+# author (User) - Author related.
+#
+# params are optional
class SnippetsFinder < UnionFinder
- attr_accessor :current_user, :params
+ include Gitlab::Allowable
+ attr_accessor :current_user, :params, :project
def initialize(current_user, params = {})
@current_user = current_user
@params = params
+ @project = params[:project]
end
def execute
items = init_collection
- items = by_project(items)
items = by_author(items)
items = by_visibility(items)
@@ -18,25 +32,42 @@ class SnippetsFinder < UnionFinder
private
def init_collection
- items = Snippet.all
+ if project.present?
+ authorized_snippets_from_project
+ else
+ authorized_snippets
+ end
+ end
- accessible(items)
+ def authorized_snippets_from_project
+ if can?(current_user, :read_project_snippet, project)
+ if project.team.member?(current_user)
+ project.snippets
+ else
+ project.snippets.public_to_user(current_user)
+ end
+ else
+ Snippet.none
+ end
end
- def accessible(items)
- segments = []
- segments << items.public_to_user(current_user)
- segments << authorized_to_user(items) if current_user
+ def authorized_snippets
+ Snippet.where(feature_available_projects.or(not_project_related)).public_or_visible_to_user(current_user)
+ end
- find_union(segments, Snippet.includes(:author))
+ def feature_available_projects
+ projects = Project.public_or_visible_to_user(current_user)
+ .with_feature_available_for_user(:snippets, current_user).select(:id)
+ arel_query = Arel::Nodes::SqlLiteral.new(projects.to_sql)
+ table[:project_id].in(arel_query)
end
- def authorized_to_user(items)
- items.where(
- 'author_id = :author_id
- OR project_id IN (:project_ids)',
- author_id: current_user.id,
- project_ids: current_user.authorized_projects.select(:id))
+ def not_project_related
+ table[:project_id].eq(nil)
+ end
+
+ def table
+ Snippet.arel_table
end
def by_visibility(items)
@@ -53,12 +84,6 @@ class SnippetsFinder < UnionFinder
items.where(author_id: params[:author].id)
end
- def by_project(items)
- return items unless params[:project]
-
- items.where(project_id: params[:project].id)
- end
-
def visibility_from_scope
case params[:scope].to_s
when 'are_private'
diff --git a/app/models/project.rb b/app/models/project.rb
index 0590cc1c720..3893b1818f3 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -1589,8 +1589,11 @@ class Project < ActiveRecord::Base
end
def protected_for?(ref)
- ProtectedBranch.protected?(self, ref) ||
+ if repository.branch_exists?(ref)
+ ProtectedBranch.protected?(self, ref)
+ elsif repository.tag_exists?(ref)
ProtectedTag.protected?(self, ref)
+ end
end
def deployment_variables
diff --git a/app/models/snippet.rb b/app/models/snippet.rb
index 7c8716f8c18..a58c208279e 100644
--- a/app/models/snippet.rb
+++ b/app/models/snippet.rb
@@ -74,6 +74,27 @@ class Snippet < ActiveRecord::Base
@link_reference_pattern ||= super("snippets", /(?<snippet>\d+)/)
end
+ # Returns a collection of snippets that are either public or visible to the
+ # logged in user.
+ #
+ # This method does not verify the user actually has the access to the project
+ # the snippet is in, so it should be only used on a relation that's already scoped
+ # for project access
+ def self.public_or_visible_to_user(user = nil)
+ if user
+ authorized = user
+ .project_authorizations
+ .select(1)
+ .where('project_authorizations.project_id = snippets.project_id')
+
+ levels = Gitlab::VisibilityLevel.levels_for_user(user)
+
+ where('EXISTS (?) OR snippets.visibility_level IN (?) or snippets.author_id = (?)', authorized, levels, user.id)
+ else
+ public_to_user
+ end
+ end
+
def to_reference(from = nil, full: false)
reference = "#{self.class.reference_prefix}#{id}"
diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb
index 1dd8f0a25a9..61a7bf02675 100644
--- a/app/policies/project_policy.rb
+++ b/app/policies/project_policy.rb
@@ -119,7 +119,6 @@ class ProjectPolicy < BasePolicy
enable :create_note
enable :upload_file
enable :read_cycle_analytics
- enable :read_project_snippet
end
rule { can?(:reporter_access) }.policy do
diff --git a/app/services/groups/nested_create_service.rb b/app/services/groups/nested_create_service.rb
index d6f08fc3cce..5c337a9faa5 100644
--- a/app/services/groups/nested_create_service.rb
+++ b/app/services/groups/nested_create_service.rb
@@ -11,8 +11,8 @@ module Groups
def execute
return nil unless group_path
- if group = Group.find_by_full_path(group_path)
- return group
+ if namespace = namespace_or_group(group_path)
+ return namespace
end
if group_path.include?('/') && !Group.supports_nested_groups?
@@ -40,10 +40,14 @@ module Groups
)
new_params[:visibility_level] ||= Gitlab::CurrentSettings.current_application_settings.default_group_visibility
- last_group = Group.find_by_full_path(partial_path) || Groups::CreateService.new(current_user, new_params).execute
+ last_group = namespace_or_group(partial_path) || Groups::CreateService.new(current_user, new_params).execute
end
last_group
end
+
+ def namespace_or_group(group_path)
+ Namespace.find_by_full_path(group_path)
+ end
end
end