summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-10-12 18:08:31 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-10-12 18:08:31 +0000
commit884a65481f9e5365329f4ba371ac5b813c45a2f9 (patch)
treecc4030d36a739eaf91543d270db9a33093f51446 /app
parentb17f0b91a66f2101a54dd1efed0c4973f04b1daf (diff)
downloadgitlab-ce-884a65481f9e5365329f4ba371ac5b813c45a2f9.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table_row.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/members/action_buttons/leave_button.vue40
-rw-r--r--app/assets/javascripts/vue_shared/components/members/action_buttons/user_action_buttons.vue7
-rw-r--r--app/assets/javascripts/vue_shared/components/members/constants.js2
-rw-r--r--app/assets/javascripts/vue_shared/components/members/modals/leave_modal.vue70
-rw-r--r--app/controllers/registrations_controller.rb30
-rw-r--r--app/finders/alert_management/alerts_finder.rb8
-rw-r--r--app/finders/releases_finder.rb10
-rw-r--r--app/graphql/resolvers/alert_management/alert_resolver.rb4
-rw-r--r--app/graphql/resolvers/alert_management/alert_status_counts_resolver.rb4
-rw-r--r--app/models/alert_management/alert.rb1
-rw-r--r--app/models/issue.rb1
-rw-r--r--app/models/issue_assignee.rb1
-rw-r--r--app/models/pages_deployment.rb10
-rw-r--r--app/models/project_pages_metadatum.rb1
-rw-r--r--app/models/release.rb17
-rw-r--r--app/models/snippet.rb4
-rw-r--r--app/services/design_management/copy_design_collection/copy_service.rb19
-rw-r--r--app/services/projects/update_pages_service.rb16
-rw-r--r--app/services/todos/destroy/entity_leave_service.rb74
-rw-r--r--app/uploaders/pages/deployment_uploader.rb28
-rw-r--r--app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml11
-rw-r--r--app/views/devise/shared/_signup_box.html.haml8
-rw-r--r--app/views/devise/shared/_terms_of_service_notice.html.haml5
24 files changed, 268 insertions, 105 deletions
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table_row.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table_row.vue
index 3f383f9e864..898973e03e1 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table_row.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table_row.vue
@@ -20,7 +20,7 @@ import { PIPELINES_TABLE } from '../../constants';
export default {
i18n: {
cancelTitle: __('Cancel'),
- redeployTitle: __('Pipelines|Retry'),
+ redeployTitle: __('Retry'),
},
directives: {
GlTooltip: GlTooltipDirective,
diff --git a/app/assets/javascripts/vue_shared/components/members/action_buttons/leave_button.vue b/app/assets/javascripts/vue_shared/components/members/action_buttons/leave_button.vue
new file mode 100644
index 00000000000..d9976e7181c
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/members/action_buttons/leave_button.vue
@@ -0,0 +1,40 @@
+<script>
+import { GlButton, GlModalDirective, GlTooltipDirective } from '@gitlab/ui';
+import { __ } from '~/locale';
+import LeaveModal from '../modals/leave_modal.vue';
+import { LEAVE_MODAL_ID } from '../constants';
+
+export default {
+ name: 'LeaveButton',
+ title: __('Leave'),
+ modalId: LEAVE_MODAL_ID,
+ components: {
+ GlButton,
+ LeaveModal,
+ },
+ directives: {
+ GlModal: GlModalDirective,
+ GlTooltip: GlTooltipDirective,
+ },
+ props: {
+ member: {
+ type: Object,
+ required: true,
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <gl-button
+ v-gl-tooltip.hover
+ v-gl-modal="$options.modalId"
+ :title="$options.title"
+ :aria-label="$options.title"
+ icon="leave"
+ variant="danger"
+ />
+ <leave-modal :member="member" />
+ </div>
+</template>
diff --git a/app/assets/javascripts/vue_shared/components/members/action_buttons/user_action_buttons.vue b/app/assets/javascripts/vue_shared/components/members/action_buttons/user_action_buttons.vue
index 05e1833b9d1..8fa3d439fc1 100644
--- a/app/assets/javascripts/vue_shared/components/members/action_buttons/user_action_buttons.vue
+++ b/app/assets/javascripts/vue_shared/components/members/action_buttons/user_action_buttons.vue
@@ -1,11 +1,12 @@
<script>
import ActionButtonGroup from './action_button_group.vue';
import RemoveMemberButton from './remove_member_button.vue';
+import LeaveButton from './leave_button.vue';
import { s__, sprintf } from '~/locale';
export default {
name: 'UserActionButtons',
- components: { ActionButtonGroup, RemoveMemberButton },
+ components: { ActionButtonGroup, RemoveMemberButton, LeaveButton },
props: {
member: {
type: Object,
@@ -48,9 +49,7 @@ export default {
<template>
<action-button-group>
<div v-if="permissions.canRemove" class="gl-px-1">
- <template v-if="isCurrentUser">
- <!-- Leave button will go here -->
- </template>
+ <leave-button v-if="isCurrentUser" :member="member" />
<remove-member-button
v-else
:member-id="member.id"
diff --git a/app/assets/javascripts/vue_shared/components/members/constants.js b/app/assets/javascripts/vue_shared/components/members/constants.js
index 9dc0ec97ce6..8b504d06bb2 100644
--- a/app/assets/javascripts/vue_shared/components/members/constants.js
+++ b/app/assets/javascripts/vue_shared/components/members/constants.js
@@ -64,3 +64,5 @@ export const MEMBER_TYPES = {
};
export const DAYS_TO_EXPIRE_SOON = 7;
+
+export const LEAVE_MODAL_ID = 'member-leave-modal';
diff --git a/app/assets/javascripts/vue_shared/components/members/modals/leave_modal.vue b/app/assets/javascripts/vue_shared/components/members/modals/leave_modal.vue
new file mode 100644
index 00000000000..9a2ce0d4931
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/members/modals/leave_modal.vue
@@ -0,0 +1,70 @@
+<script>
+import { mapState } from 'vuex';
+import { GlModal, GlForm, GlSprintf, GlTooltipDirective } from '@gitlab/ui';
+import csrf from '~/lib/utils/csrf';
+import { __, s__, sprintf } from '~/locale';
+import { LEAVE_MODAL_ID } from '../constants';
+
+export default {
+ name: 'LeaveModal',
+ actionCancel: {
+ text: __('Cancel'),
+ },
+ actionPrimary: {
+ text: __('Leave'),
+ attributes: {
+ variant: 'danger',
+ },
+ },
+ csrf,
+ modalId: LEAVE_MODAL_ID,
+ modalContent: s__('Members|Are you sure you want to leave "%{source}"?'),
+ components: { GlModal, GlForm, GlSprintf },
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
+ props: {
+ member: {
+ type: Object,
+ required: true,
+ },
+ },
+ computed: {
+ ...mapState(['memberPath']),
+ leavePath() {
+ return this.memberPath.replace(/:id$/, 'leave');
+ },
+ modalTitle() {
+ return sprintf(s__('Members|Leave "%{source}"'), { source: this.member.source.name });
+ },
+ },
+ methods: {
+ handlePrimary() {
+ this.$refs.form.$el.submit();
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-modal
+ v-bind="$attrs"
+ :modal-id="$options.modalId"
+ :title="modalTitle"
+ :action-primary="$options.actionPrimary"
+ :action-cancel="$options.actionCancel"
+ size="sm"
+ @primary="handlePrimary"
+ >
+ <gl-form ref="form" :action="leavePath" method="post">
+ <p>
+ <gl-sprintf :message="$options.modalContent">
+ <template #source>{{ member.source.name }}</template>
+ </gl-sprintf>
+ </p>
+
+ <input type="hidden" name="_method" value="delete" />
+ <input :value="$options.csrf.token" type="hidden" name="authenticity_token" />
+ </gl-form>
+ </gl-modal>
+</template>
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
index 139ef5e0692..037c83b062b 100644
--- a/app/controllers/registrations_controller.rb
+++ b/app/controllers/registrations_controller.rb
@@ -13,16 +13,12 @@ class RegistrationsController < Devise::RegistrationsController
skip_before_action :required_signup_info, :check_two_factor_requirement, only: [:welcome, :update_registration]
prepend_before_action :check_captcha, only: :create
before_action :whitelist_query_limiting, :ensure_destroy_prerequisites_met, only: [:destroy]
- before_action :ensure_terms_accepted,
- if: -> { action_name == 'create' && Gitlab::CurrentSettings.current_application_settings.enforce_terms? }
before_action :load_recaptcha, only: :new
feature_category :authentication_and_authorization
def new
if experiment_enabled?(:signup_flow)
- track_experiment_event(:terms_opt_in, 'start')
-
@resource = build_resource
else
redirect_to new_user_session_path(anchor: 'register-pane')
@@ -36,7 +32,6 @@ class RegistrationsController < Devise::RegistrationsController
super do |new_user|
persist_accepted_terms_if_required(new_user)
set_role_required(new_user)
- track_terms_experiment(new_user)
yield new_user if block_given?
end
@@ -86,10 +81,8 @@ class RegistrationsController < Devise::RegistrationsController
return unless new_user.persisted?
return unless Gitlab::CurrentSettings.current_application_settings.enforce_terms?
- if terms_accepted?
- terms = ApplicationSetting::Term.latest
- Users::RespondToTermsService.new(new_user, terms).execute(accepted: true)
- end
+ terms = ApplicationSetting::Term.latest
+ Users::RespondToTermsService.new(new_user, terms).execute(accepted: true)
end
def set_role_required(new_user)
@@ -185,18 +178,6 @@ class RegistrationsController < Devise::RegistrationsController
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42380')
end
- def ensure_terms_accepted
- return if terms_accepted?
-
- redirect_to new_user_session_path, alert: _('You must accept our Terms of Service and privacy policy in order to register an account')
- end
-
- def terms_accepted?
- return true if experiment_enabled?(:terms_opt_in)
-
- Gitlab::Utils.to_boolean(params[:terms_opt_in])
- end
-
def path_for_signed_in_user(user)
if requires_confirmation?(user)
users_almost_there_path
@@ -213,13 +194,6 @@ class RegistrationsController < Devise::RegistrationsController
true
end
- def track_terms_experiment(new_user)
- return unless new_user.persisted?
-
- track_experiment_event(:terms_opt_in, 'end')
- record_experiment_user(:terms_opt_in)
- end
-
def load_recaptcha
Gitlab::Recaptcha.load_configurations!
end
diff --git a/app/finders/alert_management/alerts_finder.rb b/app/finders/alert_management/alerts_finder.rb
index e3ff7191ea5..1d6f790af31 100644
--- a/app/finders/alert_management/alerts_finder.rb
+++ b/app/finders/alert_management/alerts_finder.rb
@@ -19,8 +19,10 @@ module AlertManagement
collection = project.alert_management_alerts
collection = by_status(collection)
- collection = by_search(collection)
collection = by_iid(collection)
+ collection = by_assignee(collection)
+ collection = by_search(collection)
+
sort(collection)
end
@@ -48,6 +50,10 @@ module AlertManagement
params[:sort] ? collection.sort_by_attribute(params[:sort]) : collection
end
+ def by_assignee(collection)
+ params[:assignee_username].present? ? collection.for_assignee_username(params[:assignee_username]) : collection
+ end
+
def authorized?
Ability.allowed?(current_user, :read_alert_management_alert, project)
end
diff --git a/app/finders/releases_finder.rb b/app/finders/releases_finder.rb
index e961ad4c0ca..da72178169e 100644
--- a/app/finders/releases_finder.rb
+++ b/app/finders/releases_finder.rb
@@ -9,6 +9,9 @@ class ReleasesFinder
@parent = parent
@current_user = current_user
@params = params
+
+ params[:order_by] ||= 'released_at'
+ params[:sort] ||= 'desc'
end
def execute(preload: true)
@@ -17,7 +20,8 @@ class ReleasesFinder
releases = get_releases
releases = by_tag(releases)
releases = releases.preloaded if preload
- releases.sorted
+ releases = order_releases(releases)
+ releases
end
private
@@ -57,4 +61,8 @@ class ReleasesFinder
releases.where(tag: params[:tag])
end
# rubocop: enable CodeReuse/ActiveRecord
+
+ def order_releases(releases)
+ releases.sort_by_attribute("#{params[:order_by]}_#{params[:sort]}")
+ end
end
diff --git a/app/graphql/resolvers/alert_management/alert_resolver.rb b/app/graphql/resolvers/alert_management/alert_resolver.rb
index 71a7615685a..dc9b1dbb5f4 100644
--- a/app/graphql/resolvers/alert_management/alert_resolver.rb
+++ b/app/graphql/resolvers/alert_management/alert_resolver.rb
@@ -22,6 +22,10 @@ module Resolvers
description: 'Search criteria for filtering alerts. This will search on title, description, service, monitoring_tool.',
required: false
+ argument :assignee_username, GraphQL::STRING_TYPE,
+ required: false,
+ description: 'Username of a user assigned to the issue'
+
type Types::AlertManagement::AlertType, null: true
def resolve_with_lookahead(**args)
diff --git a/app/graphql/resolvers/alert_management/alert_status_counts_resolver.rb b/app/graphql/resolvers/alert_management/alert_status_counts_resolver.rb
index a45de21002f..96ea4610aff 100644
--- a/app/graphql/resolvers/alert_management/alert_status_counts_resolver.rb
+++ b/app/graphql/resolvers/alert_management/alert_status_counts_resolver.rb
@@ -9,6 +9,10 @@ module Resolvers
description: 'Search criteria for filtering alerts. This will search on title, description, service, monitoring_tool.',
required: false
+ argument :assignee_username, GraphQL::STRING_TYPE,
+ required: false,
+ description: 'Username of a user assigned to the issue'
+
def resolve(**args)
::Gitlab::AlertManagement::AlertStatusCounts.new(context[:current_user], object, args)
end
diff --git a/app/models/alert_management/alert.rb b/app/models/alert_management/alert.rb
index 44d82453c1f..71d09830d56 100644
--- a/app/models/alert_management/alert.rb
+++ b/app/models/alert_management/alert.rb
@@ -113,6 +113,7 @@ module AlertManagement
scope :for_status, -> (status) { with_status(status) }
scope :for_fingerprint, -> (project, fingerprint) { where(project: project, fingerprint: fingerprint) }
scope :for_environment, -> (environment) { where(environment: environment) }
+ scope :for_assignee_username, -> (assignee_username) { joins(:assignees).merge(User.by_username(assignee_username)) }
scope :search, -> (query) { fuzzy_search(query, [:title, :description, :monitoring_tool, :service]) }
scope :open, -> { with_status(open_statuses) }
scope :not_resolved, -> { without_status(:resolved) }
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 621b1a83b82..5291b7890b6 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -90,6 +90,7 @@ class Issue < ApplicationRecord
alias_method :issuing_parent, :project
scope :in_projects, ->(project_ids) { where(project_id: project_ids) }
+ scope :not_in_projects, ->(project_ids) { where.not(project_id: project_ids) }
scope :with_due_date, -> { where.not(due_date: nil) }
scope :without_due_date, -> { where(due_date: nil) }
diff --git a/app/models/issue_assignee.rb b/app/models/issue_assignee.rb
index e57acbae546..7f3d552b3d9 100644
--- a/app/models/issue_assignee.rb
+++ b/app/models/issue_assignee.rb
@@ -8,6 +8,7 @@ class IssueAssignee < ApplicationRecord
scope :in_projects, ->(project_ids) { joins(:issue).where("issues.project_id in (?)", project_ids) }
scope :on_issues, ->(issue_ids) { where(issue_id: issue_ids) }
+ scope :for_assignee, ->(user) { where(assignee: user) }
end
IssueAssignee.prepend_if_ee('EE::IssueAssignee')
diff --git a/app/models/pages_deployment.rb b/app/models/pages_deployment.rb
index d8f122cfb23..cd952c32046 100644
--- a/app/models/pages_deployment.rb
+++ b/app/models/pages_deployment.rb
@@ -11,5 +11,15 @@ class PagesDeployment < ApplicationRecord
validates :file_store, presence: true, inclusion: { in: ObjectStorage::SUPPORTED_STORES }
validates :size, presence: true, numericality: { greater_than: 0, only_integer: true }
+ before_validation :set_size, if: :file_changed?
+
+ default_value_for(:file_store) { ::Pages::DeploymentUploader.default_store }
+
mount_file_store_uploader ::Pages::DeploymentUploader
+
+ private
+
+ def set_size
+ self.size = file.size
+ end
end
diff --git a/app/models/project_pages_metadatum.rb b/app/models/project_pages_metadatum.rb
index 8a1db4a9acf..bd1919fe7ed 100644
--- a/app/models/project_pages_metadatum.rb
+++ b/app/models/project_pages_metadatum.rb
@@ -5,6 +5,7 @@ class ProjectPagesMetadatum < ApplicationRecord
belongs_to :project, inverse_of: :pages_metadatum
belongs_to :artifacts_archive, class_name: 'Ci::JobArtifact'
+ belongs_to :pages_deployment
scope :deployed, -> { where(deployed: true) }
end
diff --git a/app/models/release.rb b/app/models/release.rb
index 4c9d89105d7..f2162a0f674 100644
--- a/app/models/release.rb
+++ b/app/models/release.rb
@@ -30,6 +30,12 @@ class Release < ApplicationRecord
scope :with_project_and_namespace, -> { includes(project: :namespace) }
scope :recent, -> { sorted.limit(MAX_NUMBER_TO_DISPLAY) }
+ # Sorting
+ scope :order_created, -> { reorder('created_at ASC') }
+ scope :order_created_desc, -> { reorder('created_at DESC') }
+ scope :order_released, -> { reorder('released_at ASC') }
+ scope :order_released_desc, -> { reorder('released_at DESC') }
+
delegate :repository, to: :project
MAX_NUMBER_TO_DISPLAY = 3
@@ -92,6 +98,17 @@ class Release < ApplicationRecord
def set_released_at
self.released_at ||= created_at
end
+
+ def self.sort_by_attribute(method)
+ case method.to_s
+ when 'created_at_asc' then order_created
+ when 'created_at_desc' then order_created_desc
+ when 'released_at_asc' then order_released
+ when 'released_at_desc' then order_released_desc
+ else
+ order_created_desc
+ end
+ end
end
Release.prepend_if_ee('EE::Release')
diff --git a/app/models/snippet.rb b/app/models/snippet.rb
index 7d2229140b8..9c1ad5bba8f 100644
--- a/app/models/snippet.rb
+++ b/app/models/snippet.rb
@@ -282,7 +282,9 @@ class Snippet < ApplicationRecord
strong_memoize(:repository_size_checker) do
::Gitlab::RepositorySizeChecker.new(
current_size_proc: -> { repository.size.megabytes },
- limit: Gitlab::CurrentSettings.snippet_size_limit
+ limit: Gitlab::CurrentSettings.snippet_size_limit,
+ total_repository_size_excess: nil,
+ additional_purchased_storage: nil
)
end
end
diff --git a/app/services/design_management/copy_design_collection/copy_service.rb b/app/services/design_management/copy_design_collection/copy_service.rb
index 68f69a9c8db..5099c2c5704 100644
--- a/app/services/design_management/copy_design_collection/copy_service.rb
+++ b/app/services/design_management/copy_design_collection/copy_service.rb
@@ -14,6 +14,9 @@ module DesignManagement
@target_repository = @target_project.design_repository
@target_design_collection = @target_issue.design_collection
@temporary_branch = "CopyDesignCollectionService_#{SecureRandom.hex}"
+ # The user who triggered the copy may not have permissions to push
+ # to the design repository.
+ @git_user = @target_project.default_owner
@designs = DesignManagement::Design.unscoped.where(issue: issue).order(:id).load
@versions = DesignManagement::Version.unscoped.where(issue: issue).order(:id).includes(:designs).load
@@ -54,9 +57,9 @@ module DesignManagement
private
- attr_reader :designs, :event_enum_map, :sha_attribute, :shas, :temporary_branch,
- :target_design_collection, :target_issue, :target_repository,
- :target_project, :versions
+ attr_reader :designs, :event_enum_map, :git_user, :sha_attribute, :shas,
+ :temporary_branch, :target_design_collection, :target_issue,
+ :target_repository, :target_project, :versions
alias_method :merge_branch, :target_branch
@@ -96,7 +99,7 @@ module DesignManagement
# create `master` first by adding a file to it.
def create_master_branch!
target_repository.create_file(
- current_user,
+ git_user,
".CopyDesignCollectionService_#{Time.now.to_i}",
'.gitlab',
message: "Commit to create #{merge_branch} branch in CopyDesignCollectionService",
@@ -106,7 +109,7 @@ module DesignManagement
def create_temporary_branch!
target_repository.add_branch(
- current_user,
+ git_user,
temporary_branch,
target_repository.root_ref
)
@@ -115,7 +118,7 @@ module DesignManagement
def remove_temporary_branch!
return unless target_repository.branch_exists?(temporary_branch)
- target_repository.rm_branch(current_user, temporary_branch)
+ target_repository.rm_branch(git_user, temporary_branch)
end
# Merge the temporary branch containing the commits to `master`
@@ -124,7 +127,7 @@ module DesignManagement
source_sha = shas.last
target_repository.raw.merge(
- current_user,
+ git_user,
source_sha,
merge_branch,
'CopyDesignCollectionService finalize merge'
@@ -155,7 +158,7 @@ module DesignManagement
end
sha = target_repository.multi_action(
- current_user,
+ git_user,
branch_name: temporary_branch,
message: commit_message(version),
actions: gitaly_actions
diff --git a/app/services/projects/update_pages_service.rb b/app/services/projects/update_pages_service.rb
index ea37f2e4ec0..64b9eca9014 100644
--- a/app/services/projects/update_pages_service.rb
+++ b/app/services/projects/update_pages_service.rb
@@ -97,6 +97,7 @@ module Projects
build.artifacts_file.use_file do |artifacts_path|
SafeZip::Extract.new(artifacts_path)
.extract(directories: [PUBLIC_DIR], to: temp_path)
+ create_pages_deployment(artifacts_path)
end
rescue SafeZip::Extract::Error => e
raise FailedToExtractError, e.message
@@ -118,6 +119,21 @@ module Projects
FileUtils.rm_r(previous_public_path, force: true)
end
+ def create_pages_deployment(artifacts_path)
+ return unless Feature.enabled?(:zip_pages_deployments, project)
+
+ File.open(artifacts_path) do |file|
+ deployment = project.pages_deployments.create!(file: file)
+ project.pages_metadatum.update!(pages_deployment: deployment)
+ end
+
+ # TODO: schedule old deployment removal https://gitlab.com/gitlab-org/gitlab/-/issues/235730
+ rescue => e
+ # we don't want to break current pages deployment process if something goes wrong
+ # TODO: remove this rescue as part of https://gitlab.com/gitlab-org/gitlab/-/issues/245308
+ Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e)
+ end
+
def latest?
# check if sha for the ref is still the most recent one
# this helps in case when multiple deployments happens
diff --git a/app/services/todos/destroy/entity_leave_service.rb b/app/services/todos/destroy/entity_leave_service.rb
index 0c0548a17a1..97c56b84434 100644
--- a/app/services/todos/destroy/entity_leave_service.rb
+++ b/app/services/todos/destroy/entity_leave_service.rb
@@ -7,16 +7,14 @@ module Todos
attr_reader :user, :entity
- # rubocop: disable CodeReuse/ActiveRecord
def initialize(user_id, entity_id, entity_type)
unless %w(Group Project).include?(entity_type)
raise ArgumentError.new("#{entity_type} is not an entity user can leave")
end
- @user = User.find_by(id: user_id)
- @entity = entity_type.constantize.find_by(id: entity_id)
+ @user = UserFinder.new(user_id).find_by_id
+ @entity = entity_type.constantize.find_by(id: entity_id) # rubocop: disable CodeReuse/ActiveRecord
end
- # rubocop: enable CodeReuse/ActiveRecord
def execute
return unless entity && user
@@ -42,34 +40,37 @@ module Todos
end
end
- # rubocop: disable CodeReuse/ActiveRecord
def remove_confidential_issue_todos
- Todo.where(
- target_id: confidential_issues.select(:id), target_type: Issue.name, user_id: user.id
- ).delete_all
+ Todo
+ .for_target(confidential_issues.select(:id))
+ .for_type(Issue.name)
+ .for_user(user)
+ .delete_all
end
- # rubocop: enable CodeReuse/ActiveRecord
- # rubocop: disable CodeReuse/ActiveRecord
def remove_project_todos
# Issues are viewable by guests (even in private projects), so remove those todos
# from projects without guest access
- Todo.where(project_id: non_authorized_guest_projects, user_id: user.id)
+ Todo
+ .for_project(non_authorized_guest_projects)
+ .for_user(user)
.delete_all
# MRs require reporter access, so remove those todos that are not authorized
- Todo.where(project_id: non_authorized_reporter_projects, target_type: MergeRequest.name, user_id: user.id)
+ Todo
+ .for_project(non_authorized_reporter_projects)
+ .for_type(MergeRequest.name)
+ .for_user(user)
.delete_all
end
- # rubocop: enable CodeReuse/ActiveRecord
- # rubocop: disable CodeReuse/ActiveRecord
def remove_group_todos
- Todo.where(group_id: non_authorized_groups, user_id: user.id).delete_all
+ Todo
+ .for_group(non_authorized_groups)
+ .for_user(user)
+ .delete_all
end
- # rubocop: enable CodeReuse/ActiveRecord
- # rubocop: disable CodeReuse/ActiveRecord
def projects
condition = case entity
when Project
@@ -78,55 +79,40 @@ module Todos
{ namespace_id: non_authorized_reporter_groups }
end
- Project.where(condition)
+ Project.where(condition) # rubocop: disable CodeReuse/ActiveRecord
end
- # rubocop: enable CodeReuse/ActiveRecord
- # rubocop: disable CodeReuse/ActiveRecord
def authorized_reporter_projects
user.authorized_projects(Gitlab::Access::REPORTER).select(:id)
end
- # rubocop: enable CodeReuse/ActiveRecord
- # rubocop: disable CodeReuse/ActiveRecord
def authorized_guest_projects
user.authorized_projects(Gitlab::Access::GUEST).select(:id)
end
- # rubocop: enable CodeReuse/ActiveRecord
- # rubocop: disable CodeReuse/ActiveRecord
def non_authorized_reporter_projects
- projects.where('id NOT IN (?)', authorized_reporter_projects)
+ projects.id_not_in(authorized_reporter_projects)
end
- # rubocop: enable CodeReuse/ActiveRecord
- # rubocop: disable CodeReuse/ActiveRecord
def non_authorized_guest_projects
- projects.where('id NOT IN (?)', authorized_guest_projects)
+ projects.id_not_in(authorized_guest_projects)
end
- # rubocop: enable CodeReuse/ActiveRecord
- # rubocop: disable CodeReuse/ActiveRecord
def authorized_reporter_groups
GroupsFinder.new(user, min_access_level: Gitlab::Access::REPORTER).execute.select(:id)
end
- # rubocop: enable CodeReuse/ActiveRecord
- # rubocop: disable CodeReuse/ActiveRecord
def non_authorized_groups
return [] unless entity.is_a?(Namespace)
entity.self_and_descendants.select(:id)
- .where('id NOT IN (?)', GroupsFinder.new(user).execute.select(:id))
+ .id_not_in(GroupsFinder.new(user).execute.select(:id))
end
- # rubocop: enable CodeReuse/ActiveRecord
- # rubocop: disable CodeReuse/ActiveRecord
def non_authorized_reporter_groups
entity.self_and_descendants.select(:id)
- .where('id NOT IN (?)', authorized_reporter_groups)
+ .id_not_in(authorized_reporter_groups)
end
- # rubocop: enable CodeReuse/ActiveRecord
def user_has_reporter_access?
return unless entity.is_a?(Namespace)
@@ -134,16 +120,16 @@ module Todos
entity.member?(User.find(user.id), Gitlab::Access::REPORTER)
end
- # rubocop: disable CodeReuse/ActiveRecord
def confidential_issues
- assigned_ids = IssueAssignee.select(:issue_id).where(user_id: user.id)
+ assigned_ids = IssueAssignee.select(:issue_id).for_assignee(user)
- Issue.where(project_id: projects, confidential: true)
- .where('project_id NOT IN(?)', authorized_reporter_projects)
- .where('author_id != ?', user.id)
- .where('id NOT IN (?)', assigned_ids)
+ Issue
+ .in_projects(projects)
+ .confidential_only
+ .not_in_projects(authorized_reporter_projects)
+ .not_authored_by(user)
+ .id_not_in(assigned_ids)
end
- # rubocop: enable CodeReuse/ActiveRecord
end
end
end
diff --git a/app/uploaders/pages/deployment_uploader.rb b/app/uploaders/pages/deployment_uploader.rb
index 4fe1a548a05..e510025fc7d 100644
--- a/app/uploaders/pages/deployment_uploader.rb
+++ b/app/uploaders/pages/deployment_uploader.rb
@@ -19,5 +19,33 @@ module Pages
def base_dir
"@hashed"
end
+
+ # override GitlabUploader
+ # if set to true it erases the original file when uploading
+ # and we copy from the artifacts archive, so artifacts end up
+ # without the file
+ def move_to_cache
+ false
+ end
+
+ class << self
+ # we only upload this files from the rails background job
+ # so we don't need direct upload for pages deployments
+ # this method is here to ignore any user setting
+ def direct_upload_enabled?
+ false
+ end
+
+ # we don't need background uploads because we upload files
+ # to the right store right away, and we already do that in
+ # the background job
+ def background_upload_enabled?
+ false
+ end
+
+ def default_store
+ object_store_enabled? ? ObjectStorage::Store::REMOTE : ObjectStorage::Store::LOCAL
+ end
+ end
end
end
diff --git a/app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml b/app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml
index ecabb4495cc..621bbb32a13 100644
--- a/app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml
+++ b/app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml
@@ -28,21 +28,12 @@
= f.label :password, class: 'label-bold'
= f.password_field :password, class: "form-control bottom", data: { qa_selector: 'new_user_password_field' }, required: true, pattern: ".{#{@minimum_password_length},}", title: _("Minimum length is %{minimum_password_length} characters.") % { minimum_password_length: @minimum_password_length }
%p.gl-field-hint.text-secondary= _('Minimum length is %{minimum_password_length} characters') % { minimum_password_length: @minimum_password_length }
- - if Gitlab::CurrentSettings.current_application_settings.enforce_terms? && !experiment_enabled?(:terms_opt_in)
- .form-group
- = check_box_tag :terms_opt_in, '1', false, required: true, data: { qa_selector: 'new_user_accept_terms_checkbox' }
- = label_tag :terms_opt_in do
- - terms_link = link_to s_("I accept the|Terms of Service and Privacy Policy"), terms_path, target: "_blank"
- - accept_terms_label = _("I accept the %{terms_link}") % { terms_link: terms_link }
- = accept_terms_label.html_safe
= render_if_exists 'devise/shared/email_opted_in', f: f
%div
- if show_recaptcha_sign_up?
= recaptcha_tags
.submit-container.mt-3
= f.submit _("Register"), class: "btn-register btn btn-block btn-success mb-0 p-2", data: { qa_selector: 'new_user_register_button' }
- - if experiment_enabled?(:terms_opt_in)
- %p.gl-text-gray-500.gl-mt-5.gl-mb-0
- = html_escape(_("By clicking Register, I agree that I have read and accepted the GitLab %{linkStart}Terms of Use and Privacy Policy%{linkEnd}")) % { linkStart: "<a href='#{terms_path}' target='_blank' rel='noreferrer noopener'>".html_safe, linkEnd: '</a>'.html_safe }
+ = render 'devise/shared/terms_of_service_notice'
- if omniauth_enabled? && button_based_providers_enabled?
= render 'devise/shared/experimental_separate_sign_up_flow_omniauth_box'
diff --git a/app/views/devise/shared/_signup_box.html.haml b/app/views/devise/shared/_signup_box.html.haml
index 1fd81cdbac2..f4ac9ad696b 100644
--- a/app/views/devise/shared/_signup_box.html.haml
+++ b/app/views/devise/shared/_signup_box.html.haml
@@ -28,16 +28,10 @@
= f.label :password, class: 'label-bold'
= f.password_field :password, class: "form-control bottom", data: { qa_selector: 'new_user_password_field' }, required: true, pattern: ".{#{@minimum_password_length},}", title: _("Minimum length is %{minimum_password_length} characters.") % { minimum_password_length: @minimum_password_length }
%p.gl-field-hint.text-secondary= _('Minimum length is %{minimum_password_length} characters') % { minimum_password_length: @minimum_password_length }
- - if Gitlab::CurrentSettings.current_application_settings.enforce_terms?
- .form-group
- = check_box_tag :terms_opt_in, '1', false, required: true, data: { qa_selector: 'new_user_accept_terms_checkbox' }
- = label_tag :terms_opt_in do
- - terms_link = link_to s_("I accept the|Terms of Service and Privacy Policy"), terms_path, target: "_blank"
- - accept_terms_label = _("I accept the %{terms_link}") % { terms_link: terms_link }
- = accept_terms_label.html_safe
= render_if_exists 'devise/shared/email_opted_in', f: f
%div
- if show_recaptcha_sign_up?
= recaptcha_tags
.submit-container
= f.submit _("Register"), class: "btn-register btn", data: { qa_selector: 'new_user_register_button' }
+ = render 'devise/shared/terms_of_service_notice'
diff --git a/app/views/devise/shared/_terms_of_service_notice.html.haml b/app/views/devise/shared/_terms_of_service_notice.html.haml
new file mode 100644
index 00000000000..46b043b2831
--- /dev/null
+++ b/app/views/devise/shared/_terms_of_service_notice.html.haml
@@ -0,0 +1,5 @@
+- company_name = Gitlab.com? ? 'GitLab' : ''
+
+- if Gitlab::CurrentSettings.current_application_settings.enforce_terms?
+ %p.gl-text-gray-500.gl-mt-5.gl-mb-0
+ = html_escape(_("By clicking Register, I agree that I have read and accepted the %{company_name} %{linkStart}Terms of Use and Privacy Policy%{linkEnd}")) % { linkStart: "<a href='#{terms_path}' target='_blank' rel='noreferrer noopener'>".html_safe, linkEnd: '</a>'.html_safe, company_name: company_name }