summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorShinya Maeda <shinya@gitlab.com>2018-05-01 14:21:36 +0900
committerShinya Maeda <shinya@gitlab.com>2018-05-01 14:21:36 +0900
commitb9cc1188a98f6fef103f0b6553bc6783bcf95fc1 (patch)
treef9ea42c5891a247e7a647d367e43883823358ce3 /lib
parentddd6b21b794250b9a74872b7646459251df9cd40 (diff)
parent54695563ca3b37f09b625c4c6798e41a0e629c0b (diff)
downloadgitlab-ce-b9cc1188a98f6fef103f0b6553bc6783bcf95fc1.tar.gz
Merge branch 'live-trace-v2' into live-trace-v2-efficient-destroy-all
Diffstat (limited to 'lib')
-rw-r--r--lib/gitlab/base_doorkeeper_controller.rb8
-rw-r--r--lib/gitlab/git/remote_repository.rb7
-rw-r--r--lib/gitlab/git/repository.rb53
-rw-r--r--lib/gitlab/gitaly_client/repository_service.rb4
-rw-r--r--lib/omni_auth/strategies/jwt.rb62
5 files changed, 115 insertions, 19 deletions
diff --git a/lib/gitlab/base_doorkeeper_controller.rb b/lib/gitlab/base_doorkeeper_controller.rb
new file mode 100644
index 00000000000..e4227af25d2
--- /dev/null
+++ b/lib/gitlab/base_doorkeeper_controller.rb
@@ -0,0 +1,8 @@
+# This is a base controller for doorkeeper.
+# It adds the `can?` helper used in the views.
+module Gitlab
+ class BaseDoorkeeperController < ActionController::Base
+ include Gitlab::Allowable
+ helper_method :can?
+ end
+end
diff --git a/lib/gitlab/git/remote_repository.rb b/lib/gitlab/git/remote_repository.rb
index 6bd6e58feeb..f40e59a8dd0 100644
--- a/lib/gitlab/git/remote_repository.rb
+++ b/lib/gitlab/git/remote_repository.rb
@@ -12,7 +12,7 @@ module Gitlab
# class.
#
class RemoteRepository
- attr_reader :path, :relative_path, :gitaly_repository
+ attr_reader :relative_path, :gitaly_repository
def initialize(repository)
@relative_path = repository.relative_path
@@ -21,7 +21,6 @@ module Gitlab
# These instance variables will not be available in gitaly-ruby, where
# we have no disk access to this repository.
@repository = repository
- @path = repository.path
end
def empty?
@@ -69,6 +68,10 @@ module Gitlab
env
end
+ def path
+ @repository.path
+ end
+
private
# Must return an object that responds to 'address' and 'storage'.
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
index 0d07fb85213..de0044fc149 100644
--- a/lib/gitlab/git/repository.rb
+++ b/lib/gitlab/git/repository.rb
@@ -391,18 +391,6 @@ module Gitlab
nil
end
- def archive_prefix(ref, sha, append_sha:)
- append_sha = (ref != sha) if append_sha.nil?
-
- project_name = self.name.chomp('.git')
- formatted_ref = ref.tr('/', '-')
-
- prefix_segments = [project_name, formatted_ref]
- prefix_segments << sha if append_sha
-
- prefix_segments.join('-')
- end
-
def archive_metadata(ref, storage_path, format = "tar.gz", append_sha:)
ref ||= root_ref
commit = Gitlab::Git::Commit.find(self, ref)
@@ -413,12 +401,44 @@ module Gitlab
{
'RepoPath' => path,
'ArchivePrefix' => prefix,
- 'ArchivePath' => archive_file_path(prefix, storage_path, format),
+ 'ArchivePath' => archive_file_path(storage_path, commit.id, prefix, format),
'CommitId' => commit.id
}
end
- def archive_file_path(name, storage_path, format = "tar.gz")
+ # This is both the filename of the archive (missing the extension) and the
+ # name of the top-level member of the archive under which all files go
+ #
+ # FIXME: The generated prefix is incorrect for projects with hashed
+ # storage enabled
+ def archive_prefix(ref, sha, append_sha:)
+ append_sha = (ref != sha) if append_sha.nil?
+
+ project_name = self.name.chomp('.git')
+ formatted_ref = ref.tr('/', '-')
+
+ prefix_segments = [project_name, formatted_ref]
+ prefix_segments << sha if append_sha
+
+ prefix_segments.join('-')
+ end
+ private :archive_prefix
+
+ # The full path on disk where the archive should be stored. This is used
+ # to cache the archive between requests.
+ #
+ # The path is a global namespace, so needs to be globally unique. This is
+ # achieved by including `gl_repository` in the path.
+ #
+ # Archives relating to a particular ref when the SHA is not present in the
+ # filename must be invalidated when the ref is updated to point to a new
+ # SHA. This is achieved by including the SHA in the path.
+ #
+ # As this is a full path on disk, it is not "cloud native". This should
+ # be resolved by either removing the cache, or moving the implementation
+ # into Gitaly and removing the ArchivePath parameter from the git-archive
+ # senddata response.
+ def archive_file_path(storage_path, sha, name, format = "tar.gz")
# Build file path
return nil unless name
@@ -436,8 +456,9 @@ module Gitlab
end
file_name = "#{name}.#{extension}"
- File.join(storage_path, self.name, file_name)
+ File.join(storage_path, self.gl_repository, sha, file_name)
end
+ private :archive_file_path
# Return repo size in megabytes
def size
@@ -1179,6 +1200,8 @@ module Gitlab
if is_enabled
gitaly_fetch_ref(source_repository, source_ref: source_ref, target_ref: target_ref)
else
+ # When removing this code, also remove source_repository#path
+ # to remove deprecated method calls
local_fetch_ref(source_repository.path, source_ref: source_ref, target_ref: target_ref)
end
end
diff --git a/lib/gitlab/gitaly_client/repository_service.rb b/lib/gitlab/gitaly_client/repository_service.rb
index bf5a491e28d..498187997e1 100644
--- a/lib/gitlab/gitaly_client/repository_service.rb
+++ b/lib/gitlab/gitaly_client/repository_service.rb
@@ -142,7 +142,7 @@ module Gitlab
:repository_service,
:is_rebase_in_progress,
request,
- timeout: GitalyClient.default_timeout
+ timeout: GitalyClient.fast_timeout
)
response.in_progress
@@ -159,7 +159,7 @@ module Gitlab
:repository_service,
:is_squash_in_progress,
request,
- timeout: GitalyClient.default_timeout
+ timeout: GitalyClient.fast_timeout
)
response.in_progress
diff --git a/lib/omni_auth/strategies/jwt.rb b/lib/omni_auth/strategies/jwt.rb
new file mode 100644
index 00000000000..2349b2a28aa
--- /dev/null
+++ b/lib/omni_auth/strategies/jwt.rb
@@ -0,0 +1,62 @@
+require 'omniauth'
+require 'jwt'
+
+module OmniAuth
+ module Strategies
+ class JWT
+ ClaimInvalid = Class.new(StandardError)
+
+ include OmniAuth::Strategy
+
+ args [:secret]
+
+ option :secret, nil
+ option :algorithm, 'HS256'
+ option :uid_claim, 'email'
+ option :required_claims, %w(name email)
+ option :info_map, { name: "name", email: "email" }
+ option :auth_url, nil
+ option :valid_within, nil
+
+ uid { decoded[options.uid_claim] }
+
+ extra do
+ { raw_info: decoded }
+ end
+
+ info do
+ options.info_map.each_with_object({}) do |(k, v), h|
+ h[k.to_s] = decoded[v.to_s]
+ end
+ end
+
+ def request_phase
+ redirect options.auth_url
+ end
+
+ def decoded
+ @decoded ||= ::JWT.decode(request.params['jwt'], options.secret, options.algorithm).first
+
+ (options.required_claims || []).each do |field|
+ raise ClaimInvalid, "Missing required '#{field}' claim" unless @decoded.key?(field.to_s)
+ end
+
+ raise ClaimInvalid, "Missing required 'iat' claim" if options.valid_within && !@decoded["iat"]
+
+ if options.valid_within && (Time.now.to_i - @decoded["iat"]).abs > options.valid_within
+ raise ClaimInvalid, "'iat' timestamp claim is too skewed from present"
+ end
+
+ @decoded
+ end
+
+ def callback_phase
+ super
+ rescue ClaimInvalid => e
+ fail! :claim_invalid, e
+ end
+ end
+
+ class Jwt < JWT; end
+ end
+end