Module: Atlassian::Jwt

Defined in:
lib/atlassian/jwt.rb,
lib/atlassian/jwt/version.rb

Constant Summary collapse

CANONICAL_QUERY_SEPARATOR =
'&'
ESCAPED_CANONICAL_QUERY_SEPARATOR =
'%26'
VERSION =
"0.2.1"

Class Method Summary collapse

Class Method Details

.build_claims(issuer, url, http_method, base_url = '', issued_at = nil, expires = nil, attributes = {}) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/atlassian/jwt.rb', line 38

def build_claims(issuer, url, http_method, base_url = '', issued_at = nil, expires = nil, attributes = {})
  issued_at ||= Time.now.to_i
  expires ||= issued_at + 60
  qsh = Digest::SHA256.hexdigest(
    Atlassian::Jwt.create_canonical_request(url, http_method, base_url)
  )

  {
    iss: issuer,
    iat: issued_at,
    exp: expires,
    qsh: qsh
  }.merge(attributes)
end

.canonicalize_query_string(query) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/atlassian/jwt.rb', line 61

def canonicalize_query_string(query)
  return '' if query.nil? || query.empty?

  query = CGI::parse(query)
  query.delete('jwt')
  query.each do |k, v|
    query[k] = v.map { |a| CGI.escape a }.join(',') if v.is_a? Array
    query[k].gsub!('+', '%20')  # Use %20, not CGI.escape default of "+"
    query[k].gsub!('%7E', '~')  # Unescape "~" per JS tests
  end
  query = Hash[query.sort]
  query.map { |k,v| "#{CGI.escape k}=#{v}" }.join(CANONICAL_QUERY_SEPARATOR)
end

.canonicalize_uri(uri, base_uri) ⇒ Object



53
54
55
56
57
58
59
# File 'lib/atlassian/jwt.rb', line 53

def canonicalize_uri(uri, base_uri)
  path = uri.path.sub(/^#{base_uri.path}/, '')
  path = '/' if path.nil? || path.empty?
  path = '/' + path unless path.start_with? '/'
  path.chomp!('/') if path.length > 1
  path.gsub(CANONICAL_QUERY_SEPARATOR, ESCAPED_CANONICAL_QUERY_SEPARATOR)
end

.create_canonical_request(uri, http_method, base_uri) ⇒ Object



27
28
29
30
31
32
33
34
35
36
# File 'lib/atlassian/jwt.rb', line 27

def create_canonical_request(uri, http_method, base_uri)
  uri = URI.parse(uri) unless uri.kind_of? URI
  base_uri = URI.parse(base_uri) unless base_uri.kind_of? URI

  [
    http_method.upcase,
    canonicalize_uri(uri, base_uri),
    canonicalize_query_string(uri.query)
  ].join(CANONICAL_QUERY_SEPARATOR)
end

.create_query_string_hash(uri, http_method, base_uri) ⇒ Object



21
22
23
24
25
# File 'lib/atlassian/jwt.rb', line 21

def create_query_string_hash(uri, http_method, base_uri)
  Digest::SHA256.hexdigest(
    create_canonical_request(uri, http_method, base_uri)
  )
end

.decode(token, secret, validate = true, options = {}) ⇒ Object



12
13
14
15
# File 'lib/atlassian/jwt.rb', line 12

def decode(token, secret, validate = true, options = {})
  options = {:algorithm => 'HS256'}.merge(options)
  ::JWT.decode(token, secret, validate, options)
end

.encode(payload, secret, algorithm = 'HS256', header_fields = {}) ⇒ Object



17
18
19
# File 'lib/atlassian/jwt.rb', line 17

def encode(payload, secret, algorithm = 'HS256', header_fields = {})
  ::JWT.encode(payload, secret, algorithm, header_fields)
end