Class: Tep::AuthBearerToken

Inherits:
Object
  • Object
show all
Defined in:
lib/tep/auth_bearer_token.rb

Class Method Summary collapse

Class Method Details

.parse_caps(s) ⇒ Object

“read,write,post_summary” -> [:read, :write, :post_summary]



87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/tep/auth_bearer_token.rb', line 87

def self.parse_caps(s)
  caps = [:_seed]
  caps.delete_at(0)
  if s.length == 0
    return caps
  end
  s.split(",").each do |name|
    if name.length > 0
      caps.push(name.to_sym)
    end
  end
  caps
end

.parse_delegate(s) ⇒ Object

“agent_id|issued_at|expires_at|origin” -> AgentDelegation, or nil for empty / malformed. The four-segment pipe encoding avoids the nested-JSON limitation; pipes don’t appear in agent ids (we constrain the issuance side).

‘.to_s` on parts is a no-op type-witness for spinel: without it the inference for the first AgentDelegation arg widens to mrb_int in some larger-codebase compile paths (no other call site constrains agent_id to a String), and the generated C compares pointer-to-int.



111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/tep/auth_bearer_token.rb', line 111

def self.parse_delegate(s)
  if s.length == 0
    return nil
  end
  parts = s.split("|")
  if parts.length < 4
    return nil
  end
  agent_id   = parts[0].to_s
  issued_at  = parts[1].to_i
  expires_at = parts[2].to_i
  origin     = parts[3].to_sym
  Tep::AgentDelegation.new(agent_id, issued_at, expires_at, origin)
end

.set_secret(s) ⇒ Object

Set the shared HMAC secret. Apps call once at boot.



40
41
42
43
# File 'lib/tep/auth_bearer_token.rb', line 40

def self.set_secret(s)
  Tep::APP.set_auth_bearer_secret(s)
  0
end

.try(req) ⇒ Object

Attempt to identify the request. Returns a Tep::Identity on successful verification, nil if no Bearer header / bad signature / expired / malformed payload.



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/tep/auth_bearer_token.rb', line 48

def self.try(req)
  header = req.req_headers["authorization"]
  if header.length < 8 || header[0, 7] != "Bearer "
    return nil
  end
  token = header[7, header.length - 7]

  secret = Tep::APP.auth_bearer_secret
  if secret.length == 0
    return nil
  end

  payload = Tep::Jwt.verify_and_decode(token, secret)
  if payload.length == 0
    return nil
  end

  # Check expiry first -- a token whose exp passed gets rejected
  # even if the signature still verifies. exp is unix epoch sec.
  exp = Tep::Json.get_int(payload, "exp")
  if exp > 0 && Time.now.to_i >= exp
    return nil
  end

  sub = Tep::Json.get_str(payload, "sub")
  if sub.length == 0
    return nil
  end

  caps_str = Tep::Json.get_str(payload, "caps")
  caps = Tep::AuthBearerToken.parse_caps(caps_str)

  delegate_str = Tep::Json.get_str(payload, "delegate")
  delegation = Tep::AuthBearerToken.parse_delegate(delegate_str)

  Tep::Identity.new(sub, delegation, caps)
end