canvas-embed 0.1.5 → 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
- 32082
1
+ 92342
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Canvas
4
4
  module Embed
5
- VERSION = '0.1.5'
5
+ VERSION = '0.1.7'
6
6
  end
7
7
  end
data/lib/canvas/embed.rb CHANGED
@@ -8,7 +8,7 @@ require 'base64'
8
8
  module Canvas
9
9
  class InvalidScopeError < StandardError
10
10
  end
11
- module Embeds
11
+ module Embed
12
12
  module_function
13
13
  # Public: Generate a token granting access to a scoped set of your data in Canvas
14
14
  #
@@ -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
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::Embeds.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::Embeds.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::Embeds.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.5
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
@@ -377,6 +377,7 @@ files:
377
377
  - example/tmp/cache/bootsnap/compile-cache-iseq/25/83a34761c8af44
378
378
  - example/tmp/cache/bootsnap/compile-cache-iseq/25/8bebc5d597430c
379
379
  - example/tmp/cache/bootsnap/compile-cache-iseq/26/0cfcf73cdf6304
380
+ - example/tmp/cache/bootsnap/compile-cache-iseq/26/420cf4a622d71b
380
381
  - example/tmp/cache/bootsnap/compile-cache-iseq/26/6ddb4fa0c38419
381
382
  - example/tmp/cache/bootsnap/compile-cache-iseq/26/81cc0a2d59e201
382
383
  - example/tmp/cache/bootsnap/compile-cache-iseq/26/9b8998000f6bed
@@ -1414,6 +1415,7 @@ files:
1414
1415
  - example/tmp/cache/bootsnap/compile-cache-iseq/b2/7702d3d8709e10
1415
1416
  - example/tmp/cache/bootsnap/compile-cache-iseq/b2/bcfc7147918ee9
1416
1417
  - example/tmp/cache/bootsnap/compile-cache-iseq/b2/c3b52c4862931e
1418
+ - example/tmp/cache/bootsnap/compile-cache-iseq/b2/d451a148d6d303
1417
1419
  - example/tmp/cache/bootsnap/compile-cache-iseq/b3/08f99db6a2f454
1418
1420
  - example/tmp/cache/bootsnap/compile-cache-iseq/b3/2928ee05dee54a
1419
1421
  - example/tmp/cache/bootsnap/compile-cache-iseq/b3/5e2f2005224107
@@ -1689,6 +1691,7 @@ files:
1689
1691
  - example/tmp/cache/bootsnap/compile-cache-iseq/d8/7cf9cd6b97ce3e
1690
1692
  - example/tmp/cache/bootsnap/compile-cache-iseq/d8/8e9b55d3c27632
1691
1693
  - example/tmp/cache/bootsnap/compile-cache-iseq/d8/d4be612eb65cc7
1694
+ - example/tmp/cache/bootsnap/compile-cache-iseq/d8/fff5874ac0039e
1692
1695
  - example/tmp/cache/bootsnap/compile-cache-iseq/d9/00dae66024922b
1693
1696
  - example/tmp/cache/bootsnap/compile-cache-iseq/d9/4752982ff62455
1694
1697
  - example/tmp/cache/bootsnap/compile-cache-iseq/d9/57d00f31fb9cc2
@@ -1901,6 +1904,7 @@ files:
1901
1904
  - example/tmp/cache/bootsnap/compile-cache-iseq/f3/037a60ada5b445
1902
1905
  - example/tmp/cache/bootsnap/compile-cache-iseq/f3/04fcc413cfa4df
1903
1906
  - example/tmp/cache/bootsnap/compile-cache-iseq/f3/16cbd38ad66198
1907
+ - example/tmp/cache/bootsnap/compile-cache-iseq/f3/1d1f40f0899932
1904
1908
  - example/tmp/cache/bootsnap/compile-cache-iseq/f3/34717834a094e6
1905
1909
  - example/tmp/cache/bootsnap/compile-cache-iseq/f4/0e93d368e5e2fb
1906
1910
  - example/tmp/cache/bootsnap/compile-cache-iseq/f4/33d0950fc0ca80
@@ -2010,6 +2014,8 @@ files:
2010
2014
  - example/tmp/restart.txt
2011
2015
  - lib/canvas/embed.rb
2012
2016
  - lib/canvas/embed/version.rb
2017
+ - pkg/canvas-embed-0.1.5.gem
2018
+ - pkg/canvas-embed-0.1.6.gem
2013
2019
  - sig/canvas/embed.rbs
2014
2020
  - spec/canvas/embed_spec.rb
2015
2021
  - spec/spec_helper.rb