Class: InstAccess::Token

Inherits:
Object
  • Object
show all
Defined in:
lib/inst_access/token.rb

Constant Summary collapse

ISSUER =
'instructure:inst_access'
ENCRYPTION_ALGO =
:'RSA-OAEP'
ENCRYPTION_METHOD =
:'A128CBC-HS256'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(jwt_payload) ⇒ Token

Returns a new instance of Token.



29
30
31
# File 'lib/inst_access/token.rb', line 29

def initialize(jwt_payload)
  @jwt_payload = jwt_payload.symbolize_keys
end

Instance Attribute Details

#jwt_payloadObject (readonly)

Returns the value of attribute jwt_payload.



27
28
29
# File 'lib/inst_access/token.rb', line 27

def jwt_payload
  @jwt_payload
end

Class Method Details

.for_user(user_uuid: nil, account_uuid: nil, canvas_domain: nil, real_user_uuid: nil, real_user_shard_id: nil, user_global_id: nil, real_user_global_id: nil, region: nil, client_id: nil, instructure_service: nil, canvas_shard_id: nil) ⇒ Object

rubocop:disable Metrics/ParameterLists

Raises:

  • (ArgumentError)


98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/inst_access/token.rb', line 98

def for_user(
  user_uuid: nil,
  account_uuid: nil,
  canvas_domain: nil,
  real_user_uuid: nil,
  real_user_shard_id: nil,
  user_global_id: nil,
  real_user_global_id: nil,
  region: nil,
  client_id: nil,
  instructure_service: nil,
  canvas_shard_id: nil
)
  raise ArgumentError, 'Must provide user uuid and account uuid' if user_uuid.blank? || .blank?

  now = Time.now.to_i

  payload = {
    iss: ISSUER,
    jti: SecureRandom.uuid,
    iat: now,
    exp: now + 1.hour.to_i,
    sub: user_uuid,
    acct: ,
    canvas_domain: canvas_domain,
    masq_sub: real_user_uuid,
    masq_shard: real_user_shard_id,
    debug_user_global_id: user_global_id&.to_s,
    debug_masq_global_id: real_user_global_id&.to_s,
    region: region,
    client_id: client_id,
    instructure_service: instructure_service,
    canvas_shard_id: canvas_shard_id
  }.compact

  new(payload)
end

.from_token_string(jws) ⇒ Object

Takes an unencrypted (but signed) token string

Raises:



138
139
140
141
142
143
144
145
146
147
148
# File 'lib/inst_access/token.rb', line 138

def from_token_string(jws)
  sig_key = InstAccess.config.signing_key
  jwt = begin
    JSON::JWT.decode(jws, sig_key)
  rescue StandardError => e
    raise InvalidToken, e
  end
  raise TokenExpired if jwt[:exp] < Time.now.to_i

  new(jwt.to_hash)
end

.token?(string) ⇒ Boolean

Returns:

  • (Boolean)


150
151
152
153
154
155
# File 'lib/inst_access/token.rb', line 150

def token?(string)
  jwt = JSON::JWT.decode(string, :skip_verification)
  jwt[:iss] == ISSUER
rescue StandardError
  false
end

Instance Method Details

#account_uuidObject



37
38
39
# File 'lib/inst_access/token.rb', line 37

def 
  jwt_payload[:acct]
end

#canvas_domainObject



41
42
43
# File 'lib/inst_access/token.rb', line 41

def canvas_domain
  jwt_payload[:canvas_domain]
end

#canvas_shard_idObject



65
66
67
# File 'lib/inst_access/token.rb', line 65

def canvas_shard_id
  jwt_payload[:canvas_shard_id]
end

#client_idObject



57
58
59
# File 'lib/inst_access/token.rb', line 57

def client_id
  jwt_payload[:client_id]
end

#instructure_service?Boolean

Returns:

  • (Boolean)


61
62
63
# File 'lib/inst_access/token.rb', line 61

def instructure_service?
  jwt_payload[:instructure_service] == true
end

#jtiObject



69
70
71
# File 'lib/inst_access/token.rb', line 69

def jti
  jwt_payload[:jti]
end

#masquerading_user_shard_idObject



49
50
51
# File 'lib/inst_access/token.rb', line 49

def masquerading_user_shard_id
  jwt_payload[:masq_shard]
end

#masquerading_user_uuidObject



45
46
47
# File 'lib/inst_access/token.rb', line 45

def masquerading_user_uuid
  jwt_payload[:masq_sub]
end

#regionObject



53
54
55
# File 'lib/inst_access/token.rb', line 53

def region
  jwt_payload[:region]
end

#to_token_stringObject



73
74
75
76
# File 'lib/inst_access/token.rb', line 73

def to_token_string
  jwe = to_jws.encrypt(InstAccess.config.encryption_key, ENCRYPTION_ALGO, ENCRYPTION_METHOD)
  jwe.to_s
end

#to_unencrypted_token_stringObject

only for testing purposes, or to do local dev w/o running a decrypting service. unencrypted tokens should not be released into the wild!



80
81
82
# File 'lib/inst_access/token.rb', line 80

def to_unencrypted_token_string
  to_jws.to_s
end

#user_uuidObject



33
34
35
# File 'lib/inst_access/token.rb', line 33

def user_uuid
  jwt_payload[:sub]
end