Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG1
-rw-r--r--app/assets/stylesheets/pages/projects.scss8
-rw-r--r--app/controllers/projects_controller.rb2
-rw-r--r--app/helpers/lfs_helper.rb4
-rw-r--r--app/helpers/projects_helper.rb12
-rw-r--r--app/models/project.rb7
-rw-r--r--app/views/admin/projects/show.html.haml6
-rw-r--r--app/views/projects/edit.html.haml10
-rw-r--r--db/migrate/20160823213309_add_lfs_enabled_to_projects.rb29
-rw-r--r--db/schema.rb1
-rw-r--r--doc/api/projects.md3
-rw-r--r--doc/workflow/project_features.md10
-rw-r--r--lib/api/entities.rb2
-rw-r--r--lib/api/projects.rb12
-rw-r--r--spec/requests/lfs_http_spec.rb107
15 files changed, 208 insertions, 6 deletions
diff --git a/CHANGELOG b/CHANGELOG
index c07e194358d..c8d224bb0b9 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -25,6 +25,7 @@ v 8.12.0 (unreleased)
- Add horizontal scrolling to all sub-navs on mobile viewports (ClemMakesApps)
- Fix markdown help references (ClemMakesApps)
- Add last commit time to repo view (ClemMakesApps)
+ - Added project specific enable/disable setting for LFS !5997
- Added tests for diff notes
- Add a button to download latest successful artifacts for branches and tags !5142
- Add delimiter to project stars and forks count (ClemMakesApps)
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index 83500a687bb..f2db373da52 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -311,6 +311,14 @@ a.deploy-project-label {
color: $gl-success;
}
+.lfs-enabled {
+ color: $gl-success;
+}
+
+.lfs-disabled {
+ color: $gl-warning;
+}
+
.breadcrumb.repo-breadcrumb {
padding: 0;
background: transparent;
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index fc52cd2f367..84d6b106cd7 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -309,7 +309,7 @@ class ProjectsController < Projects::ApplicationController
:issues_tracker_id, :default_branch,
:wiki_enabled, :visibility_level, :import_url, :last_activity_at, :namespace_id, :avatar,
:builds_enabled, :build_allow_git_fetch, :build_timeout_in_minutes, :build_coverage_regex,
- :public_builds, :only_allow_merge_if_build_succeeds, :request_access_enabled
+ :public_builds, :only_allow_merge_if_build_succeeds, :request_access_enabled, :lfs_enabled
)
end
diff --git a/app/helpers/lfs_helper.rb b/app/helpers/lfs_helper.rb
index eb651e3687e..5d82abfca79 100644
--- a/app/helpers/lfs_helper.rb
+++ b/app/helpers/lfs_helper.rb
@@ -23,10 +23,14 @@ module LfsHelper
end
def lfs_download_access?
+ return false unless project.lfs_enabled?
+
project.public? || ci? || (user && user.can?(:download_code, project))
end
def lfs_upload_access?
+ return false unless project.lfs_enabled?
+
user && user.can?(:push_code, project)
end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 356f27f2d5d..f07077bd133 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -187,6 +187,18 @@ module ProjectsHelper
nav_tabs.flatten
end
+ def project_lfs_status(project)
+ if project.lfs_enabled?
+ content_tag(:span, class: 'lfs-enabled') do
+ 'Enabled'
+ end
+ else
+ content_tag(:span, class: 'lfs-disabled') do
+ 'Disabled'
+ end
+ end
+ end
+
def git_user_name
if current_user
current_user.name
diff --git a/app/models/project.rb b/app/models/project.rb
index c34064f96ce..e5027af4a0e 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -390,6 +390,13 @@ class Project < ActiveRecord::Base
end
end
+ def lfs_enabled?
+ return false unless Gitlab.config.lfs.enabled
+ return Gitlab.config.lfs.enabled if self[:lfs_enabled].nil?
+
+ self[:lfs_enabled]
+ end
+
def repository_storage_path
Gitlab.config.repositories.storages[repository_storage]
end
diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml
index b2c607361b3..6c7c3c48604 100644
--- a/app/views/admin/projects/show.html.haml
+++ b/app/views/admin/projects/show.html.haml
@@ -73,6 +73,12 @@
%span.light last commit:
%strong
= last_commit(@project)
+
+ %li
+ %span.light Git LFS status:
+ %strong
+ = project_lfs_status(@project)
+ = link_to icon('question-circle'), help_page_path('workflow/lfs/manage_large_binaries_with_git_lfs')
- else
%li
%span.light repository:
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index b282aa52b25..836c6d7b83f 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -80,6 +80,16 @@
%strong Snippets
%br
%span.descr Share code pastes with others out of git repository
+ - if Gitlab.config.lfs.enabled && current_user.admin?
+ .form-group
+ .checkbox
+ = f.label :lfs_enabled do
+ = f.check_box :lfs_enabled, checked: @project.lfs_enabled?
+ %strong LFS
+ %br
+ %span.descr
+ Git Large File Storage
+ = link_to icon('question-circle'), help_page_path('workflow/lfs/manage_large_binaries_with_git_lfs')
- if Gitlab.config.registry.enabled
.form-group
.checkbox
diff --git a/db/migrate/20160823213309_add_lfs_enabled_to_projects.rb b/db/migrate/20160823213309_add_lfs_enabled_to_projects.rb
new file mode 100644
index 00000000000..c169084e976
--- /dev/null
+++ b/db/migrate/20160823213309_add_lfs_enabled_to_projects.rb
@@ -0,0 +1,29 @@
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class AddLfsEnabledToProjects < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ # Set this constant to true if this migration requires downtime.
+ DOWNTIME = false
+
+ # When a migration requires downtime you **must** uncomment the following
+ # constant and define a short and easy to understand explanation as to why the
+ # migration requires downtime.
+ # DOWNTIME_REASON = ''
+
+ # When using the methods "add_concurrent_index" or "add_column_with_default"
+ # you must disable the use of transactions as these methods can not run in an
+ # existing transaction. When using "add_concurrent_index" make sure that this
+ # method is the _only_ method called in the migration, any other changes
+ # should go in a separate migration. This ensures that upon failure _only_ the
+ # index creation fails and can be retried or reverted easily.
+ #
+ # To disable transactions uncomment the following line and remove these
+ # comments:
+ # disable_ddl_transaction!
+
+ def change
+ add_column :projects, :lfs_enabled, :boolean
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 0cd8648da2e..e1ce7085c62 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -825,6 +825,7 @@ ActiveRecord::Schema.define(version: 20160827011312) do
t.string "repository_storage", default: "default", null: false
t.boolean "request_access_enabled", default: true, null: false
t.boolean "has_external_wiki"
+ t.boolean "lfs_enabled"
end
add_index "projects", ["ci_id"], name: "index_projects_on_ci_id", using: :btree
diff --git a/doc/api/projects.md b/doc/api/projects.md
index 3136c493b48..0d5aa61aa74 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -452,6 +452,7 @@ Parameters:
- `import_url` (optional)
- `public_builds` (optional)
- `only_allow_merge_if_build_succeeds` (optional)
+- `lfs_enabled` (optional)
### Create project for user
@@ -478,6 +479,7 @@ Parameters:
- `import_url` (optional)
- `public_builds` (optional)
- `only_allow_merge_if_build_succeeds` (optional)
+- `lfs_enabled` (optional)
### Edit project
@@ -505,6 +507,7 @@ Parameters:
- `visibility_level` (optional)
- `public_builds` (optional)
- `only_allow_merge_if_build_succeeds` (optional)
+- `lfs_enabled` (optional)
On success, method returns 200 with the updated project. If parameters are
invalid, 400 is returned.
diff --git a/doc/workflow/project_features.md b/doc/workflow/project_features.md
index a523b3facbe..f19e7df8c9a 100644
--- a/doc/workflow/project_features.md
+++ b/doc/workflow/project_features.md
@@ -32,4 +32,12 @@ Snippets are little bits of code or text.
This is a nice place to put code or text that is used semi-regularly within the project, but does not belong in source control.
-For example, a specific config file that is used by > the team that is only valid for the people that work on the code.
+For example, a specific config file that is used by the team that is only valid for the people that work on the code.
+
+## Git LFS
+
+>**Note:** Project-specific LFS setting was added on 8.12 and is available only to admins.
+
+Git Large File Storage allows you to easily manage large binary files with Git.
+With this setting admins can better control which projects are allowed to use
+LFS.
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index cbb324dd06d..4335e3055ef 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -78,7 +78,7 @@ module API
expose :path, :path_with_namespace
expose :issues_enabled, :merge_requests_enabled, :wiki_enabled, :builds_enabled, :snippets_enabled, :container_registry_enabled
expose :created_at, :last_activity_at
- expose :shared_runners_enabled
+ expose :shared_runners_enabled, :lfs_enabled
expose :creator_id
expose :namespace
expose :forked_from_project, using: Entities::BasicProjectDetails, if: lambda{ |project, options| project.forked? }
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index 71efd4f33ca..f8979a1cc29 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -105,6 +105,7 @@ module API
# visibility_level (optional) - 0 by default
# import_url (optional)
# public_builds (optional)
+ # lfs_enabled (optional)
# Example Request
# POST /projects
post do
@@ -124,7 +125,8 @@ module API
:visibility_level,
:import_url,
:public_builds,
- :only_allow_merge_if_build_succeeds]
+ :only_allow_merge_if_build_succeeds,
+ :lfs_enabled]
attrs = map_public_to_visibility_level(attrs)
@project = ::Projects::CreateService.new(current_user, attrs).execute
if @project.saved?
@@ -156,6 +158,7 @@ module API
# visibility_level (optional)
# import_url (optional)
# public_builds (optional)
+ # lfs_enabled (optional)
# Example Request
# POST /projects/user/:user_id
post "user/:user_id" do
@@ -174,7 +177,8 @@ module API
:visibility_level,
:import_url,
:public_builds,
- :only_allow_merge_if_build_succeeds]
+ :only_allow_merge_if_build_succeeds,
+ :lfs_enabled]
attrs = map_public_to_visibility_level(attrs)
@project = ::Projects::CreateService.new(user, attrs).execute
if @project.saved?
@@ -220,6 +224,7 @@ module API
# public (optional) - if true same as setting visibility_level = 20
# visibility_level (optional) - visibility level of a project
# public_builds (optional)
+ # lfs_enabled (optional)
# Example Request
# PUT /projects/:id
put ':id' do
@@ -237,7 +242,8 @@ module API
:public,
:visibility_level,
:public_builds,
- :only_allow_merge_if_build_succeeds]
+ :only_allow_merge_if_build_succeeds,
+ :lfs_enabled]
attrs = map_public_to_visibility_level(attrs)
authorize_admin_project
authorize! :rename_project, user_project if attrs[:name].present?
diff --git a/spec/requests/lfs_http_spec.rb b/spec/requests/lfs_http_spec.rb
index 4c9b4a8ba42..fcd6521317a 100644
--- a/spec/requests/lfs_http_spec.rb
+++ b/spec/requests/lfs_http_spec.rb
@@ -44,6 +44,113 @@ describe 'Git LFS API and storage' do
end
end
+ context 'project specific LFS settings' do
+ let(:project) { create(:empty_project) }
+ let(:body) do
+ {
+ 'objects' => [
+ { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897',
+ 'size' => 1575078
+ },
+ { 'oid' => sample_oid,
+ 'size' => sample_size
+ }
+ ],
+ 'operation' => 'upload'
+ }
+ end
+ let(:authorization) { authorize_user }
+
+ context 'with LFS disabled globally' do
+ before do
+ project.team << [user, :master]
+ allow(Gitlab.config.lfs).to receive(:enabled).and_return(false)
+ end
+
+ describe 'LFS disabled in project' do
+ before do
+ project.update_attribute(:lfs_enabled, false)
+ end
+
+ it 'responds with a 501 message on upload' do
+ post_lfs_json "#{project.http_url_to_repo}/info/lfs/objects/batch", body, headers
+
+ expect(response).to have_http_status(501)
+ end
+
+ it 'responds with a 501 message on download' do
+ get "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", nil, headers
+
+ expect(response).to have_http_status(501)
+ end
+ end
+
+ describe 'LFS enabled in project' do
+ before do
+ project.update_attribute(:lfs_enabled, true)
+ end
+
+ it 'responds with a 501 message on upload' do
+ post_lfs_json "#{project.http_url_to_repo}/info/lfs/objects/batch", body, headers
+
+ expect(response).to have_http_status(501)
+ end
+
+ it 'responds with a 501 message on download' do
+ get "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", nil, headers
+
+ expect(response).to have_http_status(501)
+ end
+ end
+ end
+
+ context 'with LFS enabled globally' do
+ before do
+ project.team << [user, :master]
+ enable_lfs
+ end
+
+ describe 'LFS disabled in project' do
+ before do
+ project.update_attribute(:lfs_enabled, false)
+ end
+
+ it 'responds with a 403 message on upload' do
+ post_lfs_json "#{project.http_url_to_repo}/info/lfs/objects/batch", body, headers
+
+ expect(response).to have_http_status(403)
+ expect(json_response).to include('message' => 'Access forbidden. Check your access level.')
+ end
+
+ it 'responds with a 403 message on download' do
+ get "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", nil, headers
+
+ expect(response).to have_http_status(403)
+ expect(json_response).to include('message' => 'Access forbidden. Check your access level.')
+ end
+ end
+
+ describe 'LFS enabled in project' do
+ before do
+ project.update_attribute(:lfs_enabled, true)
+ end
+
+ it 'responds with a 200 message on upload' do
+ post_lfs_json "#{project.http_url_to_repo}/info/lfs/objects/batch", body, headers
+
+ expect(response).to have_http_status(200)
+ expect(json_response['objects'].first['size']).to eq(1575078)
+ end
+
+ it 'responds with a 200 message on download' do
+ get "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", nil, headers
+
+ expect(response).to have_http_status(200)
+ end
+ end
+ end
+ end
+
describe 'deprecated API' do
let(:project) { create(:empty_project) }