debian-mirror-gitlab/lib/gitlab/lfs_token.rb

111 lines
2.7 KiB
Ruby
Raw Permalink Normal View History

2018-12-13 13:39:08 +05:30
# frozen_string_literal: true
2016-09-29 09:46:39 +05:30
module Gitlab
class LfsToken
2019-02-15 15:39:39 +05:30
module LfsTokenHelper
def user?
actor.is_a?(User)
end
def actor_name
user? ? actor.username : "lfs+deploy-key-#{actor.id}"
end
end
include LfsTokenHelper
2016-09-29 09:46:39 +05:30
2020-06-23 00:09:42 +05:30
DEFAULT_EXPIRE_TIME = 7200 # Default value 2 hours
2019-02-15 15:39:39 +05:30
attr_accessor :actor
2019-01-03 12:48:30 +05:30
2016-09-29 09:46:39 +05:30
def initialize(actor)
@actor =
case actor
when DeployKey, User
actor
when Key
actor.user
else
raise 'Bad Actor'
end
end
2019-07-07 11:18:12 +05:30
def token
HMACToken.new(actor).token(DEFAULT_EXPIRE_TIME)
2019-02-15 15:39:39 +05:30
end
2016-09-29 09:46:39 +05:30
2019-12-21 20:55:43 +05:30
# When the token is an lfs one and the actor
# is blocked or the password has been changed,
# the token is no longer valid
2019-02-15 15:39:39 +05:30
def token_valid?(token_to_check)
2019-12-21 20:55:43 +05:30
HMACToken.new(actor).token_valid?(token_to_check) && valid_user?
2016-09-29 09:46:39 +05:30
end
2018-03-17 18:26:18 +05:30
def deploy_key_pushable?(project)
actor.is_a?(DeployKey) && actor.can_push_to?(project)
end
2019-01-03 12:48:30 +05:30
def type
2019-02-15 15:39:39 +05:30
user? ? :lfs_token : :lfs_deploy_token
2016-09-29 09:46:39 +05:30
end
2019-12-21 20:55:43 +05:30
def valid_user?
return true unless user?
2021-07-02 01:05:55 +05:30
!actor.blocked? && !actor.password_expired_if_applicable?
2019-12-21 20:55:43 +05:30
end
2019-07-07 11:18:12 +05:30
def authentication_payload(repository_http_path)
{
username: actor_name,
lfs_token: token,
repository_http_path: repository_http_path,
expires_in: DEFAULT_EXPIRE_TIME
}
end
2019-12-21 20:55:43 +05:30
def basic_encoding
ActionController::HttpAuthentication::Basic.encode_credentials(actor_name, token)
end
2019-03-02 22:35:43 +05:30
private # rubocop:disable Lint/UselessAccessModifier
2019-02-15 15:39:39 +05:30
class HMACToken
include LfsTokenHelper
def initialize(actor)
@actor = actor
end
def token(expire_time)
hmac_token = JSONWebToken::HMACToken.new(secret)
hmac_token.expire_time = Time.now + expire_time
hmac_token[:data] = { actor: actor_name }
hmac_token.encoded
end
def token_valid?(token_to_check)
decoded_token = JSONWebToken::HMACToken.decode(token_to_check, secret).first
decoded_token.dig('data', 'actor') == actor_name
rescue JWT::DecodeError
false
end
private
attr_reader :actor
def secret
case actor
when DeployKey, Key
2021-12-11 22:18:48 +05:30
# Since fingerprint is based on the public key, let's take more bytes from attr_encrypted_db_key_base
2022-06-21 17:19:12 +05:30
actor.fingerprint_sha256.first(16) + Settings.attr_encrypted_db_key_base_32
2019-02-15 15:39:39 +05:30
when User
# Take the last 16 characters as they're more unique than the first 16
2021-12-11 22:18:48 +05:30
actor.id.to_s + actor.encrypted_password.last(16) + Settings.attr_encrypted_db_key_base.first(16)
2019-02-15 15:39:39 +05:30
end
end
2019-01-03 12:48:30 +05:30
end
2016-09-29 09:46:39 +05:30
end
end