mirror of
https://gitlab.com/gitlab-org/gitlab-foss.git
synced 2025-08-06 10:19:48 +00:00
53 lines
1001 B
Ruby
53 lines
1001 B
Ruby
# frozen_string_literal: true
|
|
|
|
module JSONWebToken
|
|
class RSAToken < Token
|
|
ALGORITHM = 'RS256'
|
|
|
|
attr_reader :key_file
|
|
|
|
def initialize(key_file)
|
|
super()
|
|
@key_file = key_file
|
|
end
|
|
|
|
def encoded
|
|
self.class.encode(payload, key, kid)
|
|
end
|
|
|
|
def self.encode(payload, key, kid)
|
|
headers = { kid: kid, typ: 'JWT' }
|
|
JWT.encode(payload, key, ALGORITHM, headers)
|
|
end
|
|
|
|
def self.decode(token, key)
|
|
JWT.decode(token, key, true, { algorithm: ALGORITHM })
|
|
end
|
|
|
|
private
|
|
|
|
def key_data
|
|
@key_data ||= File.read(key_file)
|
|
end
|
|
|
|
def key
|
|
@key ||= OpenSSL::PKey::RSA.new(key_data)
|
|
end
|
|
|
|
def public_key
|
|
key.public_key
|
|
end
|
|
|
|
def kid
|
|
# calculate sha256 from DER encoded ASN1
|
|
kid = Digest::SHA256.digest(public_key.to_der)
|
|
|
|
# we encode only 30 bytes with base32
|
|
kid = Base32.encode(kid[0..29])
|
|
|
|
# insert colon every 4 characters
|
|
kid.scan(/.{4}/).join(':')
|
|
end
|
|
end
|
|
end
|