canvas-embed 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- 56214
1
+ 92342
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Canvas
4
4
  module Embed
5
- VERSION = '0.1.6'
5
+ VERSION = '0.1.7'
6
6
  end
7
7
  end
data/lib/canvas/embed.rb CHANGED
@@ -17,7 +17,7 @@ module Canvas
17
17
  # expiration_seconds - Optional Integer, how long the token should be valid for
18
18
  # user_id - Optional String, identifier for the user, used in logging in Canvas.
19
19
  #
20
- def generate_token(private_key, scopes, expiration_seconds = 3600, user_id = nil)
20
+ def generate_embed_token(private_key, scopes, expiration_seconds = 3600, user_id = nil)
21
21
  if !scopes.is_a?(Hash)
22
22
  raise InvalidScopeError.new("Invalid scope #{scopes} type #{scopes.class}")
23
23
  end
@@ -40,5 +40,33 @@ module Canvas
40
40
  # strict for no newlines
41
41
  Base64.strict_encode64(token)
42
42
  end
43
+
44
+ # Public: Generate a token allowing one of your users to login to your account or sub-account
45
+ #
46
+ # private_key - String, signing key obtained from Canvas
47
+ # email - String, the email of the user to login. This should match a user or invite in one of your accounts.
48
+ # expiration_seconds - Optional Integer, how long the token should be valid for. Default to 10 minutes.
49
+ # user_id - Optional String, identifier for the user, used in logging in Canvas.
50
+ #
51
+ def generate_login_token(private_key, email, expiration_seconds = 600, user_id = nil)
52
+ # token consists of an id and the signing key
53
+ key_id, key = private_key.split('.')
54
+ # transform signing key hex into bytes
55
+ key_bytes = [key].pack('H*')
56
+ secret_box = RbNaCl::SecretBox.new(key_bytes)
57
+ nonce = RbNaCl::Random.random_bytes(secret_box.nonce_bytes)
58
+ exp = Time.now.to_i + expiration_seconds
59
+ message = { 'email' => email, 'exp' => exp }
60
+ if user_id != nil
61
+ message['userId'] = user_id
62
+ end
63
+ ciphertext = secret_box.encrypt(nonce, message.to_json)
64
+ # transform bytes into hex
65
+ unpacked_message = ciphertext.unpack1('H*')
66
+ unpacked_nonce = nonce.unpack1('H*')
67
+ token = { 'message' => unpacked_message, 'nonce' => unpacked_nonce, 'keyId' => key_id }.to_json
68
+ # strict for no newlines
69
+ Base64.strict_encode64(token)
70
+ end
43
71
  end
44
72
  end
Binary file
@@ -17,9 +17,9 @@ RSpec.describe Canvas::Embed do
17
17
  key = RbNaCl::Random.random_bytes(RbNaCl::SecretBox.key_bytes)
18
18
  unpacked_key = "emk_ZRzQbE9d.#{key.unpack1('H*')}"
19
19
 
20
- original_message = { 'team' => 'canvas' }
20
+ scopes = { 'team' => 'canvas' }
21
21
 
22
- token = Canvas::Embed.generate_token(unpacked_key, original_message)
22
+ token = Canvas::Embed.generate_embed_token(unpacked_key, scopes)
23
23
  expect(token).not_to be nil
24
24
 
25
25
  decoded = JSON.parse(Base64.decode64(token))
@@ -43,15 +43,15 @@ RSpec.describe Canvas::Embed do
43
43
  it 'rejects non-hash' do
44
44
  key = RbNaCl::Random.random_bytes(RbNaCl::SecretBox.key_bytes)
45
45
  unpacked_key = "emk_ZRzQbE9d.#{key.unpack1('H*')}"
46
- original_message = "'team': 'canvas'"
47
- expect { Canvas::Embed.generate_token(unpacked_key, original_message) }.to raise_error(Canvas::InvalidScopeError)
46
+ scopes = "'team': 'canvas'"
47
+ expect { Canvas::Embed.generate_embed_token(unpacked_key, scopes) }.to raise_error(Canvas::InvalidScopeError)
48
48
  end
49
49
 
50
50
  it 'accepts custom expiration and userId' do
51
51
  key = RbNaCl::Random.random_bytes(RbNaCl::SecretBox.key_bytes)
52
52
  unpacked_key = "emk_ZRzQbE9d.#{key.unpack1('H*')}"
53
- original_message = { 'team' => 'canvas' }
54
- token = Canvas::Embed.generate_token(unpacked_key, original_message, 7200, "cus_abc123")
53
+ scopes = { 'team' => 'canvas' }
54
+ token = Canvas::Embed.generate_embed_token(unpacked_key, scopes, 7200, "cus_abc123")
55
55
  expect(token).not_to be nil
