summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/controllers/concerns/page_limiter.rb2
-rw-r--r--app/controllers/projects/grafana_api_controller.rb2
-rw-r--r--app/controllers/uploads_controller.rb2
-rw-r--r--app/helpers/submodule_helper.rb78
-rw-r--r--app/models/active_session.rb2
-rw-r--r--app/models/hooks/web_hook.rb5
-rw-r--r--app/policies/group_policy.rb9
-rw-r--r--app/policies/project_policy.rb13
-rw-r--r--app/services/error_tracking/list_projects_service.rb16
-rw-r--r--app/services/users/update_service.rb8
-rw-r--r--app/views/devise/mailer/_confirmation_instructions_account.html.haml2
-rw-r--r--app/views/devise/mailer/_confirmation_instructions_account.text.erb2
12 files changed, 97 insertions, 44 deletions
diff --git a/app/controllers/concerns/page_limiter.rb b/app/controllers/concerns/page_limiter.rb
index 1d044a41899..97df540d31b 100644
--- a/app/controllers/concerns/page_limiter.rb
+++ b/app/controllers/concerns/page_limiter.rb
@@ -58,7 +58,7 @@ module PageLimiter
# Record the page limit being hit in Prometheus
def record_page_limit_interception
- dd = DeviceDetector.new(request.user_agent)
+ dd = Gitlab::SafeDeviceDetector.new(request.user_agent)
Gitlab::Metrics.counter(:gitlab_page_out_of_bounds,
controller: params[:controller],
diff --git a/app/controllers/projects/grafana_api_controller.rb b/app/controllers/projects/grafana_api_controller.rb
index d5099367873..9cd511f6a11 100644
--- a/app/controllers/projects/grafana_api_controller.rb
+++ b/app/controllers/projects/grafana_api_controller.rb
@@ -4,6 +4,8 @@ class Projects::GrafanaApiController < Projects::ApplicationController
include RenderServiceResults
include MetricsDashboard
+ before_action :authorize_read_grafana!, only: :proxy
+
feature_category :metrics
urgency :low
diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb
index 09419a4589d..66f715f32af 100644
--- a/app/controllers/uploads_controller.rb
+++ b/app/controllers/uploads_controller.rb
@@ -52,6 +52,8 @@ class UploadsController < ApplicationController
# access to itself when a secret is given.
# For instance, user avatars are readable by anyone,
# while temporary, user snippet uploads are not.
+ return false if !current_user && public_visibility_restricted?
+
!secret? || can?(current_user, :update_user, model)
when Appearance
true
diff --git a/app/helpers/submodule_helper.rb b/app/helpers/submodule_helper.rb
index e3e2f423da3..c38d69df8e4 100644
--- a/app/helpers/submodule_helper.rb
+++ b/app/helpers/submodule_helper.rb
@@ -17,40 +17,26 @@ module SubmoduleHelper
url = File.join(Gitlab.config.gitlab.url, repository.project.full_path)
end
- if url =~ %r{([^/:]+)/([^/]+(?:\.git)?)\Z}
- namespace = Regexp.last_match(1)
- project = Regexp.last_match(2)
- gitlab_hosts = [Gitlab.config.gitlab.url,
- Gitlab.config.gitlab_shell.ssh_path_prefix]
-
- gitlab_hosts.each do |host|
- if url.start_with?(host)
- namespace, _, project = url.sub(host, '').rpartition('/')
- break
- end
- end
-
- namespace.delete_prefix!('/')
- project.rstrip!
- project.delete_suffix!('.git')
-
- if self_url?(url, namespace, project)
- [
- url_helpers.namespace_project_path(namespace, project),
- url_helpers.namespace_project_tree_path(namespace, project, submodule_item_id),
- (url_helpers.namespace_project_compare_path(namespace, project, to: submodule_item_id, from: old_submodule_item_id) if old_submodule_item_id)
- ]
- elsif relative_self_url?(url)
- relative_self_links(url, submodule_item_id, old_submodule_item_id, repository.project)
- elsif gist_github_dot_com_url?(url)
- gist_github_com_tree_links(namespace, project, submodule_item_id)
- elsif github_dot_com_url?(url)
- github_com_tree_links(namespace, project, submodule_item_id, old_submodule_item_id)
- elsif gitlab_dot_com_url?(url)
- gitlab_com_tree_links(namespace, project, submodule_item_id, old_submodule_item_id)
- else
- [sanitize_submodule_url(url), nil, nil]
- end
+ namespace, project = extract_namespace_project(url)
+
+ if namespace.blank? || project.blank?
+ return [sanitize_submodule_url(url), nil, nil]
+ end
+
+ if self_url?(url, namespace, project)
+ [
+ url_helpers.namespace_project_path(namespace, project),
+ url_helpers.namespace_project_tree_path(namespace, project, submodule_item_id),
+ (url_helpers.namespace_project_compare_path(namespace, project, to: submodule_item_id, from: old_submodule_item_id) if old_submodule_item_id)
+ ]
+ elsif relative_self_url?(url)
+ relative_self_links(url, submodule_item_id, old_submodule_item_id, repository.project)
+ elsif gist_github_dot_com_url?(url)
+ gist_github_com_tree_links(namespace, project, submodule_item_id)
+ elsif github_dot_com_url?(url)
+ github_com_tree_links(namespace, project, submodule_item_id, old_submodule_item_id)
+ elsif gitlab_dot_com_url?(url)
+ gitlab_com_tree_links(namespace, project, submodule_item_id, old_submodule_item_id)
else
[sanitize_submodule_url(url), nil, nil]
end
@@ -58,6 +44,30 @@ module SubmoduleHelper
protected
+ def extract_namespace_project(url)
+ namespace_fragment, _, project = url.rpartition('/')
+ namespace = namespace_fragment.rpartition(%r{[:/]}).last
+
+ return [nil, nil] unless project.present? && namespace.present?
+
+ gitlab_hosts = [Gitlab.config.gitlab.url,
+ Gitlab.config.gitlab_shell.ssh_path_prefix]
+
+ matching_host = gitlab_hosts.find do |host|
+ url.start_with?(host)
+ end
+
+ if matching_host
+ namespace, _, project = url.delete_prefix(matching_host).rpartition('/')
+ end
+
+ namespace.delete_prefix!('/')
+ project.rstrip!
+ project.delete_suffix!('.git')
+
+ [namespace, project]
+ end
+
def gist_github_dot_com_url?(url)
url =~ %r{gist\.github\.com[/:][^/]+/[^/]+\Z}
end
diff --git a/app/models/active_session.rb b/app/models/active_session.rb
index b16c4a2b353..2d1dec1977d 100644
--- a/app/models/active_session.rb
+++ b/app/models/active_session.rb
@@ -67,7 +67,7 @@ class ActiveSession
def self.set(user, request)
Gitlab::Redis::Sessions.with do |redis|
session_private_id = request.session.id.private_id
- client = DeviceDetector.new(request.user_agent)
+ client = Gitlab::SafeDeviceDetector.new(request.user_agent)
timestamp = Time.current
expiry = Settings.gitlab['session_expire_delay'] * 60
diff --git a/app/models/hooks/web_hook.rb b/app/models/hooks/web_hook.rb
index 189291a38ec..49418cda3ac 100644
--- a/app/models/hooks/web_hook.rb
+++ b/app/models/hooks/web_hook.rb
@@ -41,6 +41,7 @@ class WebHook < ApplicationRecord
after_initialize :initialize_url_variables
before_validation :reset_token
+ before_validation :reset_url_variables, unless: ->(hook) { hook.is_a?(ServiceHook) }
before_validation :set_branch_filter_nil, if: :branch_filter_strategy_all_branches?
validates :push_events_branch_filter, untrusted_regexp: true, if: :branch_filter_strategy_regex?
validates :push_events_branch_filter, "web_hooks/wildcard_branch_filter": true, if: :branch_filter_strategy_wildcard?
@@ -213,6 +214,10 @@ class WebHook < ApplicationRecord
self.token = nil if url_changed? && !encrypted_token_changed?
end
+ def reset_url_variables
+ self.url_variables = {} if url_changed? && !encrypted_url_variables_changed?
+ end
+
def next_failure_count
recent_failures.succ.clamp(1, MAX_FAILURES)
end
diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb
index 858c145de3f..8eea995529c 100644
--- a/app/policies/group_policy.rb
+++ b/app/policies/group_policy.rb
@@ -273,6 +273,9 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
rule { can?(:admin_group) & resource_access_token_feature_available }.policy do
enable :read_resource_access_tokens
enable :destroy_resource_access_tokens
+ end
+
+ rule { can?(:admin_group) & resource_access_token_creation_allowed }.policy do
enable :admin_setting_to_allow_project_access_token_creation
end
@@ -338,12 +341,16 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
true
end
+ def resource_access_token_create_feature_available?
+ true
+ end
+
def can_read_group_member?
!(@subject.private? && access_level == GroupMember::NO_ACCESS)
end
def resource_access_token_creation_allowed?
- resource_access_token_feature_available? && group.root_ancestor.namespace_settings.resource_access_token_creation_allowed?
+ resource_access_token_create_feature_available? && group.root_ancestor.namespace_settings.resource_access_token_creation_allowed?
end
def valid_dependency_proxy_deploy_token
diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb
index 7f67e80e432..fd3dbb54d57 100644
--- a/app/policies/project_policy.rb
+++ b/app/policies/project_policy.rb
@@ -157,7 +157,9 @@ class ProjectPolicy < BasePolicy
condition(:service_desk_enabled) { @subject.service_desk_enabled? }
with_scope :subject
- condition(:resource_access_token_feature_available) { resource_access_token_feature_available? }
+ condition(:resource_access_token_feature_available) do
+ resource_access_token_feature_available?
+ end
condition(:resource_access_token_creation_allowed) { resource_access_token_creation_allowed? }
# We aren't checking `:read_issue` or `:read_merge_request` in this case
@@ -308,6 +310,8 @@ class ProjectPolicy < BasePolicy
rule { guest & can?(:download_code) }.enable :build_download_code
rule { guest & can?(:read_container_image) }.enable :build_read_container_image
+ rule { guest & ~public_project }.enable :read_grafana
+
rule { can?(:reporter_access) }.policy do
enable :admin_issue_board
enable :download_code
@@ -340,6 +344,7 @@ class ProjectPolicy < BasePolicy
enable :read_package
enable :read_product_analytics
enable :read_ci_cd_analytics
+ enable :read_grafana
end
# We define `:public_user_access` separately because there are cases in gitlab-ee
@@ -919,12 +924,16 @@ class ProjectPolicy < BasePolicy
true
end
+ def resource_access_token_create_feature_available?
+ true
+ end
+
def resource_access_token_creation_allowed?
group = project.group
return true unless group # always enable for projects in personal namespaces
- resource_access_token_feature_available? && group.root_ancestor.namespace_settings.resource_access_token_creation_allowed?
+ resource_access_token_create_feature_available? && group.root_ancestor.namespace_settings.resource_access_token_creation_allowed?
end
def project
diff --git a/app/services/error_tracking/list_projects_service.rb b/app/services/error_tracking/list_projects_service.rb
index 2f23d47029c..d52306ef805 100644
--- a/app/services/error_tracking/list_projects_service.rb
+++ b/app/services/error_tracking/list_projects_service.rb
@@ -2,6 +2,8 @@
module ErrorTracking
class ListProjectsService < ErrorTracking::BaseService
+ MASKED_TOKEN_REGEX = /\A\*+\z/.freeze
+
private
def perform
@@ -20,23 +22,31 @@ module ErrorTracking
def project_error_tracking_setting
(super || project.build_error_tracking_setting).tap do |setting|
+ url_changed = !setting.api_url&.start_with?(params[:api_host])
+
setting.api_url = ErrorTracking::ProjectErrorTrackingSetting.build_api_url_from(
api_host: params[:api_host],
organization_slug: 'org',
project_slug: 'proj'
)
- setting.token = token(setting)
+ setting.token = token(setting, url_changed)
setting.enabled = true
end
end
strong_memoize_attr :project_error_tracking_setting
- def token(setting)
+ def token(setting, url_changed)
+ return if url_changed && masked_token?
+
# Use param token if not masked, otherwise use database token
- return params[:token] unless /\A\*+\z/.match?(params[:token])
+ return params[:token] unless masked_token?
setting.token
end
+
+ def masked_token?
+ MASKED_TOKEN_REGEX.match?(params[:token])
+ end
end
end
diff --git a/app/services/users/update_service.rb b/app/services/users/update_service.rb
index cb2711b6fee..96018db5974 100644
--- a/app/services/users/update_service.rb
+++ b/app/services/users/update_service.rb
@@ -31,6 +31,7 @@ module Users
assign_identity
build_canonical_email
+ reset_unconfirmed_email
if @user.save(validate: validate) && update_status
notify_success(user_exists)
@@ -64,6 +65,13 @@ module Users
Users::UpdateCanonicalEmailService.new(user: @user).execute
end
+ def reset_unconfirmed_email
+ return unless @user.persisted?
+ return unless @user.email_changed?
+
+ @user.update_column(:unconfirmed_email, nil)
+ end
+
def update_status
return true unless @status_params
diff --git a/app/views/devise/mailer/_confirmation_instructions_account.html.haml b/app/views/devise/mailer/_confirmation_instructions_account.html.haml
index 9d469ff6e7b..c1655818770 100644
--- a/app/views/devise/mailer/_confirmation_instructions_account.html.haml
+++ b/app/views/devise/mailer/_confirmation_instructions_account.html.haml
@@ -1,7 +1,7 @@
- confirmation_link = confirmation_url(@resource, confirmation_token: @token)
- if @resource.unconfirmed_email.present? || !@resource.created_recently?
#content
- = email_default_heading(@resource.unconfirmed_email || @resource.email)
+ = email_default_heading(@email)
%p= _('Click the link below to confirm your email address.')
#cta
= link_to _('Confirm your email address'), confirmation_link
diff --git a/app/views/devise/mailer/_confirmation_instructions_account.text.erb b/app/views/devise/mailer/_confirmation_instructions_account.text.erb
index e6da78e3a3d..7e4f38885f6 100644
--- a/app/views/devise/mailer/_confirmation_instructions_account.text.erb
+++ b/app/views/devise/mailer/_confirmation_instructions_account.text.erb
@@ -1,5 +1,5 @@
<% if @resource.unconfirmed_email.present? || !@resource.created_recently? %>
-<%= @resource.unconfirmed_email || @resource.email %>,
+<%= @email %>,
<%= _('Use the link below to confirm your email address.') %>
<% else %>
<% if Gitlab.com? %>