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.
- checksums.yaml +4 -4
- data/Gemfile +2 -0
- data/README.md +12 -0
- data/example/Gemfile +1 -1
- data/example/Gemfile.lock +2 -2
- data/example/README.md +1 -1
- data/example/app/controllers/application_controller.rb +9 -2
- data/example/config/routes.rb +2 -1
- data/example/log/development.log +1315 -0
- data/example/tmp/cache/bootsnap/compile-cache-iseq/26/420cf4a622d71b +0 -0
- data/example/tmp/cache/bootsnap/compile-cache-iseq/68/a73620fd7d4284 +0 -0
- data/example/tmp/cache/bootsnap/compile-cache-iseq/b2/d451a148d6d303 +0 -0
- data/example/tmp/cache/bootsnap/compile-cache-iseq/d8/fff5874ac0039e +0 -0
- data/example/tmp/cache/bootsnap/compile-cache-iseq/ee/02ad963145723a +0 -0
- data/example/tmp/cache/bootsnap/compile-cache-iseq/f3/1d1f40f0899932 +0 -0
- data/example/tmp/cache/bootsnap/load-path-cache +0 -0
- data/example/tmp/pids/server.pid +1 -1
- data/lib/canvas/embed/version.rb +1 -1
- data/lib/canvas/embed.rb +30 -2
- data/pkg/canvas-embed-0.1.5.gem +0 -0
- data/pkg/canvas-embed-0.1.6.gem +0 -0
- data/spec/canvas/embed_spec.rb +27 -6
- metadata +8 -2
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/example/tmp/pids/server.pid
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
92342
|
data/lib/canvas/embed/version.rb
CHANGED
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
|
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
|
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
|
data/spec/canvas/embed_spec.rb
CHANGED
@@ -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
|
-
|
20
|
+
scopes = { 'team' => 'canvas' }
|
21
21
|
|
22
|
-
token = Canvas::
|
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
|
-
|
47
|
-
expect { Canvas::
|
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
|
-
|
54
|
-
token = Canvas::
|
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.
|
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-
|
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
|