56
56
  decoded = JSON.parse(Base64.decode64(token))
57
57
  expect(decoded['keyId']).to eq('emk_ZRzQbE9d')
@@ -68,4 +68,25 @@ RSpec.describe Canvas::Embed do
68
68
  expect(context['exp']).to eq(Time.now.to_i + 7200)
69
69
  expect(context['userId']).to eq("cus_abc123")
70
70
  end
71
+
72
+ it 'generates login token' do
73
+ key = RbNaCl::Random.random_bytes(RbNaCl::SecretBox.key_bytes)
74
+ unpacked_key = "emk_ZRzQbE9d.#{key.unpack1('H*')}"
75
+ token = Canvas::Embed.generate_login_token(unpacked_key, "will@cooldata.com", 300)
76
+ expect(token).not_to be nil
77
+ decoded = JSON.parse(Base64.decode64(token))
78
+ expect(decoded['keyId']).to eq('emk_ZRzQbE9d')
79
+
80
+ message_hex = decoded['message']
81
+ nonce_hex = decoded['nonce']
82
+ nonce = [nonce_hex].pack('H*')
83
+ message = [message_hex].pack('H*')
84
+
85
+ secret_box = RbNaCl::SecretBox.new(key)
86
+ decrypted_message = secret_box.decrypt(nonce, message)
87
+ context = JSON.parse(decrypted_message)
88
+
89
+ expect(context['exp']).to eq(Time.now.to_i + 300)
90
+ expect(context['email']).to eq("will@cooldata.com")
91
+ end
71
92
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: canvas-embed
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Will Pride
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-07 00:00:00.000000000 Z
11
+ date: 2023-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rbnacl
@@ -93,8 +93,6 @@ files:
93
93
  - example/config/storage.yml
94
94
  - example/log/development.log
95
95
  - example/storage/development.sqlite3
96
- - example/storage/development.sqlite3-shm
97
- - example/storage/development.sqlite3-wal
98
96
  - example/tmp/cache/bootsnap/compile-cache-iseq/00/47f4f1a378e4f3
99
97
  - example/tmp/cache/bootsnap/compile-cache-iseq/00/adaa3c79791768
100
98
  - example/tmp/cache/bootsnap/compile-cache-iseq/00/aea96502258cc3
@@ -379,6 +377,7 @@ files:
379
377
  - example/tmp/cache/bootsnap/compile-cache-iseq/25/83a34761c8af44
380
378
  - example/tmp/cache/bootsnap/compile-cache-iseq/25/8bebc5d597430c
381
379
  - example/tmp/cache/bootsnap/compile-cache-iseq/26/0cfcf73cdf6304
380
+ - example/tmp/cache/bootsnap/compile-cache-iseq/26/420cf4a622d71b
382
381
  - example/tmp/cache/bootsnap/compile-cache-iseq/26/6ddb4fa0c38419
383
382
  - example/tmp/cache/bootsnap/compile-cache-iseq/26/81cc0a2d59e201
384
383
  - example/tmp/cache/bootsnap/compile-cache-iseq/26/9b8998000f6bed
@@ -1905,6 +1904,7 @@ files:
1905
1904
  - example/tmp/cache/bootsnap/compile-cache-iseq/f3/037a60ada5b445
1906
1905
  - example/tmp/cache/bootsnap/compile-cache-iseq/f3/04fcc413cfa4df
1907
1906
  - example/tmp/cache/bootsnap/compile-cache-iseq/f3/16cbd38ad66198
1907
+ - example/tmp/cache/bootsnap/compile-cache-iseq/f3/1d1f40f0899932
1908
1908
  - example/tmp/cache/bootsnap/compile-cache-iseq/f3/34717834a094e6
1909
1909
  - example/tmp/cache/bootsnap/compile-cache-iseq/f4/0e93d368e5e2fb
1910
1910
  - example/tmp/cache/bootsnap/compile-cache-iseq/f4/33d0950fc0ca80
@@ -2015,6 +2015,7 @@ files:
2015
2015
  - lib/canvas/embed.rb
2016
2016
  - lib/canvas/embed/version.rb
2017
2017
  - pkg/canvas-embed-0.1.5.gem
2018
+ - pkg/canvas-embed-0.1.6.gem
2018
2019
  - sig/canvas/embed.rbs
2019
2020
  - spec/canvas/embed_spec.rb
2020
2021
  - spec/spec_helper.rb
File without changes