summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorPatricio Cano <suprnova32@gmail.com>2016-08-25 17:26:20 -0500
committerPatricio Cano <suprnova32@gmail.com>2016-09-15 12:21:00 -0500
commite40e3fdc8271d1becf7952c7e30546c5abecb79b (patch)
treed2b8ef12a133ea77c598b456d15c46ea55a1e1bd /app
parentf8bd9625f44ae4233c14e473c57becfb7ff15ca9 (diff)
downloadgitlab-ce-e40e3fdc8271d1becf7952c7e30546c5abecb79b.tar.gz
Added LFS support to SSH
- Required on the GitLab Rails side is mostly authentication and API related.
Diffstat (limited to 'app')
-rw-r--r--app/controllers/projects/git_http_client_controller.rb42
-rw-r--r--app/helpers/lfs_helper.rb2
-rw-r--r--app/models/deploy_key.rb5
-rw-r--r--app/models/user.rb3
4 files changed, 38 insertions, 14 deletions
diff --git a/app/controllers/projects/git_http_client_controller.rb b/app/controllers/projects/git_http_client_controller.rb
index f5ce63fdfed..1e6709dc8eb 100644
--- a/app/controllers/projects/git_http_client_controller.rb
+++ b/app/controllers/projects/git_http_client_controller.rb
@@ -4,6 +4,8 @@ class Projects::GitHttpClientController < Projects::ApplicationController
include ActionController::HttpAuthentication::Basic
include KerberosSpnegoHelper
+ class MissingPersonalTokenError < StandardError; end
+
attr_reader :user
# Git clients will not know what authenticity token to send along
@@ -21,18 +23,8 @@ class Projects::GitHttpClientController < Projects::ApplicationController
if allow_basic_auth? && basic_auth_provided?
login, password = user_name_and_password(request)
- auth_result = Gitlab::Auth.find_for_git_client(login, password, project: project, ip: request.ip)
-
- if auth_result.type == :ci && download_request?
- @ci = true
- elsif auth_result.type == :oauth && !download_request?
- # Not allowed
- elsif auth_result.type == :missing_personal_token
- render_missing_personal_token
- return # Render above denied access, nothing left to do
- else
- @user = auth_result.user
- end
+
+ handle_authentication(login, password)
if ci? || user
return # Allow access
@@ -48,6 +40,10 @@ class Projects::GitHttpClientController < Projects::ApplicationController
send_challenges
render plain: "HTTP Basic: Access denied\n", status: 401
+
+ rescue MissingPersonalTokenError
+ render_missing_personal_token
+ return
end
def basic_auth_provided?
@@ -118,6 +114,28 @@ class Projects::GitHttpClientController < Projects::ApplicationController
@ci.present?
end
+ def handle_authentication(login, password)
+ auth_result = Gitlab::Auth.find_for_git_client(login, password, project: project, ip: request.ip)
+
+ if auth_result.type == :ci && download_request?
+ @ci = true
+ elsif auth_result.type == :oauth && !download_request?
+ # Not allowed
+ elsif auth_result.type == :missing_personal_token
+ raise MissingPersonalTokenError
+ elsif auth_result.type == :lfs_deploy_token && download_request?
+ @lfs_deploy_key = true
+ @user = auth_result.user
+ else
+ @user = auth_result.user
+ end
+ end
+
+ def lfs_deploy_key?
+ key = user
+ @lfs_deploy_key.present? && (key && key.projects.include?(project))
+ end
+
def verify_workhorse_api!
Gitlab::Workhorse.verify_api_request!(request.headers)
end
diff --git a/app/helpers/lfs_helper.rb b/app/helpers/lfs_helper.rb
index 5d82abfca79..0c867fc8741 100644
--- a/app/helpers/lfs_helper.rb
+++ b/app/helpers/lfs_helper.rb
@@ -25,7 +25,7 @@ module LfsHelper
def lfs_download_access?
return false unless project.lfs_enabled?
- project.public? || ci? || (user && user.can?(:download_code, project))
+ project.public? || ci? || lfs_deploy_key? || (user && user.can?(:download_code, project))
end
def lfs_upload_access?
diff --git a/app/models/deploy_key.rb b/app/models/deploy_key.rb
index 2c525d4cd7a..de51b63c120 100644
--- a/app/models/deploy_key.rb
+++ b/app/models/deploy_key.rb
@@ -1,7 +1,12 @@
class DeployKey < Key
+ include TokenAuthenticatable
+ add_authentication_token_field :lfs_token
+
has_many :deploy_keys_projects, dependent: :destroy
has_many :projects, through: :deploy_keys_projects
+ before_save :ensure_lfs_token
+
scope :in_projects, ->(projects) { joins(:deploy_keys_projects).where('deploy_keys_projects.project_id in (?)', projects) }
scope :are_public, -> { where(public: true) }
diff --git a/app/models/user.rb b/app/models/user.rb
index 6996740eebd..94ae3911859 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -13,6 +13,7 @@ class User < ActiveRecord::Base
DEFAULT_NOTIFICATION_LEVEL = :participating
add_authentication_token_field :authentication_token
+ add_authentication_token_field :lfs_token
default_value_for :admin, false
default_value_for(:external) { current_application_settings.user_default_external }
@@ -117,7 +118,7 @@ class User < ActiveRecord::Base
before_validation :set_public_email, if: ->(user) { user.public_email_changed? }
after_update :update_emails_with_primary_email, if: ->(user) { user.email_changed? }
- before_save :ensure_authentication_token
+ before_save :ensure_authentication_token, :ensure_lfs_token
before_save :ensure_external_user_rights
after_save :ensure_namespace_correct
after_initialize :set_projects_limit