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) ⇒ Object

rubocop:disable Metrics/ParameterLists

Raises:

  • (ArgumentError)


82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/inst_access/token.rb', line 82

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
)
  raise ArgumentError, 'Must provide user uuid and account uuid' if user_uuid.blank? || .blank?

  now = Time.now.to_i

  payload = {
    iss: ISSUER,
    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
  }.compact

  new(payload)
end

.from_token_string(jws) ⇒ Object

Takes an unencrypted (but signed) token string

Raises:



115
116
117
118
119
120
121
122
123
124
125
# File 'lib/inst_access/token.rb', line 115

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)


127
128
129
130
131
132
# File 'lib/inst_access/token.rb', line 127

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

#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



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

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!



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

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