From 2b73aaa15ad9f651f51f8c71de461da6664a4fbb Mon Sep 17 00:00:00 2001 From: Ali Ibrahim Date: Sun, 14 Aug 2016 13:49:08 -0400 Subject: Allow to add deploy keys with write-access --- lib/gitlab/git_access.rb | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index 1882eb8d050..f208df3cdce 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -50,10 +50,13 @@ module Gitlab end def push_access_check(changes) + unless project.repository.exists? + return build_status_object(false, "A repository for this project does not exist yet.") + end if user user_push_access_check(changes) elsif deploy_key - build_status_object(false, "Deploy keys are not allowed to push code.") + deploy_key_push_access_check(changes) else raise 'Wrong actor' end @@ -72,10 +75,6 @@ module Gitlab return build_status_object(true) end - unless project.repository.exists? - return build_status_object(false, "A repository for this project does not exist yet.") - end - changes_list = Gitlab::ChangesList.new(changes) # Iterate over all changes to find if user allowed all of them to be applied @@ -90,6 +89,14 @@ module Gitlab build_status_object(true) end + def deploy_key_push_access_check(changes) + if actor.can_push? + build_status_object(true) + else + build_status_object(false, "The deploy key does not have write access to the project.") + end + end + def change_access_check(change) Checks::ChangeAccess.new(change, user_access: user_access, project: project).exec end -- cgit v1.2.1 From fcc2c43ebb32c0e9a3ae636e66460b42cbae4d53 Mon Sep 17 00:00:00 2001 From: Ali Ibrahim Date: Thu, 18 Aug 2016 03:27:45 -0400 Subject: Added can_push attribute to deploy keys and update docs for API --- lib/api/entities.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 055716ab1e3..5df65a2327d 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -234,7 +234,7 @@ module API end class SSHKey < Grape::Entity - expose :id, :title, :key, :created_at + expose :id, :title, :key, :created_at, :can_push end class SSHKeyWithUser < SSHKey -- cgit v1.2.1 From 2811a213a6199978ca1f3eea002a7a77f8b87554 Mon Sep 17 00:00:00 2001 From: Ali Ibrahim Date: Fri, 19 Aug 2016 14:40:45 -0400 Subject: added spacing --- lib/gitlab/git_access.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index f208df3cdce..f7432df5557 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -53,6 +53,7 @@ module Gitlab unless project.repository.exists? return build_status_object(false, "A repository for this project does not exist yet.") end + if user user_push_access_check(changes) elsif deploy_key -- cgit v1.2.1 From 05cc87052a7755da3d352409ef3ab024921593c4 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 11 Nov 2016 20:40:28 +0800 Subject: Improve write access check for deploy key --- lib/gitlab/git_access.rb | 81 +++++++++++++++++++++--------------------------- 1 file changed, 36 insertions(+), 45 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index 64b5c4b98dc..819e0657bdd 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -7,7 +7,7 @@ module Gitlab ERROR_MESSAGES = { upload: 'You are not allowed to upload code for this project.', download: 'You are not allowed to download code from this project.', - deploy_key: 'Deploy keys are not allowed to push code.', + deploy_key: 'This deploy key does not have write access to this project.', no_repo: 'A repository for this project does not exist yet.' } @@ -46,22 +46,18 @@ module Gitlab def download_access_check if user user_download_access_check - elsif deploy_key.nil? && !Guest.can?(:download_code, project) + elsif !Guest.can?(:download_code, project) raise UnauthorizedError, ERROR_MESSAGES[:download] end end def push_access_check(changes) - unless project.repository.exists? - return build_status_object(false, "A repository for this project does not exist yet.") - end - - if user - user_push_access_check(changes) - elsif deploy_key + if deploy_key deploy_key_push_access_check(changes) + elsif user + user_push_access_check(changes) else - raise UnauthorizedError, ERROR_MESSAGES[deploy_key ? :deploy_key : :upload] + raise UnauthorizedError, ERROR_MESSAGES[:upload] end end @@ -88,34 +84,19 @@ module Gitlab return # Allow access. end - unless project.repository.exists? - raise UnauthorizedError, ERROR_MESSAGES[:no_repo] - end - - changes_list = Gitlab::ChangesList.new(changes) - - # Iterate over all changes to find if user allowed all of them to be applied - changes_list.each do |change| - status = change_access_check(change) - unless status.allowed? - # If user does not have access to make at least one change - cancel all push - raise UnauthorizedError, status.message - end - end + check_repository_existence! + check_change_access!(changes) end def deploy_key_push_access_check(changes) - if actor.can_push? - build_status_object(true) + if deploy_key.can_push? + check_repository_existence! + check_change_access!(changes) else - build_status_object(false, "The deploy key does not have write access to the project.") + raise UnauthorizedError, ERROR_MESSAGES[:deploy_key] end end - def change_access_check(change) - Checks::ChangeAccess.new(change, user_access: user_access, project: project).exec - end - def protocol_allowed? Gitlab::ProtocolAccess.allowed?(protocol) end @@ -146,6 +127,27 @@ module Gitlab end end + def check_repository_existence! + unless project.repository.exists? + raise UnauthorizedError, ERROR_MESSAGES[:no_repo] + end + end + + def check_change_access!(changes) + changes_list = Gitlab::ChangesList.new(changes) + + # Iterate over all changes to find if user allowed all of them to be applied + changes_list.each do |change| + status = Checks::ChangeAccess.new(change, + user_access: user_access, + project: project).exec + unless status.allowed? + # If user does not have access to make at least one change - cancel all push + raise UnauthorizedError, status.message + end + end + end + def matching_merge_request?(newrev, branch_name) Checks::MatchingMergeRequest.new(newrev, branch_name, project).match? end @@ -154,20 +156,11 @@ module Gitlab actor if actor.is_a?(DeployKey) end - def deploy_key_can_read_project? - if deploy_key - return true if project.public? - deploy_key.projects.include?(project) - else - false - end - end - def can_read_project? - if user + if deploy_key + project.public? || deploy_key.projects.include?(project) + elsif user user_access.can_read_project? - elsif deploy_key - deploy_key_can_read_project? else Guest.can?(:read_project, project) end @@ -182,8 +175,6 @@ module Gitlab case actor when User actor - when DeployKey - nil when Key actor.user end -- cgit v1.2.1 From 38fbcb99dba61cfae1b788e0ec947911c4d14dd8 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 11 Nov 2016 21:24:21 +0800 Subject: So deploy key might not have a corresponding user --- lib/gitlab/git_access.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index 819e0657bdd..78f562821ea 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -46,7 +46,7 @@ module Gitlab def download_access_check if user user_download_access_check - elsif !Guest.can?(:download_code, project) + elsif deploy_key.nil? && !Guest.can?(:download_code, project) raise UnauthorizedError, ERROR_MESSAGES[:download] end end @@ -91,7 +91,7 @@ module Gitlab def deploy_key_push_access_check(changes) if deploy_key.can_push? check_repository_existence! - check_change_access!(changes) + check_change_access!(changes) if user else raise UnauthorizedError, ERROR_MESSAGES[:deploy_key] end -- cgit v1.2.1 From 71ae01fefe62caf396640affb8ca618fe68db5a0 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 11 Nov 2016 21:44:33 +0800 Subject: Add more tests and fix write to project check --- lib/gitlab/git_access.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index 78f562821ea..96979398c83 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -89,7 +89,7 @@ module Gitlab end def deploy_key_push_access_check(changes) - if deploy_key.can_push? + if deploy_key.can_push_to?(project) check_repository_existence! check_change_access!(changes) if user else -- cgit v1.2.1 From 5da9bfa453268474b3bff13c63e55b29bbcdf016 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 11 Nov 2016 22:26:05 +0800 Subject: Fix test for GitAccessWiki, it's overriding change_access_check --- lib/gitlab/git_access.rb | 9 ++++++--- lib/gitlab/git_access_wiki.rb | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index 96979398c83..b462cffeaf6 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -138,9 +138,7 @@ module Gitlab # Iterate over all changes to find if user allowed all of them to be applied changes_list.each do |change| - status = Checks::ChangeAccess.new(change, - user_access: user_access, - project: project).exec + status = check_single_change_access(change) unless status.allowed? # If user does not have access to make at least one change - cancel all push raise UnauthorizedError, status.message @@ -148,6 +146,11 @@ module Gitlab end end + def check_single_change_access(change) + Checks::ChangeAccess.new( + change, user_access: user_access, project: project).exec + end + def matching_merge_request?(newrev, branch_name) Checks::MatchingMergeRequest.new(newrev, branch_name, project).match? end diff --git a/lib/gitlab/git_access_wiki.rb b/lib/gitlab/git_access_wiki.rb index f71d3575909..f7976a64ef5 100644 --- a/lib/gitlab/git_access_wiki.rb +++ b/lib/gitlab/git_access_wiki.rb @@ -1,6 +1,6 @@ module Gitlab class GitAccessWiki < GitAccess - def change_access_check(change) + def check_single_change_access(change) if user_access.can_do_action?(:create_wiki) build_status_object(true) else -- cgit v1.2.1 From 721478123068c6718ec73c72a7b7d32c00c816df Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 16 Nov 2016 19:48:54 +0800 Subject: Also need to check against push rules: Feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7383#note_18440615 --- lib/gitlab/git_access.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index b462cffeaf6..19bdfc878b1 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -91,7 +91,7 @@ module Gitlab def deploy_key_push_access_check(changes) if deploy_key.can_push_to?(project) check_repository_existence! - check_change_access!(changes) if user + check_change_access!(changes) else raise UnauthorizedError, ERROR_MESSAGES[:deploy_key] end -- cgit v1.2.1 From a9765fb47fbbd1e1070434fc06cc76b25a42caa6 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 16 Nov 2016 20:31:08 +0800 Subject: Introduce has_access_to? so that we could reuse it Feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7383#note_18439108 --- lib/gitlab/auth/result.rb | 3 +-- lib/gitlab/git_access.rb | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/auth/result.rb b/lib/gitlab/auth/result.rb index 6be7f690676..39b86c61a18 100644 --- a/lib/gitlab/auth/result.rb +++ b/lib/gitlab/auth/result.rb @@ -9,8 +9,7 @@ module Gitlab def lfs_deploy_token?(for_project) type == :lfs_deploy_token && - actor && - actor.projects.include?(for_project) + actor.try(:has_access_to?, for_project) end def success? diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index 19bdfc878b1..a7ad944e79e 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -161,7 +161,7 @@ module Gitlab def can_read_project? if deploy_key - project.public? || deploy_key.projects.include?(project) + project.public? || deploy_key.has_access_to?(project) elsif user user_access.can_read_project? else -- cgit v1.2.1 From 48090a9188e13e3ddaffb5957a7b5a264024f060 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 16 Nov 2016 22:07:04 +0800 Subject: Introduce no_user_or_blocked? and fix tests due to checking user permission. --- lib/gitlab/user_access.rb | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/user_access.rb b/lib/gitlab/user_access.rb index 9858d2e7d83..6c7e673fb9f 100644 --- a/lib/gitlab/user_access.rb +++ b/lib/gitlab/user_access.rb @@ -8,6 +8,8 @@ module Gitlab end def can_do_action?(action) + return false if no_user_or_blocked? + @permission_cache ||= {} @permission_cache[action] ||= user.can?(action, project) end @@ -17,7 +19,7 @@ module Gitlab end def allowed? - return false if user.blank? || user.blocked? + return false if no_user_or_blocked? if user.requires_ldap_check? && user.try_obtain_ldap_lease return false unless Gitlab::LDAP::Access.allowed?(user) @@ -27,7 +29,7 @@ module Gitlab end def can_push_to_branch?(ref) - return false unless user + return false if no_user_or_blocked? if project.protected_branch?(ref) return true if project.empty_repo? && project.user_can_push_to_empty_repo?(user) @@ -40,7 +42,7 @@ module Gitlab end def can_merge_to_branch?(ref) - return false unless user + return false if no_user_or_blocked? if project.protected_branch?(ref) access_levels = project.protected_branches.matching(ref).map(&:merge_access_levels).flatten @@ -51,9 +53,15 @@ module Gitlab end def can_read_project? - return false unless user + return false if no_user_or_blocked? user.can?(:read_project, project) end + + private + + def no_user_or_blocked? + user.nil? || user.blocked? + end end end -- cgit v1.2.1 From 8c1a01e05fd3c6e1621242aaf31a0ce2789ad546 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 18 Nov 2016 03:48:23 +0800 Subject: We never check user privilege if it's a deploy key --- lib/gitlab/checks/change_access.rb | 11 +++++++++-- lib/gitlab/git_access.rb | 29 +++++++++++++++++++---------- 2 files changed, 28 insertions(+), 12 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/checks/change_access.rb b/lib/gitlab/checks/change_access.rb index cb1065223d4..6b6a86ffde9 100644 --- a/lib/gitlab/checks/change_access.rb +++ b/lib/gitlab/checks/change_access.rb @@ -1,13 +1,15 @@ module Gitlab module Checks class ChangeAccess - attr_reader :user_access, :project + attr_reader :user_access, :project, :skip_authorization - def initialize(change, user_access:, project:) + def initialize( + change, user_access:, project:, skip_authorization: false) @oldrev, @newrev, @ref = change.values_at(:oldrev, :newrev, :ref) @branch_name = Gitlab::Git.branch_name(@ref) @user_access = user_access @project = project + @skip_authorization = skip_authorization end def exec @@ -23,6 +25,7 @@ module Gitlab protected def protected_branch_checks + return if skip_authorization return unless @branch_name return unless project.protected_branch?(@branch_name) @@ -48,6 +51,8 @@ module Gitlab end def tag_checks + return if skip_authorization + tag_ref = Gitlab::Git.tag_name(@ref) if tag_ref && protected_tag?(tag_ref) && user_access.cannot_do_action?(:admin_project) @@ -56,6 +61,8 @@ module Gitlab end def push_checks + return if skip_authorization + if user_access.cannot_do_action?(:push_code) "You are not allowed to push code to this project." end diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index a7ad944e79e..6be0ab08a1f 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -27,7 +27,7 @@ module Gitlab def check(cmd, changes) check_protocol! - check_active_user! + check_active_user! unless deploy_key? check_project_accessibility! check_command_existence!(cmd) @@ -44,9 +44,13 @@ module Gitlab end def download_access_check - if user + if deploy_key + true + elsif user user_download_access_check - elsif deploy_key.nil? && !Guest.can?(:download_code, project) + elsif Guest.can?(:download_code, project) + true + else raise UnauthorizedError, ERROR_MESSAGES[:download] end end @@ -148,7 +152,10 @@ module Gitlab def check_single_change_access(change) Checks::ChangeAccess.new( - change, user_access: user_access, project: project).exec + change, + user_access: user_access, + project: project, + skip_authorization: deploy_key?).exec end def matching_merge_request?(newrev, branch_name) @@ -156,17 +163,19 @@ module Gitlab end def deploy_key - actor if actor.is_a?(DeployKey) + actor if deploy_key? + end + + def deploy_key? + actor.is_a?(DeployKey) end def can_read_project? if deploy_key - project.public? || deploy_key.has_access_to?(project) + deploy_key.has_access_to?(project) elsif user - user_access.can_read_project? - else - Guest.can?(:read_project, project) - end + user.can?(:read_project, project) + end || Guest.can?(:read_project, project) end protected -- cgit v1.2.1 From 0c532dbb243bf9bb5bf77248ce87a2a0e4478421 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 18 Nov 2016 04:08:24 +0800 Subject: Check if the key could really download, feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7383#note_18518792 --- lib/gitlab/git_access.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index 6be0ab08a1f..d5690f870e9 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -45,7 +45,7 @@ module Gitlab def download_access_check if deploy_key - true + deploy_key.has_access_to?(project) elsif user user_download_access_check elsif Guest.can?(:download_code, project) -- cgit v1.2.1 From e72e2f9ba0a160960f68035fbbdbe3f0f86b0dba Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 18 Nov 2016 04:11:04 +0800 Subject: Still grant :download_code if guest could do that Feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7383#note_18518792 --- lib/gitlab/git_access.rb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index d5690f870e9..3f674532488 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -48,11 +48,9 @@ module Gitlab deploy_key.has_access_to?(project) elsif user user_download_access_check - elsif Guest.can?(:download_code, project) - true - else - raise UnauthorizedError, ERROR_MESSAGES[:download] - end + end || + Guest.can?(:download_code, project) || + raise(UnauthorizedError, ERROR_MESSAGES[:download]) end def push_access_check(changes) -- cgit v1.2.1 From 8dbea582497bbc45735cf145a3da4c88c9e0e78d Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 18 Nov 2016 17:28:05 +0800 Subject: Check download privilege more specifically and add another error message for the new error. --- lib/gitlab/git_access.rb | 58 ++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 29 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index 3f674532488..b87ca316240 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -7,7 +7,10 @@ module Gitlab ERROR_MESSAGES = { upload: 'You are not allowed to upload code for this project.', download: 'You are not allowed to download code from this project.', - deploy_key: 'This deploy key does not have write access to this project.', + deploy_key_upload: + 'This deploy key does not have write access to this project.', + deploy_key: + 'This deploy key does not have access to this project.', no_repo: 'A repository for this project does not exist yet.' } @@ -44,29 +47,36 @@ module Gitlab end def download_access_check - if deploy_key - deploy_key.has_access_to?(project) - elsif user - user_download_access_check - end || - Guest.can?(:download_code, project) || - raise(UnauthorizedError, ERROR_MESSAGES[:download]) + passed = if deploy_key + deploy_key.has_access_to?(project) + elsif user + user_can_download_code? || build_can_download_code? + end || Guest.can?(:download_code, project) + + unless passed + message = if deploy_key + ERROR_MESSAGES[:deploy_key] + else + ERROR_MESSAGES[:download] + end + + raise UnauthorizedError, message + end end def push_access_check(changes) if deploy_key - deploy_key_push_access_check(changes) + deploy_key_push_access_check elsif user - user_push_access_check(changes) + user_push_access_check else raise UnauthorizedError, ERROR_MESSAGES[:upload] end - end - def user_download_access_check - unless user_can_download_code? || build_can_download_code? - raise UnauthorizedError, ERROR_MESSAGES[:download] - end + return if changes.blank? # Allow access. + + check_repository_existence! + check_change_access!(changes) end def user_can_download_code? @@ -77,25 +87,15 @@ module Gitlab authentication_abilities.include?(:build_download_code) && user_access.can_do_action?(:build_download_code) end - def user_push_access_check(changes) + def user_push_access_check unless authentication_abilities.include?(:push_code) raise UnauthorizedError, ERROR_MESSAGES[:upload] end - - if changes.blank? - return # Allow access. - end - - check_repository_existence! - check_change_access!(changes) end - def deploy_key_push_access_check(changes) - if deploy_key.can_push_to?(project) - check_repository_existence! - check_change_access!(changes) - else - raise UnauthorizedError, ERROR_MESSAGES[:deploy_key] + def deploy_key_push_access_check + unless deploy_key.can_push_to?(project) + raise UnauthorizedError, ERROR_MESSAGES[:deploy_key_upload] end end -- cgit v1.2.1 From 1b150576d9de9096796f76e1635d27ddaa2b1dd5 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 6 Dec 2016 21:09:23 +0800 Subject: Prefer guest_can_downlod_code? --- lib/gitlab/git_access.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index 9563fa7cafb..d42879e38cd 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -51,7 +51,7 @@ module Gitlab deploy_key.has_access_to?(project) elsif user user_can_download_code? || build_can_download_code? - end || Guest.can?(:download_code, project) + end || guest_can_downlod_code? unless passed message = if deploy_key -- cgit v1.2.1 From 46d7c1d2b3cf87023cb6bcf40dd53aa79606d203 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 6 Dec 2016 21:10:27 +0800 Subject: Prefer guest_can_download_code? and fix typo --- lib/gitlab/git_access.rb | 4 ++-- lib/gitlab/git_access_wiki.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index d42879e38cd..412f42c6320 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -51,7 +51,7 @@ module Gitlab deploy_key.has_access_to?(project) elsif user user_can_download_code? || build_can_download_code? - end || guest_can_downlod_code? + end || guest_can_download_code? unless passed message = if deploy_key @@ -79,7 +79,7 @@ module Gitlab check_change_access!(changes) end - def guest_can_downlod_code? + def guest_can_download_code? Guest.can?(:download_code, project) end diff --git a/lib/gitlab/git_access_wiki.rb b/lib/gitlab/git_access_wiki.rb index 74171f4f90e..67eaa5e088d 100644 --- a/lib/gitlab/git_access_wiki.rb +++ b/lib/gitlab/git_access_wiki.rb @@ -1,6 +1,6 @@ module Gitlab class GitAccessWiki < GitAccess - def guest_can_downlod_code? + def guest_can_download_code? Guest.can?(:download_wiki_code, project) end -- cgit v1.2.1 From 6cb6f58a6259c91f79489b7f5a71f413d0e0d81c Mon Sep 17 00:00:00 2001 From: BM5k Date: Fri, 2 Dec 2016 18:44:06 -0700 Subject: rename theme to match actual colors --- lib/gitlab/themes.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/gitlab/themes.rb b/lib/gitlab/themes.rb index d4020af76f9..19ab76ae80f 100644 --- a/lib/gitlab/themes.rb +++ b/lib/gitlab/themes.rb @@ -15,7 +15,7 @@ module Gitlab Theme.new(1, 'Graphite', 'ui_graphite'), Theme.new(2, 'Charcoal', 'ui_charcoal'), Theme.new(3, 'Green', 'ui_green'), - Theme.new(4, 'Gray', 'ui_gray'), + Theme.new(4, 'Black', 'ui_black'), Theme.new(5, 'Violet', 'ui_violet'), Theme.new(6, 'Blue', 'ui_blue') ].freeze -- cgit v1.2.1 From 57e3e942de1adef2c8621905370f07d7da7870c4 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Sat, 10 Dec 2016 01:45:13 +0800 Subject: Don't pass the actor for deploy key, feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7383#note_19579483 --- lib/gitlab/git_access.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib') diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index 412f42c6320..d483038e8e9 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -189,6 +189,8 @@ module Gitlab case actor when User actor + when DeployKey + nil when Key actor.user end -- cgit v1.2.1 From 8ac50d78eb921989d100a91aad9eb6e59cbf43dc Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Sat, 10 Dec 2016 02:04:36 +0800 Subject: Check project existence for push too, and we don't have to check for deploy key for downloading because deploy key could certainly download when it could already read the project. Feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7383#note_19578626 --- lib/gitlab/git_access.rb | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index d483038e8e9..13efc1ed73d 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -9,8 +9,6 @@ module Gitlab download: 'You are not allowed to download code from this project.', deploy_key_upload: 'This deploy key does not have write access to this project.', - deploy_key: - 'This deploy key does not have access to this project.', no_repo: 'A repository for this project does not exist yet.' } @@ -33,10 +31,11 @@ module Gitlab check_active_user! unless deploy_key? check_project_accessibility! check_command_existence!(cmd) + check_repository_existence! case cmd when *DOWNLOAD_COMMANDS - download_access_check + download_access_check unless deploy_key? when *PUSH_COMMANDS push_access_check(changes) end @@ -47,20 +46,12 @@ module Gitlab end def download_access_check - passed = if deploy_key - deploy_key.has_access_to?(project) - elsif user - user_can_download_code? || build_can_download_code? - end || guest_can_download_code? + passed = user_can_download_code? || + build_can_download_code? || + guest_can_download_code? unless passed - message = if deploy_key - ERROR_MESSAGES[:deploy_key] - else - ERROR_MESSAGES[:download] - end - - raise UnauthorizedError, message + raise UnauthorizedError, ERROR_MESSAGES[:download] end end @@ -75,7 +66,6 @@ module Gitlab return if changes.blank? # Allow access. - check_repository_existence! check_change_access!(changes) end -- cgit v1.2.1 From 884f57c9102416805427d773eb21e09fd30c2452 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 20 Dec 2016 21:19:07 +0800 Subject: Use consistent names and move checks to the method, and move those checks to be private. Feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7383#note_20285012 https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7383#note_20285279 --- lib/gitlab/git_access.rb | 82 +++++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 39 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index 545506f3dfd..f0b241fb5e6 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -29,16 +29,16 @@ module Gitlab def check(cmd, changes) check_protocol! - check_active_user! unless deploy_key? + check_active_user! check_project_accessibility! check_command_existence!(cmd) check_repository_existence! case cmd when *DOWNLOAD_COMMANDS - download_access_check unless deploy_key? + check_download_access! when *PUSH_COMMANDS - push_access_check(changes) + check_push_access!(changes) end build_status_object(true) @@ -46,30 +46,6 @@ module Gitlab build_status_object(false, ex.message) end - def download_access_check - passed = user_can_download_code? || - build_can_download_code? || - guest_can_download_code? - - unless passed - raise UnauthorizedError, ERROR_MESSAGES[:download] - end - end - - def push_access_check(changes) - if deploy_key - deploy_key_push_access_check - elsif user - user_push_access_check - else - raise UnauthorizedError, ERROR_MESSAGES[:upload] - end - - return if changes.blank? # Allow access. - - check_change_access!(changes) - end - def guest_can_download_code? Guest.can?(:download_code, project) end @@ -82,18 +58,6 @@ module Gitlab authentication_abilities.include?(:build_download_code) && user_access.can_do_action?(:build_download_code) end - def user_push_access_check - unless authentication_abilities.include?(:push_code) - raise UnauthorizedError, ERROR_MESSAGES[:upload] - end - end - - def deploy_key_push_access_check - unless deploy_key.can_push_to?(project) - raise UnauthorizedError, ERROR_MESSAGES[:deploy_key_upload] - end - end - def protocol_allowed? Gitlab::ProtocolAccess.allowed?(protocol) end @@ -107,6 +71,8 @@ module Gitlab end def check_active_user! + return if deploy_key? + if user && !user_access.allowed? raise UnauthorizedError, "Your account has been blocked." end @@ -130,6 +96,44 @@ module Gitlab end end + def check_download_access! + return if deploy_key? + + passed = user_can_download_code? || + build_can_download_code? || + guest_can_download_code? + + unless passed + raise UnauthorizedError, ERROR_MESSAGES[:download] + end + end + + def check_push_access!(changes) + if deploy_key + check_deploy_key_push_access! + elsif user + check_user_push_access! + else + raise UnauthorizedError, ERROR_MESSAGES[:upload] + end + + return if changes.blank? # Allow access. + + check_change_access!(changes) + end + + def check_user_push_access! + unless authentication_abilities.include?(:push_code) + raise UnauthorizedError, ERROR_MESSAGES[:upload] + end + end + + def check_deploy_key_push_access! + unless deploy_key.can_push_to?(project) + raise UnauthorizedError, ERROR_MESSAGES[:deploy_key_upload] + end + end + def check_change_access!(changes) changes_list = Gitlab::ChangesList.new(changes) -- cgit v1.2.1 From c1d11bf57c3091aa4695e302e21c39b9ec723f54 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 20 Dec 2016 23:30:01 +0800 Subject: Rubocop prefers to indent this way --- lib/gitlab/git_access.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index f0b241fb5e6..7e1484613f2 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -100,8 +100,8 @@ module Gitlab return if deploy_key? passed = user_can_download_code? || - build_can_download_code? || - guest_can_download_code? + build_can_download_code? || + guest_can_download_code? unless passed raise UnauthorizedError, ERROR_MESSAGES[:download] -- cgit v1.2.1 From d05dd81b99b897bcf41bfa4055d1f42bb9669af9 Mon Sep 17 00:00:00 2001 From: Markus Koller Date: Tue, 29 Nov 2016 20:25:41 +0100 Subject: Don't expose all namespace fields in API --- lib/api/entities.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index dfbb3ab86dd..c7530d9eb05 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -88,7 +88,7 @@ module API expose :shared_runners_enabled expose :lfs_enabled?, as: :lfs_enabled expose :creator_id - expose :namespace + expose :namespace, using: 'API::Entities::Namespace' expose :forked_from_project, using: Entities::BasicProjectDetails, if: lambda{ |project, options| project.forked? } expose :avatar_url expose :star_count, :forks_count @@ -391,7 +391,7 @@ module API end class Namespace < Grape::Entity - expose :id, :path, :kind + expose :id, :name, :path, :kind end class MemberAccess < Grape::Entity -- cgit v1.2.1 From d5c49779125f70c49ff8b160355d4999d27091ee Mon Sep 17 00:00:00 2001 From: Markus Koller Date: Tue, 29 Nov 2016 20:21:39 +0100 Subject: Consistently use current_user in API entities --- lib/api/entities.rb | 16 ++++++++-------- lib/api/groups.rb | 14 +++++++------- lib/api/projects.rb | 12 ++++++------ 3 files changed, 21 insertions(+), 21 deletions(-) (limited to 'lib') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index c7530d9eb05..c1e42fb7d47 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -78,11 +78,11 @@ module API expose :container_registry_enabled # Expose old field names with the new permissions methods to keep API compatible - expose(:issues_enabled) { |project, options| project.feature_available?(:issues, options[:user]) } - expose(:merge_requests_enabled) { |project, options| project.feature_available?(:merge_requests, options[:user]) } - expose(:wiki_enabled) { |project, options| project.feature_available?(:wiki, options[:user]) } - expose(:builds_enabled) { |project, options| project.feature_available?(:builds, options[:user]) } - expose(:snippets_enabled) { |project, options| project.feature_available?(:snippets, options[:user]) } + expose(:issues_enabled) { |project, options| project.feature_available?(:issues, options[:current_user]) } + expose(:merge_requests_enabled) { |project, options| project.feature_available?(:merge_requests, options[:current_user]) } + expose(:wiki_enabled) { |project, options| project.feature_available?(:wiki, options[:current_user]) } + expose(:builds_enabled) { |project, options| project.feature_available?(:builds, options[:current_user]) } + expose(:snippets_enabled) { |project, options| project.feature_available?(:snippets, options[:current_user]) } expose :created_at, :last_activity_at expose :shared_runners_enabled @@ -92,7 +92,7 @@ module API expose :forked_from_project, using: Entities::BasicProjectDetails, if: lambda{ |project, options| project.forked? } expose :avatar_url expose :star_count, :forks_count - expose :open_issues_count, if: lambda { |project, options| project.feature_available?(:issues, options[:user]) && project.default_issues_tracker? } + expose :open_issues_count, if: lambda { |project, options| project.feature_available?(:issues, options[:current_user]) && project.default_issues_tracker? } expose :runners_token, if: lambda { |_project, options| options[:user_can_admin_project] } expose :public_builds expose :shared_with_groups do |project, options| @@ -440,12 +440,12 @@ module API class ProjectWithAccess < Project expose :permissions do expose :project_access, using: Entities::ProjectAccess do |project, options| - project.project_members.find_by(user_id: options[:user].id) + project.project_members.find_by(user_id: options[:current_user].id) end expose :group_access, using: Entities::GroupAccess do |project, options| if project.group - project.group.group_members.find_by(user_id: options[:user].id) + project.group.group_members.find_by(user_id: options[:current_user].id) end end end diff --git a/lib/api/groups.rb b/lib/api/groups.rb index 9b9d3df7435..a9ae2977dc5 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -38,7 +38,7 @@ module API groups = groups.where.not(id: params[:skip_groups]) if params[:skip_groups].present? groups = groups.reorder(params[:order_by] => params[:sort]) - present paginate(groups), with: Entities::Group + present paginate(groups), with: Entities::Group, current_user: current_user end desc 'Get list of owned groups for authenticated user' do @@ -49,7 +49,7 @@ module API end get '/owned' do groups = current_user.owned_groups - present paginate(groups), with: Entities::Group, user: current_user + present paginate(groups), with: Entities::Group, current_user: current_user end desc 'Create a group. Available only for users who can create groups.' do @@ -66,7 +66,7 @@ module API group = ::Groups::CreateService.new(current_user, declared_params(include_missing: false)).execute if group.persisted? - present group, with: Entities::Group + present group, with: Entities::Group, current_user: current_user else render_api_error!("Failed to save group #{group.errors.messages}", 400) end @@ -92,7 +92,7 @@ module API authorize! :admin_group, group if ::Groups::UpdateService.new(group, current_user, declared_params(include_missing: false)).execute - present group, with: Entities::GroupDetail + present group, with: Entities::GroupDetail, current_user: current_user else render_validation_error!(group) end @@ -103,7 +103,7 @@ module API end get ":id" do group = find_group!(params[:id]) - present group, with: Entities::GroupDetail + present group, with: Entities::GroupDetail, current_user: current_user end desc 'Remove a group.' @@ -134,7 +134,7 @@ module API projects = GroupProjectsFinder.new(group).execute(current_user) projects = filter_projects(projects) entity = params[:simple] ? Entities::BasicProjectDetails : Entities::Project - present paginate(projects), with: entity, user: current_user + present paginate(projects), with: entity, current_user: current_user end desc 'Transfer a project to the group namespace. Available only for admin.' do @@ -150,7 +150,7 @@ module API result = ::Projects::TransferService.new(project, current_user).execute(group) if result - present group, with: Entities::GroupDetail + present group, with: Entities::GroupDetail, current_user: current_user else render_api_error!("Failed to transfer project #{project.errors.messages}", 400) end diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 2929d2157dc..f5609d878f8 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -75,7 +75,7 @@ module API projects = filter_projects(projects) entity = params[:simple] || !current_user ? Entities::BasicProjectDetails : Entities::ProjectWithAccess - present paginate(projects), with: entity, user: current_user + present paginate(projects), with: entity, current_user: current_user end desc 'Get a projects list for authenticated user' do @@ -94,7 +94,7 @@ module API projects = filter_projects(projects) entity = params[:simple] ? Entities::BasicProjectDetails : Entities::ProjectWithAccess - present paginate(projects), with: entity, user: current_user + present paginate(projects), with: entity, current_user: current_user end desc 'Get an owned projects list for authenticated user' do @@ -110,7 +110,7 @@ module API projects = current_user.owned_projects projects = filter_projects(projects) - present paginate(projects), with: Entities::ProjectWithAccess, user: current_user + present paginate(projects), with: Entities::ProjectWithAccess, current_user: current_user end desc 'Gets starred project for the authenticated user' do @@ -126,7 +126,7 @@ module API projects = current_user.viewable_starred_projects projects = filter_projects(projects) - present paginate(projects), with: Entities::Project, user: current_user + present paginate(projects), with: Entities::Project, current_user: current_user end desc 'Get all projects for admin user' do @@ -142,7 +142,7 @@ module API projects = Project.all projects = filter_projects(projects) - present paginate(projects), with: Entities::ProjectWithAccess, user: current_user + present paginate(projects), with: Entities::ProjectWithAccess, current_user: current_user end desc 'Search for projects the current user has access to' do @@ -221,7 +221,7 @@ module API end get ":id" do entity = current_user ? Entities::ProjectWithAccess : Entities::BasicProjectDetails - present user_project, with: entity, user: current_user, + present user_project, with: entity, current_user: current_user, user_can_admin_project: can?(current_user, :admin_project, user_project) end -- cgit v1.2.1 From 6fd58ee48dcfbca49c609c45004d6c25035af2eb Mon Sep 17 00:00:00 2001 From: Markus Koller Date: Sat, 3 Dec 2016 17:00:04 +0100 Subject: Remove rake task update_commit_count --- lib/tasks/gitlab/update_commit_count.rake | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 lib/tasks/gitlab/update_commit_count.rake (limited to 'lib') diff --git a/lib/tasks/gitlab/update_commit_count.rake b/lib/tasks/gitlab/update_commit_count.rake deleted file mode 100644 index 3bd10b0208b..00000000000 --- a/lib/tasks/gitlab/update_commit_count.rake +++ /dev/null @@ -1,20 +0,0 @@ -namespace :gitlab do - desc "GitLab | Update commit count for projects" - task update_commit_count: :environment do - projects = Project.where(commit_count: 0) - puts "#{projects.size} projects need to be updated. This might take a while." - ask_to_continue unless ENV['force'] == 'yes' - - projects.find_each(batch_size: 100) do |project| - print "#{project.name_with_namespace.color(:yellow)} ... " - - unless project.repo_exists? - puts "skipping, because the repo is empty".color(:magenta) - next - end - - project.update_commit_count - puts project.commit_count.to_s.color(:green) - end - end -end -- cgit v1.2.1 From 3ef4f74b1acc9399db320b53dffc592542de0126 Mon Sep 17 00:00:00 2001 From: Markus Koller Date: Tue, 22 Nov 2016 17:58:10 +0100 Subject: Add more storage statistics This adds counters for build artifacts and LFS objects, and moves the preexisting repository_size and commit_count from the projects table into a new project_statistics table. The counters are displayed in the administration area for projects and groups, and also available through the API for admins (on */all) and normal users (on */owned) The statistics are updated through ProjectCacheWorker, which can now do more granular updates with the new :statistics argument. --- lib/api/entities.rb | 19 +++++++++++ lib/api/groups.rb | 21 ++++++++++-- lib/api/helpers.rb | 2 +- lib/api/projects.rb | 80 ++++++++++++++++++++++++-------------------- lib/tasks/gitlab/import.rake | 3 +- 5 files changed, 82 insertions(+), 43 deletions(-) (limited to 'lib') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index c1e42fb7d47..9f15c08f472 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -101,6 +101,16 @@ module API expose :only_allow_merge_if_build_succeeds expose :request_access_enabled expose :only_allow_merge_if_all_discussions_are_resolved + + expose :statistics, using: 'API::Entities::ProjectStatistics', if: :statistics + end + + class ProjectStatistics < Grape::Entity + expose :commit_count + expose :storage_size + expose :repository_size + expose :lfs_objects_size + expose :build_artifacts_size end class Member < UserBasic @@ -127,6 +137,15 @@ module API expose :avatar_url expose :web_url expose :request_access_enabled + + expose :statistics, if: :statistics do + with_options format_with: -> (value) { value.to_i } do + expose :storage_size + expose :repository_size + expose :lfs_objects_size + expose :build_artifacts_size + end + end end class GroupDetail < Group diff --git a/lib/api/groups.rb b/lib/api/groups.rb index a9ae2977dc5..e04d2e40fb6 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -11,6 +11,20 @@ module API optional :lfs_enabled, type: Boolean, desc: 'Enable/disable LFS for the projects in this group' optional :request_access_enabled, type: Boolean, desc: 'Allow users to request member access' end + + params :statistics_params do + optional :statistics, type: Boolean, default: false, desc: 'Include project statistics' + end + + def present_groups(groups, options = {}) + options = options.reverse_merge( + with: Entities::Group, + current_user: current_user, + ) + + groups = groups.with_statistics if options[:statistics] + present paginate(groups), options + end end resource :groups do @@ -18,6 +32,7 @@ module API success Entities::Group end params do + use :statistics_params optional :skip_groups, type: Array[Integer], desc: 'Array of group ids to exclude from list' optional :all_available, type: Boolean, desc: 'Show all group that you have access to' optional :search, type: String, desc: 'Search for a specific group' @@ -38,7 +53,7 @@ module API groups = groups.where.not(id: params[:skip_groups]) if params[:skip_groups].present? groups = groups.reorder(params[:order_by] => params[:sort]) - present paginate(groups), with: Entities::Group, current_user: current_user + present_groups groups, statistics: params[:statistics] && current_user.is_admin? end desc 'Get list of owned groups for authenticated user' do @@ -46,10 +61,10 @@ module API end params do use :pagination + use :statistics_params end get '/owned' do - groups = current_user.owned_groups - present paginate(groups), with: Entities::Group, current_user: current_user + present_groups current_user.owned_groups, statistics: params[:statistics] end desc 'Create a group. Available only for users who can create groups.' do diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 4be659fc20b..fe00c83bff3 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -248,7 +248,7 @@ module API rack_response({ 'message' => '500 Internal Server Error' }.to_json, 500) end - # Projects helpers + # project helpers def filter_projects(projects) if params[:search].present? diff --git a/lib/api/projects.rb b/lib/api/projects.rb index f5609d878f8..3be14e8eb76 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -40,6 +40,15 @@ module API resource :projects do helpers do + params :collection_params do + use :sort_params + use :filter_params + use :pagination + + optional :simple, type: Boolean, default: false, + desc: 'Return only the ID, URL, name, and path of each project' + end + params :sort_params do optional :order_by, type: String, values: %w[id name path created_at updated_at last_activity_at], default: 'created_at', desc: 'Return projects ordered by field' @@ -52,97 +61,94 @@ module API optional :visibility, type: String, values: %w[public internal private], desc: 'Limit by visibility' optional :search, type: String, desc: 'Return list of authorized projects matching the search criteria' - use :sort_params + end + + params :statistics_params do + optional :statistics, type: Boolean, default: false, desc: 'Include project statistics' end params :create_params do optional :namespace_id, type: Integer, desc: 'Namespace ID for the new project. Default to the user namespace.' optional :import_url, type: String, desc: 'URL from which the project is imported' end + + def present_projects(projects, options = {}) + options = options.reverse_merge( + with: Entities::Project, + current_user: current_user, + simple: params[:simple], + ) + + projects = filter_projects(projects) + projects = projects.with_statistics if options[:statistics] + options[:with] = Entities::BasicProjectDetails if options[:simple] + + present paginate(projects), options + end end desc 'Get a list of visible projects for authenticated user' do success Entities::BasicProjectDetails end params do - optional :simple, type: Boolean, default: false, - desc: 'Return only the ID, URL, name, and path of each project' - use :filter_params - use :pagination + use :collection_params end get '/visible' do - projects = ProjectsFinder.new.execute(current_user) - projects = filter_projects(projects) - entity = params[:simple] || !current_user ? Entities::BasicProjectDetails : Entities::ProjectWithAccess - - present paginate(projects), with: entity, current_user: current_user + entity = current_user ? Entities::ProjectWithAccess : Entities::BasicProjectDetails + present_projects ProjectsFinder.new.execute(current_user), with: entity end desc 'Get a projects list for authenticated user' do success Entities::BasicProjectDetails end params do - optional :simple, type: Boolean, default: false, - desc: 'Return only the ID, URL, name, and path of each project' - use :filter_params - use :pagination + use :collection_params end get do authenticate! - projects = current_user.authorized_projects - projects = filter_projects(projects) - entity = params[:simple] ? Entities::BasicProjectDetails : Entities::ProjectWithAccess - - present paginate(projects), with: entity, current_user: current_user + present_projects current_user.authorized_projects, + with: Entities::ProjectWithAccess end desc 'Get an owned projects list for authenticated user' do success Entities::BasicProjectDetails end params do - use :filter_params - use :pagination + use :collection_params + use :statistics_params end get '/owned' do authenticate! - projects = current_user.owned_projects - projects = filter_projects(projects) - - present paginate(projects), with: Entities::ProjectWithAccess, current_user: current_user + present_projects current_user.owned_projects, + with: Entities::ProjectWithAccess, + statistics: params[:statistics] end desc 'Gets starred project for the authenticated user' do success Entities::BasicProjectDetails end params do - use :filter_params - use :pagination + use :collection_params end get '/starred' do authenticate! - projects = current_user.viewable_starred_projects - projects = filter_projects(projects) - - present paginate(projects), with: Entities::Project, current_user: current_user + present_projects current_user.viewable_starred_projects end desc 'Get all projects for admin user' do success Entities::BasicProjectDetails end params do - use :filter_params - use :pagination + use :collection_params + use :statistics_params end get '/all' do authenticated_as_admin! - projects = Project.all - projects = filter_projects(projects) - - present paginate(projects), with: Entities::ProjectWithAccess, current_user: current_user + present_projects Project.all, with: Entities::ProjectWithAccess, statistics: params[:statistics] end desc 'Search for projects the current user has access to' do diff --git a/lib/tasks/gitlab/import.rake b/lib/tasks/gitlab/import.rake index dbdd4e977e8..a2eca74a3c8 100644 --- a/lib/tasks/gitlab/import.rake +++ b/lib/tasks/gitlab/import.rake @@ -63,8 +63,7 @@ namespace :gitlab do if project.persisted? puts " * Created #{project.name} (#{repo_path})".color(:green) - project.update_repository_size - project.update_commit_count + ProjectCacheWorker.perform(project.id) else puts " * Failed trying to create #{project.name} (#{repo_path})".color(:red) puts " Errors: #{project.errors.messages}".color(:red) -- cgit v1.2.1 From a3bb2463c41124d6d7f5927bbff578a4991c15cb Mon Sep 17 00:00:00 2001 From: "http://jneen.net/" Date: Fri, 11 Nov 2016 14:09:49 +0900 Subject: switch to email_reply_trimmer from discourse --- lib/gitlab/email/reply_parser.rb | 30 ++++-------------------------- 1 file changed, 4 insertions(+), 26 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/email/reply_parser.rb b/lib/gitlab/email/reply_parser.rb index f586c5ab062..e53a99cd8e0 100644 --- a/lib/gitlab/email/reply_parser.rb +++ b/lib/gitlab/email/reply_parser.rb @@ -13,9 +13,11 @@ module Gitlab encoding = body.encoding - body = discourse_email_trimmer(body) + body = EmailReplyTrimmer.trim(body) - body = EmailReplyParser.parse_reply(body) + # TODO [jneen]: do we want to allow empty-quoting? (replies only containing a blockquote) + # EmailReplyTrimmer allows this as a special case, so we detect it manually here. + return "" if body.lines.all? { |l| l.strip.empty? || l.start_with?('>') } body.force_encoding(encoding).encode("UTF-8") end @@ -57,30 +59,6 @@ module Gitlab rescue nil end - - REPLYING_HEADER_LABELS = %w(From Sent To Subject Reply To Cc Bcc Date) - REPLYING_HEADER_REGEX = Regexp.union(REPLYING_HEADER_LABELS.map { |label| "#{label}:" }) - - def discourse_email_trimmer(body) - lines = body.scrub.lines.to_a - range_end = 0 - - lines.each_with_index do |l, idx| - # This one might be controversial but so many reply lines have years, times and end with a colon. - # Let's try it and see how well it works. - break if (l =~ /\d{4}/ && l =~ /\d:\d\d/ && l =~ /\:$/) || - (l =~ /On \w+ \d+,? \d+,?.*wrote:/) - - # Headers on subsequent lines - break if (0..2).all? { |off| lines[idx + off] =~ REPLYING_HEADER_REGEX } - # Headers on the same line - break if REPLYING_HEADER_LABELS.count { |label| l.include?(label) } >= 3 - - range_end = idx - end - - lines[0..range_end].join.strip - end end end end -- cgit v1.2.1 From 03753ff146a448eb66e7af12f56dcc4cf11922d9 Mon Sep 17 00:00:00 2001 From: "http://jneen.net/" Date: Tue, 15 Nov 2016 16:58:37 +0900 Subject: remove trailing whitespace from email bodies --- lib/gitlab/email/reply_parser.rb | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib') diff --git a/lib/gitlab/email/reply_parser.rb b/lib/gitlab/email/reply_parser.rb index e53a99cd8e0..ed8c1cd09f8 100644 --- a/lib/gitlab/email/reply_parser.rb +++ b/lib/gitlab/email/reply_parser.rb @@ -15,6 +15,9 @@ module Gitlab body = EmailReplyTrimmer.trim(body) + # [jneen] not using /\s+$/ here because that deletes empty lines + body = body.gsub(/[ \t]$/, '') + # TODO [jneen]: do we want to allow empty-quoting? (replies only containing a blockquote) # EmailReplyTrimmer allows this as a special case, so we detect it manually here. return "" if body.lines.all? { |l| l.strip.empty? || l.start_with?('>') } -- cgit v1.2.1 From 017579fe149e976fb0b2b21b234ea923913cadb2 Mon Sep 17 00:00:00 2001 From: "http://jneen.net/" Date: Fri, 18 Nov 2016 18:57:37 +0900 Subject: protect against EmailReplyTrimmer returning nil --- lib/gitlab/email/reply_parser.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/gitlab/email/reply_parser.rb b/lib/gitlab/email/reply_parser.rb index ed8c1cd09f8..e714923c4d8 100644 --- a/lib/gitlab/email/reply_parser.rb +++ b/lib/gitlab/email/reply_parser.rb @@ -13,7 +13,7 @@ module Gitlab encoding = body.encoding - body = EmailReplyTrimmer.trim(body) + body = EmailReplyTrimmer.trim(body) or return "" # [jneen] not using /\s+$/ here because that deletes empty lines body = body.gsub(/[ \t]$/, '') -- cgit v1.2.1 From 602c3198626ae2a23f8f2962963c18f3b3bf1664 Mon Sep 17 00:00:00 2001 From: "http://jneen.net/" Date: Tue, 22 Nov 2016 15:25:09 +0900 Subject: allow empty-quotes --- lib/gitlab/email/reply_parser.rb | 4 ---- 1 file changed, 4 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/email/reply_parser.rb b/lib/gitlab/email/reply_parser.rb index e714923c4d8..5957cbbad7e 100644 --- a/lib/gitlab/email/reply_parser.rb +++ b/lib/gitlab/email/reply_parser.rb @@ -18,10 +18,6 @@ module Gitlab # [jneen] not using /\s+$/ here because that deletes empty lines body = body.gsub(/[ \t]$/, '') - # TODO [jneen]: do we want to allow empty-quoting? (replies only containing a blockquote) - # EmailReplyTrimmer allows this as a special case, so we detect it manually here. - return "" if body.lines.all? { |l| l.strip.empty? || l.start_with?('>') } - body.force_encoding(encoding).encode("UTF-8") end -- cgit v1.2.1 From 56031276993347a7fba542c67c640fdae79df716 Mon Sep 17 00:00:00 2001 From: "http://jneen.net/" Date: Tue, 22 Nov 2016 15:37:30 +0900 Subject: remove comment attribution --- lib/gitlab/email/reply_parser.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/gitlab/email/reply_parser.rb b/lib/gitlab/email/reply_parser.rb index 5957cbbad7e..96d0a4f5153 100644 --- a/lib/gitlab/email/reply_parser.rb +++ b/lib/gitlab/email/reply_parser.rb @@ -15,7 +15,7 @@ module Gitlab body = EmailReplyTrimmer.trim(body) or return "" - # [jneen] not using /\s+$/ here because that deletes empty lines + # not using /\s+$/ here because that deletes empty lines body = body.gsub(/[ \t]$/, '') body.force_encoding(encoding).encode("UTF-8") -- cgit v1.2.1 From f02f238d52f061ee386438fb8bbe14b379e41f42 Mon Sep 17 00:00:00 2001 From: "http://jneen.net/" Date: Tue, 13 Dec 2016 12:14:38 -0800 Subject: Revert "allow empty-quotes" This reverts commit 4f2f678aff8d7dfcac96c47cf7eb480a5707ddaf. --- lib/gitlab/email/reply_parser.rb | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib') diff --git a/lib/gitlab/email/reply_parser.rb b/lib/gitlab/email/reply_parser.rb index 96d0a4f5153..971afe4a878 100644 --- a/lib/gitlab/email/reply_parser.rb +++ b/lib/gitlab/email/reply_parser.rb @@ -18,6 +18,10 @@ module Gitlab # not using /\s+$/ here because that deletes empty lines body = body.gsub(/[ \t]$/, '') + # TODO [jneen]: do we want to allow empty-quoting? (replies only containing a blockquote) + # EmailReplyTrimmer allows this as a special case, so we detect it manually here. + return "" if body.lines.all? { |l| l.strip.empty? || l.start_with?('>') } + body.force_encoding(encoding).encode("UTF-8") end -- cgit v1.2.1 From 1b8a576d3fe9d283ad20ebb863bd11ec58eb5fb5 Mon Sep 17 00:00:00 2001 From: "http://jneen.net/" Date: Tue, 13 Dec 2016 12:15:42 -0800 Subject: Be more certain in the comment --- lib/gitlab/email/reply_parser.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/email/reply_parser.rb b/lib/gitlab/email/reply_parser.rb index 971afe4a878..7dedd5ec4aa 100644 --- a/lib/gitlab/email/reply_parser.rb +++ b/lib/gitlab/email/reply_parser.rb @@ -18,8 +18,9 @@ module Gitlab # not using /\s+$/ here because that deletes empty lines body = body.gsub(/[ \t]$/, '') - # TODO [jneen]: do we want to allow empty-quoting? (replies only containing a blockquote) - # EmailReplyTrimmer allows this as a special case, so we detect it manually here. + # NOTE: We currently don't support empty quotes. + # EmailReplyTrimmer allows this as a special case, + # so we detect it manually here. return "" if body.lines.all? { |l| l.strip.empty? || l.start_with?('>') } body.force_encoding(encoding).encode("UTF-8") -- cgit v1.2.1 From 7218daaa96badbaadf6e94b6729a74a15273935d Mon Sep 17 00:00:00 2001 From: "http://jneen.net/" Date: Thu, 22 Dec 2016 00:10:35 -0800 Subject: fix guard style --- lib/gitlab/email/reply_parser.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/gitlab/email/reply_parser.rb b/lib/gitlab/email/reply_parser.rb index 7dedd5ec4aa..8c8dd1b9cef 100644 --- a/lib/gitlab/email/reply_parser.rb +++ b/lib/gitlab/email/reply_parser.rb @@ -13,7 +13,9 @@ module Gitlab encoding = body.encoding - body = EmailReplyTrimmer.trim(body) or return "" + body = EmailReplyTrimmer.trim(body) + + return '' unless body # not using /\s+$/ here because that deletes empty lines body = body.gsub(/[ \t]$/, '') -- cgit v1.2.1 From db8ee6672cf49a2eed4e244080246f21a9e14dd9 Mon Sep 17 00:00:00 2001 From: Adam Niedzielski Date: Fri, 23 Dec 2016 11:08:09 +0100 Subject: Rename "autodeploy" to "auto deploy" --- lib/gitlab/template/gitlab_ci_yml_template.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/template/gitlab_ci_yml_template.rb b/lib/gitlab/template/gitlab_ci_yml_template.rb index d19b0a52043..9d2ecee9756 100644 --- a/lib/gitlab/template/gitlab_ci_yml_template.rb +++ b/lib/gitlab/template/gitlab_ci_yml_template.rb @@ -15,7 +15,7 @@ module Gitlab { 'General' => '', 'Pages' => 'Pages', - 'Autodeploy' => 'autodeploy' + 'Auto deploy' => 'autodeploy' } end @@ -28,7 +28,7 @@ module Gitlab end def dropdown_names(context) - categories = context == 'autodeploy' ? ['Autodeploy'] : ['General', 'Pages'] + categories = context == 'autodeploy' ? ['Auto deploy'] : ['General', 'Pages'] super().slice(*categories) end end -- cgit v1.2.1 From 1b109c99a4802e2cc6598d19248013c0dc152d7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Fri, 23 Dec 2016 17:03:25 +0100 Subject: Fix a Grape deprecation, use `#request_method` instead of `#route_method` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- lib/api/helpers.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 4be659fc20b..151d7400549 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -96,7 +96,7 @@ module API end def authenticate_non_get! - authenticate! unless %w[GET HEAD].include?(route.route_method) + authenticate! unless %w[GET HEAD].include?(route.request_method) end def authenticate_by_gitlab_shell_token! -- cgit v1.2.1 From 1e5e56c698740e049a3fcf7b578ac006d5deef42 Mon Sep 17 00:00:00 2001 From: Sean McGivern Date: Mon, 26 Dec 2016 15:03:05 +0000 Subject: Fix MR with files hidden by .gitattributes Don't try to highlight and cache files hidden by .gitattributes entries. --- lib/gitlab/diff/file_collection/merge_request_diff.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/gitlab/diff/file_collection/merge_request_diff.rb b/lib/gitlab/diff/file_collection/merge_request_diff.rb index 56530448f36..329d12f13d1 100644 --- a/lib/gitlab/diff/file_collection/merge_request_diff.rb +++ b/lib/gitlab/diff/file_collection/merge_request_diff.rb @@ -61,7 +61,10 @@ module Gitlab end def cacheable?(diff_file) - @merge_request_diff.present? && diff_file.blob && diff_file.blob.text? + @merge_request_diff.present? && + diff_file.blob && + diff_file.blob.text? && + @project.repository.diffable?(diff_file.blob) end def cache_key -- cgit v1.2.1 From 2ac92662ea1577f4a71751ded4dafbd90d74bd2b Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Wed, 28 Dec 2016 12:40:39 +0100 Subject: Parameter already enforced via grape --- lib/api/notes.rb | 2 -- 1 file changed, 2 deletions(-) (limited to 'lib') diff --git a/lib/api/notes.rb b/lib/api/notes.rb index d0faf17714b..284e4cf549a 100644 --- a/lib/api/notes.rb +++ b/lib/api/notes.rb @@ -69,8 +69,6 @@ module API optional :created_at, type: String, desc: 'The creation date of the note' end post ":id/#{noteables_str}/:noteable_id/notes" do - required_attributes! [:body] - opts = { note: params[:body], noteable_type: noteables_str.classify, -- cgit v1.2.1 From ec7485de216695b53c26fb36fedba9f7d702acaa Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Tue, 13 Dec 2016 09:00:41 +0100 Subject: Grapify the settings API --- lib/api/settings.rb | 118 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 106 insertions(+), 12 deletions(-) (limited to 'lib') diff --git a/lib/api/settings.rb b/lib/api/settings.rb index c4cb1c7924a..9eb9a105bde 100644 --- a/lib/api/settings.rb +++ b/lib/api/settings.rb @@ -9,23 +9,117 @@ module API end end - # Get current applicaiton settings - # - # Example Request: - # GET /application/settings + desc 'Get the current application settings' do + success Entities::ApplicationSetting + end get "application/settings" do present current_settings, with: Entities::ApplicationSetting end - # Modify application settings - # - # Example Request: - # PUT /application/settings + desc 'Modify application settings' do + success Entities::ApplicationSetting + end + params do + optional :default_branch_protection, type: Integer, values: [0, 1, 2], desc: 'Determine if developers can push to master' + optional :default_project_visibility, type: Integer, values: Gitlab::VisibilityLevel.values, desc: 'The default project visibility' + optional :default_snippet_visibility, type: Integer, values: Gitlab::VisibilityLevel.values, desc: 'The default snippet visibility' + optional :default_group_visibility, type: Integer, values: Gitlab::VisibilityLevel.values, desc: 'The default group visibility' + optional :restricted_visibility_levels, type: Array[String], desc: 'Selected levels cannot be used by non-admin users for projects or snippets. If the public level is restricted, user profiles are only visible to logged in users.' + optional :import_sources, type: Array[String], values: %w[github bitbucket gitlab google_code fogbugz git gitlab_project], + desc: 'Enabled sources for code import during project creation. OmniAuth must be configured for GitHub, Bitbucket, and GitLab.com' + optional :disabled_oauth_sign_in_sources, type: Array[String], desc: 'Disable certain OAuth sign-in sources' + optional :enabled_git_access_protocol, type: String, values: %w[ssh http nil], desc: 'Allow only the selected protocols to be used for Git access.' + optional :gravatar_enabled, type: Boolean, desc: 'Flag indicating if the Gravatar service is enabled' + optional :default_projects_limit, type: Integer, desc: 'The maximum number of personal projects' + optional :max_attachment_size, type: Integer, desc: 'Maximum attachment size in MB' + optional :session_expire_delay, type: Integer, desc: 'Session duration in minutes. GitLab restart is required to apply changes.' + optional :user_oauth_applications, type: Boolean, desc: 'Allow users to register any application to use GitLab as an OAuth provider' + optional :user_default_external, type: Boolean, desc: 'Newly registered users will by default be external' + optional :signup_enabled, type: Boolean, desc: 'Flag indicating if sign up is enabled' + optional :send_user_confirmation_email, type: Boolean, desc: 'Send confirmation email on sign-up' + optional :domain_whitelist, type: String, desc: 'ONLY users with e-mail addresses that match these domain(s) will be able to sign-up. Wildcards allowed. Use separate lines for multiple entries. Ex: domain.com, *.domain.com' + optional :domain_blacklist_enabled, type: Boolean, desc: 'Enable domain blacklist for sign ups' + given domain_blacklist_enabled: ->(val) { val } do + requires :domain_blacklist, type: String, desc: 'Users with e-mail addresses that match these domain(s) will NOT be able to sign-up. Wildcards allowed. Use separate lines for multiple entries. Ex: domain.com, *.domain.com' + end + optional :after_sign_up_text, type: String, desc: 'Text shown after sign up' + optional :signin_enabled, type: Boolean, desc: 'Flag indicating if sign in is enabled' + optional :require_two_factor_authentication, type: Boolean, desc: 'Require all users to setup Two-factor authentication' + given require_two_factor_authentication: ->(val) { val } do + requires :two_factor_grace_period, type: Integer, desc: 'Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication' + end + optional :home_page_url, type: String, desc: 'We will redirect non-logged in users to this page' + optional :after_sign_out_path, type: String, desc: 'We will redirect users to this page after they sign out' + optional :sign_in_text, type: String, desc: 'The sign in text of the GitLab application' + optional :help_page_text, type: String, desc: 'Custom text displayed on the help page' + optional :shared_runners_enabled, type: Boolean, desc: 'Enable shared runners for new projects' + given shared_runners_enabled: ->(val) { val } do + requires :shared_runners_text, type: String, desc: 'Shared runners text ' + end + optional :max_artifacts_size, type: Integer, desc: "Set the maximum file size each build's artifacts can have" + optional :container_registry_token_expire_delay, type: Integer, desc: 'Authorization token duration (minutes)' + optional :metrics_enabled, type: Boolean, desc: 'Enable the InfluxDB metrics' + given metrics_enabled: ->(val) { val } do + requires :metrics_host, type: String, desc: 'The InfluxDB host' + requires :metrics_port, type: Integer, desc: 'The UDP port to use for connecting to InfluxDB' + requires :metrics_pool_size, type: Integer, desc: 'The amount of InfluxDB connections to open' + requires :metrics_timeout, type: Integer, desc: 'The amount of seconds after which an InfluxDB connection will time out' + requires :metrics_method_call_threshold, type: Integer, desc: 'A method call is only tracked when it takes longer to complete than the given amount of milliseconds.' + requires :metrics_sample_interval, type: Integer, desc: 'The sampling interval in seconds' + requires :metrics_packet_size, type: Integer, desc: 'The amount of points to store in a single UDP packet' + end + optional :sidekiq_throttling_enabled, type: Boolean, desc: 'Enable Sidekiq Job Throttling' + given sidekiq_throttling_enabled: ->(val) { val } do + requires :sidekiq_throttling_queus, type: Array[String], desc: 'Choose which queues you wish to throttle' + requires :sidekiq_throttling_factor, type: Float, desc: 'The factor by which the queues should be throttled. A value between 0.0 and 1.0, exclusive.' + end + optional :recaptcha_enabled, type: Boolean, desc: 'Helps prevent bots from creating accounts' + given recaptcha_enabled: ->(val) { val } do + requires :recaptcha_site_key, type: String, desc: 'Generate site key at http://www.google.com/recaptcha' + requires :recaptcha_private_key, type: String, desc: 'Generate private key at http://www.google.com/recaptcha' + end + optional :akismet_enabled, type: Boolean, desc: 'Helps prevent bots from creating issues' + given akismet_enabled: ->(val) { val } do + requires :akismet_api_key, type: String, desc: 'Generate API key at http://www.akismet.com' + end + optional :admin_notification_email, type: String, desc: 'Abuse reports will be sent to this address if it is set. Abuse reports are always available in the admin area.' + optional :sentry_enabled, type: Boolean, desc: 'Sentry is an error reporting and logging tool which is currently not shipped with GitLab, get it here: https://getsentry.com' + given sentry_enabled: ->(val) { val } do + requires :sentry_dsn, type: String, desc: 'Sentry Data Source Name' + end + optional :repository_storage, type: String, desc: 'Storage paths for new projects' + optional :repository_checks_enabled, type: Boolean, desc: "GitLab will periodically run 'git fsck' in all project and wiki repositories to look for silent disk corruption issues." + optional :koding_enabled, type: Boolean, desc: 'Enable Koding' + given koding_enabled: ->(val) { val } do + requires :koding_url, type: String, desc: 'The Koding team URL' + end + optional :version_check_enabled, type: Boolean, desc: 'Let GitLab inform you when an update is available.' + optional :email_author_in_body, type: Boolean, desc: 'Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead.' + optional :html_emails_enabled, type: Boolean, desc: 'By default GitLab sends emails in HTML and plain text formats so mail clients can choose what format to use. Disable this option if you only want to send emails in plain text format.' + optional :housekeeping_enabled, type: Boolean, desc: 'Enable automatic repository housekeeping (git repack, git gc)' + given housekeeping_enabled: ->(val) { val } do + requires :housekeeping_bitmaps_enabled, type: Boolean, desc: "Creating pack file bitmaps makes housekeeping take a little longer but bitmaps should accelerate 'git clone' performance." + requires :housekeeping_incremental_repack_period, type: Integer, desc: "Number of Git pushes after which an incremental 'git repack' is run." + requires :housekeeping_full_repack_period, type: Integer, desc: "Number of Git pushes after which a full 'git repack' is run." + requires :housekeeping_gc_period, type: Integer, desc: "Number of Git pushes after which 'git gc' is run." + end + at_least_one_of :default_branch_protection, :default_project_visibility, :default_snippet_visibility, + :default_group_visibility, :restricted_visibility_levels, :import_sources, + :enabled_git_access_protocol, :gravatar_enabled, :default_projects_limit, + :max_attachment_size, :session_expire_delay, :disabled_oauth_sign_in_sources, + :user_oauth_applications, :user_default_external, :signup_enabled, + :send_user_confirmation_email, :domain_whitelist, :domain_blacklist_enabled, + :after_sign_up_text, :signin_enabled, :require_two_factor_authentication, + :home_page_url, :after_sign_out_path, :sign_in_text, :help_page_text, + :shared_runners_enabled, :max_artifacts_size, :container_registry_token_expire_delay, + :metrics_enabled, :sidekiq_throttling_enabled, :recaptcha_enabled, + :akismet_enabled, :admin_notification_email, :sentry_enabled, + :repository_storage, :repository_checks_enabled, :koding_enabled, + :version_check_enabled, :email_author_in_body, :html_emails_enabled, + :housekeeping_enabled + end put "application/settings" do - attributes = ["repository_storage"] + current_settings.attributes.keys - ["id"] - attrs = attributes_for_keys(attributes) - - if current_settings.update_attributes(attrs) + if current_settings.update_attributes(declared_params(include_missing: false)) present current_settings, with: Entities::ApplicationSetting else render_validation_error!(current_settings) -- cgit v1.2.1