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

rubocop:disable Metrics/ParameterLists, Metrics/CyclomaticComplexity

Raises:

  • (ArgumentError)


78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/inst_access/token.rb', line 78

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
)
  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: 
  }
  payload[:canvas_domain] = canvas_domain if canvas_domain
  payload[:masq_sub] = real_user_uuid if real_user_uuid
  payload[:masq_shard] = real_user_shard_id if real_user_shard_id
  payload[:debug_user_global_id] = user_global_id.to_s if user_global_id
  payload[:debug_masq_global_id] = real_user_global_id.to_s if real_user_global_id

  new(payload)
end

.from_token_string(jws) ⇒ Object

Takes an unencrypted (but signed) token string

Raises:



108
109
110
111
112
113
114
115
116
117
118
# File 'lib/inst_access/token.rb', line 108

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)


120
121
122
123
124
125
# File 'lib/inst_access/token.rb', line 120

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

#to_token_stringObject



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

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!



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

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