summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/behaviors/markdown/render_mermaid.js2
-rw-r--r--app/assets/javascripts/blob/openapi/index.js6
-rw-r--r--app/controllers/graphql_controller.rb16
-rw-r--r--app/graphql/gitlab_schema.rb3
-rw-r--r--app/graphql/types/user_interface.rb16
-rw-r--r--app/helpers/search_helper.rb24
-rw-r--r--app/models/concerns/bulk_member_access_load.rb25
-rw-r--r--app/models/concerns/diff_positionable_note.rb1
-rw-r--r--app/models/preloaders/user_max_access_level_in_groups_preloader.rb7
-rw-r--r--app/models/project.rb1
-rw-r--r--app/models/project_team.rb6
-rw-r--r--app/models/todo.rb2
-rw-r--r--app/policies/issuable_policy.rb4
-rw-r--r--app/policies/project_policy.rb13
-rw-r--r--app/services/protected_branches/base_service.rb18
-rw-r--r--app/services/protected_branches/create_service.rb2
-rw-r--r--app/services/protected_branches/update_service.rb2
-rw-r--r--app/validators/json_schema_validator.rb4
-rw-r--r--app/validators/json_schemas/position.json151
-rw-r--r--app/views/layouts/_search.html.haml5
-rw-r--r--app/views/projects/show.html.haml2
21 files changed, 272 insertions, 38 deletions
diff --git a/app/assets/javascripts/behaviors/markdown/render_mermaid.js b/app/assets/javascripts/behaviors/markdown/render_mermaid.js
index 3f878949f9b..d78c456ed5b 100644
--- a/app/assets/javascripts/behaviors/markdown/render_mermaid.js
+++ b/app/assets/javascripts/behaviors/markdown/render_mermaid.js
@@ -75,7 +75,7 @@ export function initMermaid(mermaid) {
function importMermaidModule() {
return import(/* webpackChunkName: 'mermaid' */ 'mermaid')
- .then((mermaid) => {
+ .then(({ default: mermaid }) => {
mermaidModule = initMermaid(mermaid);
})
.catch((err) => {
diff --git a/app/assets/javascripts/blob/openapi/index.js b/app/assets/javascripts/blob/openapi/index.js
index cb251274b18..b19cc19cb8c 100644
--- a/app/assets/javascripts/blob/openapi/index.js
+++ b/app/assets/javascripts/blob/openapi/index.js
@@ -1,5 +1,6 @@
import { SwaggerUIBundle } from 'swagger-ui-dist';
import createFlash from '~/flash';
+import { removeParams, updateHistory } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
export default () => {
@@ -7,9 +8,14 @@ export default () => {
Promise.all([import(/* webpackChunkName: 'openapi' */ 'swagger-ui-dist/swagger-ui.css')])
.then(() => {
+ // Temporary fix to prevent an XSS attack due to "useUnsafeMarkdown"
+ // Once we upgrade Swagger to "4.0.0", we can safely remove this as it will be deprecated
+ // Follow-up issue: https://gitlab.com/gitlab-org/gitlab/-/issues/339696
+ updateHistory({ url: removeParams(['useUnsafeMarkdown']), replace: true });
SwaggerUIBundle({
url: el.dataset.endpoint,
dom_id: '#js-openapi-viewer',
+ useUnsafeMarkdown: false,
});
})
.catch((error) => {
diff --git a/app/controllers/graphql_controller.rb b/app/controllers/graphql_controller.rb
index 515fbd7b482..8b2b3afd134 100644
--- a/app/controllers/graphql_controller.rb
+++ b/app/controllers/graphql_controller.rb
@@ -7,6 +7,9 @@ class GraphqlController < ApplicationController
# Header can be passed by tests to disable SQL query limits.
DISABLE_SQL_QUERY_LIMIT_HEADER = 'HTTP_X_GITLAB_DISABLE_SQL_QUERY_LIMIT'
+ # Max size of the query text in characters
+ MAX_QUERY_SIZE = 10_000
+
# If a user is using their session to access GraphQL, we need to have session
# storage, since the admin-mode check is session wide.
# We can't enable this for anonymous users because that would cause users using
@@ -27,6 +30,7 @@ class GraphqlController < ApplicationController
before_action :set_user_last_activity
before_action :track_vs_code_usage
before_action :disable_query_limiting
+ before_action :limit_query_size
before_action :disallow_mutations_for_get
@@ -73,6 +77,16 @@ class GraphqlController < ApplicationController
raise ::Gitlab::Graphql::Errors::ArgumentError, "Mutations are forbidden in #{request.request_method} requests"
end
+ def limit_query_size
+ total_size = if multiplex?
+ params[:_json].sum { _1[:query].size }
+ else
+ query.size
+ end
+
+ raise ::Gitlab::Graphql::Errors::ArgumentError, "Query too large" if total_size > MAX_QUERY_SIZE
+ end
+
def any_mutating_query?
if multiplex?
multiplex_queries.any? { |q| mutation?(q[:query], q[:operation_name]) }
@@ -118,7 +132,7 @@ class GraphqlController < ApplicationController
end
def query
- params[:query]
+ params.fetch(:query, '')
end
def multiplex_queries
diff --git a/app/graphql/gitlab_schema.rb b/app/graphql/gitlab_schema.rb
index 38ba1611c48..d4c9269c681 100644
--- a/app/graphql/gitlab_schema.rb
+++ b/app/graphql/gitlab_schema.rb
@@ -26,6 +26,9 @@ class GitlabSchema < GraphQL::Schema
default_max_page_size 100
+ validate_max_errors 5
+ validate_timeout 0.2.seconds
+
lazy_resolve ::Gitlab::Graphql::Lazy, :force
class << self
diff --git a/app/graphql/types/user_interface.rb b/app/graphql/types/user_interface.rb
index 8c67275eb73..7cc201b6df4 100644
--- a/app/graphql/types/user_interface.rb
+++ b/app/graphql/types/user_interface.rb
@@ -29,7 +29,10 @@ module Types
field :name,
type: GraphQL::Types::String,
null: false,
- description: 'Human-readable name of the user.'
+ resolver_method: :redacted_name,
+ description: 'Human-readable name of the user. ' \
+ 'Will return `****` if the user is a project bot and the requester does not have permission to read resource access tokens.'
+
field :state,
type: Types::UserStateEnum,
null: false,
@@ -121,5 +124,16 @@ module Types
::Types::UserType
end
end
+
+ def redacted_name
+ return object.name unless object.project_bot?
+
+ return object.name if context[:current_user]&.can?(:read_resource_access_tokens, object.projects.first)
+
+ # If the requester does not have permission to read the project bot name,
+ # the API returns an arbitrary string. UI changes will be addressed in a follow up issue:
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/346058
+ '****'
+ end
end
end
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index b8e58e3afb1..adc003cf2ef 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -201,18 +201,30 @@ module SearchHelper
if @project && @project.repository.root_ref
ref = @ref || @project.repository.root_ref
- result = [
- { category: "In this project", label: _("Files"), url: project_tree_path(@project, ref) },
- { category: "In this project", label: _("Commits"), url: project_commits_path(@project, ref) },
- { category: "In this project", label: _("Network"), url: project_network_path(@project, ref) },
- { category: "In this project", label: _("Graph"), url: project_graph_path(@project, ref) },
+ result = []
+
+ if can?(current_user, :download_code, @project)
+ result.concat([
+ { category: "In this project", label: _("Files"), url: project_tree_path(@project, ref) },
+ { category: "In this project", label: _("Commits"), url: project_commits_path(@project, ref) }
+ ])
+ end
+
+ if can?(current_user, :read_repository_graphs, @project)
+ result.concat([
+ { category: "In this project", label: _("Network"), url: project_network_path(@project, ref) },
+ { category: "In this project", label: _("Graph"), url: project_graph_path(@project, ref) }
+ ])
+ end
+
+ result.concat([
{ category: "In this project", label: _("Issues"), url: project_issues_path(@project) },
{ category: "In this project", label: _("Merge requests"), url: project_merge_requests_path(@project) },
{ category: "In this project", label: _("Milestones"), url: project_milestones_path(@project) },
{ category: "In this project", label: _("Snippets"), url: project_snippets_path(@project) },
{ category: "In this project", label: _("Members"), url: project_project_members_path(@project) },
{ category: "In this project", label: _("Wiki"), url: project_wikis_path(@project) }
- ]
+ ])
if can?(current_user, :read_feature_flag, @project)
result << { category: "In this project", label: _("Feature Flags"), url: project_feature_flags_path(@project) }
diff --git a/app/models/concerns/bulk_member_access_load.rb b/app/models/concerns/bulk_member_access_load.rb
index e252ca36629..927d6ccb28f 100644
--- a/app/models/concerns/bulk_member_access_load.rb
+++ b/app/models/concerns/bulk_member_access_load.rb
@@ -9,11 +9,15 @@ module BulkMemberAccessLoad
# Determine the maximum access level for a group of resources in bulk.
#
# Returns a Hash mapping resource ID -> maximum access level.
- def max_member_access_for_resource_ids(resource_klass, resource_ids, memoization_index = self.id, &block)
+ def max_member_access_for_resource_ids(resource_klass, resource_ids, &block)
raise 'Block is mandatory' unless block_given?
+ memoization_index = self.id
+ memoization_class = self.class
+
resource_ids = resource_ids.uniq
- access = load_access_hash(resource_klass, memoization_index)
+ memo_id = "#{memoization_class}:#{memoization_index}"
+ access = load_access_hash(resource_klass, memo_id)
# Look up only the IDs we need
resource_ids -= access.keys
@@ -33,8 +37,8 @@ module BulkMemberAccessLoad
access
end
- def merge_value_to_request_store(resource_klass, resource_id, memoization_index, value)
- max_member_access_for_resource_ids(resource_klass, [resource_id], memoization_index) do
+ def merge_value_to_request_store(resource_klass, resource_id, value)
+ max_member_access_for_resource_ids(resource_klass, [resource_id]) do
{ resource_id => value }
end
end
@@ -45,16 +49,13 @@ module BulkMemberAccessLoad
"max_member_access_for_#{klass.name.underscore.pluralize}:#{memoization_index}"
end
- def load_access_hash(resource_klass, memoization_index)
- key = max_member_access_for_resource_key(resource_klass, memoization_index)
+ def load_access_hash(resource_klass, memo_id)
+ return {} unless Gitlab::SafeRequestStore.active?
- access = {}
- if Gitlab::SafeRequestStore.active?
- Gitlab::SafeRequestStore[key] ||= {}
- access = Gitlab::SafeRequestStore[key]
- end
+ key = max_member_access_for_resource_key(resource_klass, memo_id)
+ Gitlab::SafeRequestStore[key] ||= {}
- access
+ Gitlab::SafeRequestStore[key]
end
end
end
diff --git a/app/models/concerns/diff_positionable_note.rb b/app/models/concerns/diff_positionable_note.rb
index cea3c7d119c..b13ca4bf06e 100644
--- a/app/models/concerns/diff_positionable_note.rb
+++ b/app/models/concerns/diff_positionable_note.rb
@@ -12,6 +12,7 @@ module DiffPositionableNote
serialize :change_position, Gitlab::Diff::Position # rubocop:disable Cop/ActiveRecordSerialize
validate :diff_refs_match_commit, if: :for_commit?
+ validates :position, json_schema: { filename: "position", hash_conversion: true }
end
%i(original_position position change_position).each do |meth|
diff --git a/app/models/preloaders/user_max_access_level_in_groups_preloader.rb b/app/models/preloaders/user_max_access_level_in_groups_preloader.rb
index 14f1d271572..8ef8b9763a4 100644
--- a/app/models/preloaders/user_max_access_level_in_groups_preloader.rb
+++ b/app/models/preloaders/user_max_access_level_in_groups_preloader.rb
@@ -5,8 +5,6 @@ module Preloaders
# stores the values in requests store.
# Will only be able to preload max access level for groups where the user is a direct member
class UserMaxAccessLevelInGroupsPreloader
- include BulkMemberAccessLoad
-
def initialize(groups, user)
@groups = groups
@user = user
@@ -19,8 +17,9 @@ module Preloaders
.group(:source_id)
.maximum(:access_level)
- group_memberships.each do |group_id, max_access_level|
- merge_value_to_request_store(User, @user.id, group_id, max_access_level)
+ @groups.each do |group|
+ access_level = group_memberships[group.id]
+ group.merge_value_to_request_store(User, @user.id, access_level) if access_level.present?
end
end
end
diff --git a/app/models/project.rb b/app/models/project.rb
index f68fdadf51b..b0dafeccc92 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -37,6 +37,7 @@ class Project < ApplicationRecord
include Repositories::CanHousekeepRepository
include EachBatch
include GitlabRoutingHelper
+ include BulkMemberAccessLoad
extend Gitlab::Cache::RequestCache
extend Gitlab::Utils::Override
diff --git a/app/models/project_team.rb b/app/models/project_team.rb
index 774d81156b7..b40c4366c2a 100644
--- a/app/models/project_team.rb
+++ b/app/models/project_team.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true
class ProjectTeam
- include BulkMemberAccessLoad
-
attr_accessor :project
def initialize(project)
@@ -169,7 +167,7 @@ class ProjectTeam
#
# Returns a Hash mapping user ID -> maximum access level.
def max_member_access_for_user_ids(user_ids)
- max_member_access_for_resource_ids(User, user_ids, project.id) do |user_ids|
+ project.max_member_access_for_resource_ids(User, user_ids) do |user_ids|
project.project_authorizations
.where(user: user_ids)
.group(:user_id)
@@ -178,7 +176,7 @@ class ProjectTeam
end
def write_member_access_for_user_id(user_id, project_access_level)
- merge_value_to_request_store(User, user_id, project.id, project_access_level)
+ project.merge_value_to_request_store(User, user_id, project_access_level)
end
def max_member_access(user_id)
diff --git a/app/models/todo.rb b/app/models/todo.rb
index 94a99603848..a7a34b2caad 100644
--- a/app/models/todo.rb
+++ b/app/models/todo.rb
@@ -67,7 +67,7 @@ class Todo < ApplicationRecord
scope :for_type, -> (type) { where(target_type: type) }
scope :for_target, -> (id) { where(target_id: id) }
scope :for_commit, -> (id) { where(commit_id: id) }
- scope :with_entity_associations, -> { preload(:target, :author, :note, group: :route, project: [:route, { namespace: :route }]) }
+ scope :with_entity_associations, -> { preload(:target, :author, :note, group: :route, project: [:route, { namespace: [:route, :owner] }]) }
scope :joins_issue_and_assignees, -> { left_joins(issue: :assignees) }
enum resolved_by_action: { system_done: 0, api_all_done: 1, api_done: 2, mark_all_done: 3, mark_done: 4 }, _prefix: :resolved_by
diff --git a/app/policies/issuable_policy.rb b/app/policies/issuable_policy.rb
index 39ce26526e6..ed5a0f24ed0 100644
--- a/app/policies/issuable_policy.rb
+++ b/app/policies/issuable_policy.rb
@@ -17,7 +17,9 @@ class IssuablePolicy < BasePolicy
enable :read_issue
enable :update_issue
enable :reopen_issue
- enable :read_merge_request
+ end
+
+ rule { can?(:read_merge_request) & assignee_or_author }.policy do
enable :update_merge_request
enable :reopen_merge_request
end
diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb
index b40bfbf5a79..7e4d7432f9c 100644
--- a/app/policies/project_policy.rb
+++ b/app/policies/project_policy.rb
@@ -90,6 +90,11 @@ class ProjectPolicy < BasePolicy
user.is_a?(DeployToken) && user.has_access_to?(project) && user.write_package_registry
end
+ desc "Deploy token with read access"
+ condition(:download_code_deploy_token) do
+ user.is_a?(DeployToken) && user.has_access_to?(project)
+ end
+
desc "If user is authenticated via CI job token then the target project should be in scope"
condition(:project_allowed_for_job_token) do
!@user&.from_ci_job_token? || @user.ci_job_token_scope.includes?(project)
@@ -494,6 +499,10 @@ class ProjectPolicy < BasePolicy
prevent(:download_wiki_code)
end
+ rule { download_code_deploy_token }.policy do
+ enable :download_wiki_code
+ end
+
rule { builds_disabled | repository_disabled }.policy do
prevent(*create_read_update_admin_destroy(:build))
prevent(*create_read_update_admin_destroy(:pipeline_schedule))
@@ -675,12 +684,14 @@ class ProjectPolicy < BasePolicy
rule { project_bot }.enable :project_bot_access
+ rule { can?(:read_all_resources) }.enable :read_resource_access_tokens
+
rule { can?(:admin_project) & resource_access_token_feature_available }.policy do
enable :read_resource_access_tokens
enable :destroy_resource_access_tokens
end
- rule { can?(:read_resource_access_tokens) & resource_access_token_creation_allowed }.policy do
+ rule { can?(:admin_project) & resource_access_token_feature_available & resource_access_token_creation_allowed }.policy do
enable :create_resource_access_tokens
end
diff --git a/app/services/protected_branches/base_service.rb b/app/services/protected_branches/base_service.rb
index f48e02ab4b5..df801311aaf 100644
--- a/app/services/protected_branches/base_service.rb
+++ b/app/services/protected_branches/base_service.rb
@@ -13,5 +13,23 @@ module ProtectedBranches
def after_execute(*)
# overridden in EE::ProtectedBranches module
end
+
+ def filtered_params
+ return unless params
+
+ params[:name] = sanitize_branch_name(params[:name]) if params[:name].present?
+ params
+ end
+
+ private
+
+ def sanitize_branch_name(name)
+ name = CGI.unescapeHTML(name)
+ name = Sanitize.fragment(name)
+
+ # Sanitize.fragment escapes HTML chars, so unescape again to allow names
+ # like `feature->master`
+ CGI.unescapeHTML(name)
+ end
end
end
diff --git a/app/services/protected_branches/create_service.rb b/app/services/protected_branches/create_service.rb
index dada449989a..ea494dd4426 100644
--- a/app/services/protected_branches/create_service.rb
+++ b/app/services/protected_branches/create_service.rb
@@ -21,7 +21,7 @@ module ProtectedBranches
end
def protected_branch
- @protected_branch ||= project.protected_branches.new(params)
+ @protected_branch ||= project.protected_branches.new(filtered_params)
end
end
end
diff --git a/app/services/protected_branches/update_service.rb b/app/services/protected_branches/update_service.rb
index 1e70f2d9793..40e9a286af9 100644
--- a/app/services/protected_branches/update_service.rb
+++ b/app/services/protected_branches/update_service.rb
@@ -8,7 +8,7 @@ module ProtectedBranches
old_merge_access_levels = protected_branch.merge_access_levels.map(&:clone)
old_push_access_levels = protected_branch.push_access_levels.map(&:clone)
- if protected_branch.update(params)
+ if protected_branch.update(filtered_params)
after_execute(protected_branch: protected_branch, old_merge_access_levels: old_merge_access_levels, old_push_access_levels: old_push_access_levels)
end
diff --git a/app/validators/json_schema_validator.rb b/app/validators/json_schema_validator.rb
index 68f03e8a6a3..4896c2ea2ef 100644
--- a/app/validators/json_schema_validator.rb
+++ b/app/validators/json_schema_validator.rb
@@ -24,8 +24,10 @@ class JsonSchemaValidator < ActiveModel::EachValidator
end
def validate_each(record, attribute, value)
+ value = value.to_h.stringify_keys if options[:hash_conversion] == true
+
unless valid_schema?(value)
- record.errors.add(attribute, "must be a valid json schema")
+ record.errors.add(attribute, _("must be a valid json schema"))
end
end
diff --git a/app/validators/json_schemas/position.json b/app/validators/json_schemas/position.json
new file mode 100644
index 00000000000..d2c83be7639
--- /dev/null
+++ b/app/validators/json_schemas/position.json
@@ -0,0 +1,151 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "description": "Gitlab::Diff::Position",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "base_sha": {
+ "oneOf": [
+ { "type": "null" },
+ { "type": "string", "maxLength": 40 }
+ ]
+ },
+ "start_sha": {
+ "oneOf": [
+ { "type": "null" },
+ { "type": "string", "maxLength": 40 }
+ ]
+ },
+ "head_sha": {
+ "oneOf": [
+ { "type": "null" },
+ { "type": "string", "maxLength": 40 }
+ ]
+ },
+ "file_identifier_hash": {
+ "oneOf": [
+ { "type": "null" },
+ { "type": "string", "maxLength": 40 }
+ ]
+ },
+ "old_path": {
+ "oneOf": [
+ { "type": "null" },
+ { "type": "string", "maxLength": 1000 }
+ ]
+ },
+ "new_path": {
+ "oneOf": [
+ { "type": "null" },
+ { "type": "string", "maxLength": 1000 }
+ ]
+ },
+ "position_type": {
+ "oneOf": [
+ { "type": "null" },
+ { "type": "string", "maxLength": 10 }
+ ]
+ },
+ "old_line": {
+ "oneOf": [
+ { "type": "null" },
+ { "type": "integer" }
+ ]
+ },
+ "new_line": {
+ "oneOf": [
+ { "type": "null" },
+ { "type": "integer" }
+ ]
+ },
+ "line_range": {
+ "oneOf": [
+ { "type": "null" },
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "start": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "line_code": { "type": "string", "maxLength": 100 },
+ "type": {
+ "oneOf": [
+ { "type": "null" },
+ { "type": "string", "maxLength": 100 }
+ ]
+ },
+ "old_line": {
+ "oneOf": [
+ { "type": "null" },
+ { "type": "integer" }
+ ]
+ },
+ "new_line": {
+ "oneOf": [
+ { "type": "null" },
+ { "type": "integer" }
+ ]
+ }
+ }
+ },
+ "end": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "line_code": { "type": "string", "maxLength": 100 },
+ "type": {
+ "oneOf": [
+ { "type": "null" },
+ { "type": "string", "maxLength": 100 }
+ ]
+ },
+ "old_line": {
+ "oneOf": [
+ { "type": "null" },
+ { "type": "integer" }
+ ]
+ },
+ "new_line": {
+ "oneOf": [
+ { "type": "null" },
+ { "type": "integer" }
+ ]
+ }
+ }
+ }
+ }
+ }
+ ]
+ },
+ "width": {
+ "oneOf": [
+ { "type": "null" },
+ { "type": "integer" },
+ { "type": "string", "maxLength": 10 }
+ ]
+ },
+ "height": {
+ "oneOf": [
+ { "type": "null" },
+ { "type": "integer" },
+ { "type": "string", "maxLength": 10 }
+ ]
+ },
+ "x": {
+ "oneOf": [
+ { "type": "null" },
+ { "type": "integer" },
+ { "type": "string", "maxLength": 10 }
+ ]
+ },
+ "y": {
+ "oneOf": [
+ { "type": "null" },
+ { "type": "integer" },
+ { "type": "string", "maxLength": 10 }
+ ]
+ }
+ }
+}
diff --git a/app/views/layouts/_search.html.haml b/app/views/layouts/_search.html.haml
index 2d186dfbd91..0350dc82e46 100644
--- a/app/views/layouts/_search.html.haml
+++ b/app/views/layouts/_search.html.haml
@@ -29,8 +29,9 @@
= hidden_field_tag :scope, search_context.scope
= hidden_field_tag :search_code, search_context.code_search?
+ - ref = search_context.ref if can?(current_user, :download_code, search_context.project)
= hidden_field_tag :snippets, search_context.for_snippets?
- = hidden_field_tag :repository_ref, search_context.ref
+ = hidden_field_tag :repository_ref, ref
= hidden_field_tag :nav_source, 'navbar'
-# workaround for non-JS feature specs, see spec/support/helpers/search_helpers.rb
@@ -38,4 +39,4 @@
%noscript= button_tag 'Search'
.search-autocomplete-opts.hide{ :'data-autocomplete-path' => search_autocomplete_path,
:'data-autocomplete-project-id' => search_context.project.try(:id),
- :'data-autocomplete-project-ref' => search_context.ref }
+ :'data-autocomplete-project-ref' => ref }
diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml
index e515f1e7320..1cbb061784e 100644
--- a/app/views/projects/show.html.haml
+++ b/app/views/projects/show.html.haml
@@ -1,5 +1,4 @@
- current_route_path = request.fullpath.match(%r{-/tree/[^/]+/(.+$)}).to_a[1]
-- add_page_startup_graphql_call('repository/path_last_commit', { projectPath: @project.full_path, ref: current_ref, path: current_route_path || "" })
- @content_class = "limit-container-width" unless fluid_layout
- @skip_current_level_breadcrumb = true
- add_page_specific_style 'page_bundles/project'
@@ -14,6 +13,7 @@
= render "home_panel"
- if can?(current_user, :download_code, @project) && @project.repository_languages.present?
+ - add_page_startup_graphql_call('repository/path_last_commit', { projectPath: @project.full_path, ref: current_ref, path: current_route_path || "" })
= repository_languages_bar(@project.repository_languages)
= render "archived_notice", project: @project