opentok 4.9.0 → 4.11.0
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/.github/workflows/ci.yml +1 -1
- data/CHANGES.md +4 -0
- data/Gemfile +2 -0
- data/lib/opentok/opentok.rb +1 -0
- data/lib/opentok/session.rb +1 -0
- data/lib/opentok/token_generator.rb +60 -4
- data/lib/opentok/version.rb +1 -1
- data/spec/matchers/token.rb +34 -2
- data/spec/opentok/session_spec.rb +0 -1
- data/spec/shared/opentok_generates_tokens.rb +263 -103
- data/spec/shared/session_generates_tokens.rb +110 -38
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '08afb004026d5e2f7a095d057c455acf33bd8a0ea268b367fee4b27b63d15949'
|
|
4
|
+
data.tar.gz: 1e0e778d936e767389554fcaa60a58663019b6016b23b4ca11520ad25404b631
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8f99b13b1f41af4cffb9aaabeb93d6ef7f033ee739bbcdcaae6836742e53cab7d7c18a1e04ce3bab765be8ab03cf244f0bed719c034fc0e1d3caf811eb948eaa
|
|
7
|
+
data.tar.gz: ad34ad438181cb082907a1d781f5a684ef5d83b88abec3a68cc1f3f7d31a1580f6b024f9c022a6cf58312fb33ad6bd1ab282df2d62a7ea2873cc844622f7a9c5
|
data/.github/workflows/ci.yml
CHANGED
data/CHANGES.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
# 4.11.0
|
|
2
|
+
|
|
3
|
+
* Updating client token creation to use JWTs by default. See [#287](https://github.com/opentok/OpenTok-Ruby-SDK/pull/274)
|
|
4
|
+
|
|
1
5
|
# 4.9.0
|
|
2
6
|
|
|
3
7
|
* Adds the `publisheronly` role for client token creation. See [#272](https://github.com/opentok/OpenTok-Ruby-SDK/pull/272)
|
data/Gemfile
CHANGED
data/lib/opentok/opentok.rb
CHANGED
|
@@ -36,6 +36,7 @@ module OpenTok
|
|
|
36
36
|
# the token.
|
|
37
37
|
#
|
|
38
38
|
# @param [Hash] options A hash defining options for the token.
|
|
39
|
+
# @option options [String] :token_type The type of token to generate. Must be one of 'T1' or 'JWT'. 'JWT' is the default.
|
|
39
40
|
# @option options [Symbol] :role The role for the token. Set this to one of the following
|
|
40
41
|
# values:
|
|
41
42
|
# * <code>:subscriber</code> -- A subscriber can only subscribe to streams.
|
data/lib/opentok/session.rb
CHANGED
|
@@ -28,6 +28,7 @@ module OpenTok
|
|
|
28
28
|
# Generates a token.
|
|
29
29
|
#
|
|
30
30
|
# @param [Hash] options
|
|
31
|
+
# @option options [String] :token_type The type of token to generate. Must be one of 'T1' or 'JWT'. 'JWT' is the default.
|
|
31
32
|
# @option options [Symbol] :role The role for the token. Set this to one of the following
|
|
32
33
|
# values:
|
|
33
34
|
# * <code>:subscriber</code> -- A subscriber can only subscribe to streams.
|
|
@@ -6,10 +6,13 @@ require "addressable/uri"
|
|
|
6
6
|
require "openssl"
|
|
7
7
|
require "active_support"
|
|
8
8
|
require "active_support/time"
|
|
9
|
+
require "jwt"
|
|
9
10
|
|
|
10
11
|
module OpenTok
|
|
11
12
|
# @private
|
|
12
13
|
module TokenGenerator
|
|
14
|
+
VALID_TOKEN_TYPES = ['T1', 'JWT'].freeze
|
|
15
|
+
|
|
13
16
|
# this works when using include TokenGenerator
|
|
14
17
|
def self.included(base)
|
|
15
18
|
base.extend(ClassMethods)
|
|
@@ -33,7 +36,14 @@ module OpenTok
|
|
|
33
36
|
end
|
|
34
37
|
dynamic_args.compact!
|
|
35
38
|
args = args.first(4-dynamic_args.length)
|
|
36
|
-
|
|
39
|
+
token_type = if args.any? && args.last.is_a?(Hash) && args.last.has_key?(:token_type)
|
|
40
|
+
args.last[:token_type].upcase
|
|
41
|
+
else
|
|
42
|
+
"JWT"
|
|
43
|
+
end
|
|
44
|
+
raise "'#{token_type}' is not a valid token type. Must be one of: #{VALID_TOKEN_TYPES.join(', ')}" unless VALID_TOKEN_TYPES.include? token_type
|
|
45
|
+
|
|
46
|
+
self.class.generate_token(token_type).call(*dynamic_args, *args)
|
|
37
47
|
end
|
|
38
48
|
end
|
|
39
49
|
|
|
@@ -43,14 +53,14 @@ module OpenTok
|
|
|
43
53
|
end
|
|
44
54
|
|
|
45
55
|
# Generates a token
|
|
46
|
-
def generate_token
|
|
47
|
-
TokenGenerator::
|
|
56
|
+
def generate_token(token_type)
|
|
57
|
+
token_type == 'T1' ? TokenGenerator::GENERATE_T1_TOKEN_LAMBDA : TokenGenerator::GENERATE_JWT_LAMBDA
|
|
48
58
|
end
|
|
49
59
|
|
|
50
60
|
end
|
|
51
61
|
|
|
52
62
|
# @private TODO: this probably doesn't need to be a constant anyone can read
|
|
53
|
-
|
|
63
|
+
GENERATE_T1_TOKEN_LAMBDA = ->(api_key, api_secret, session_id, opts = {}) do
|
|
54
64
|
# normalize required data params
|
|
55
65
|
role = opts.fetch(:role, :publisher)
|
|
56
66
|
unless ROLES.has_key? role
|
|
@@ -101,6 +111,52 @@ module OpenTok
|
|
|
101
111
|
TOKEN_SENTINEL + Base64.strict_encode64(meta_string + ":" + data_string)
|
|
102
112
|
end
|
|
103
113
|
|
|
114
|
+
GENERATE_JWT_LAMBDA = ->(api_key, api_secret, session_id, opts = {}) do
|
|
115
|
+
# normalize required data params
|
|
116
|
+
role = opts.fetch(:role, :publisher)
|
|
117
|
+
unless ROLES.has_key? role
|
|
118
|
+
raise "'#{role}' is not a recognized role"
|
|
119
|
+
end
|
|
120
|
+
unless Session.belongs_to_api_key? session_id.to_s, api_key
|
|
121
|
+
raise "Cannot generate token for a session_id that doesn't belong to api_key: #{api_key}"
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# minimum data params
|
|
125
|
+
data_params = {
|
|
126
|
+
:iss => api_key,
|
|
127
|
+
:ist => "project",
|
|
128
|
+
:iat => Time.now.to_i,
|
|
129
|
+
:nonce => Random.rand,
|
|
130
|
+
:role => role,
|
|
131
|
+
:scope => "session.connect",
|
|
132
|
+
:session_id => session_id,
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
# normalize and add additional data params
|
|
136
|
+
unless (expire_time = opts[:expire_time].to_i) == 0
|
|
137
|
+
unless expire_time.between?(Time.now.to_i, (Time.now + 30.days).to_i)
|
|
138
|
+
raise "Expire time must be within the next 30 days"
|
|
139
|
+
end
|
|
140
|
+
data_params[:exp] = expire_time.to_i
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
unless opts[:data].nil?
|
|
144
|
+
unless (data = opts[:data].to_s).length < 1000
|
|
145
|
+
raise "Connection data must be less than 1000 characters"
|
|
146
|
+
end
|
|
147
|
+
data_params[:connection_data] = data
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
if opts[:initial_layout_class_list]
|
|
151
|
+
if opts[:initial_layout_class_list].is_a?(Array)
|
|
152
|
+
data_params[:initial_layout_class_list] = opts[:initial_layout_class_list].join(' ')
|
|
153
|
+
else
|
|
154
|
+
data_params[:initial_layout_class_list] = opts[:initial_layout_class_list].to_s
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
JWT.encode(data_params, api_secret, 'HS256', header_fields={typ: 'JWT'})
|
|
159
|
+
end
|
|
104
160
|
|
|
105
161
|
# this works when using extend TokenGenerator
|
|
106
162
|
# def generates_tokens(method_opts)
|
data/lib/opentok/version.rb
CHANGED
data/spec/matchers/token.rb
CHANGED
|
@@ -3,8 +3,9 @@ require "rspec/matchers"
|
|
|
3
3
|
require "base64"
|
|
4
4
|
require "openssl"
|
|
5
5
|
require "addressable/uri"
|
|
6
|
+
require "jwt"
|
|
6
7
|
|
|
7
|
-
RSpec::Matchers.define :
|
|
8
|
+
RSpec::Matchers.define :carry_t1_token_data do |input_data|
|
|
8
9
|
option_to_token_key = {
|
|
9
10
|
:api_key => :partner_id,
|
|
10
11
|
:data => :connection_data,
|
|
@@ -37,7 +38,7 @@ RSpec::Matchers.define :carry_token_data do |input_data|
|
|
|
37
38
|
end
|
|
38
39
|
end
|
|
39
40
|
|
|
40
|
-
RSpec::Matchers.define :
|
|
41
|
+
RSpec::Matchers.define :carry_valid_t1_token_signature do |api_secret|
|
|
41
42
|
match do |token|
|
|
42
43
|
decoded_token = Base64.decode64(token[4..token.length])
|
|
43
44
|
metadata, data_string = decoded_token.split(':')
|
|
@@ -48,3 +49,34 @@ RSpec::Matchers.define :carry_valid_token_signature do |api_secret|
|
|
|
48
49
|
signature == OpenSSL::HMAC.hexdigest(digest, api_secret, data_string)
|
|
49
50
|
end
|
|
50
51
|
end
|
|
52
|
+
|
|
53
|
+
RSpec::Matchers.define :carry_jwt_token_data do |input_data|
|
|
54
|
+
match do |token|
|
|
55
|
+
decoded_token = JWT.decode(token, nil, false)
|
|
56
|
+
token_data = decoded_token.first.transform_keys {|k| k.to_sym}.transform_values {|v| v.to_s}
|
|
57
|
+
check_token_data = lambda { |key, value|
|
|
58
|
+
if token_data.has_key? key
|
|
59
|
+
unless value.nil?
|
|
60
|
+
return token_data[key] == value.to_s
|
|
61
|
+
end
|
|
62
|
+
return true
|
|
63
|
+
end
|
|
64
|
+
false
|
|
65
|
+
}
|
|
66
|
+
unless input_data.respond_to? :all?
|
|
67
|
+
return check_token_data.call(input_data, nil)
|
|
68
|
+
end
|
|
69
|
+
input_data.all? { |k, v| check_token_data.call(k, v) }
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
RSpec::Matchers.define :carry_valid_jwt_token_signature do |api_secret|
|
|
74
|
+
match do |token|
|
|
75
|
+
begin
|
|
76
|
+
JWT.decode(token, api_secret, true)
|
|
77
|
+
rescue
|
|
78
|
+
return false
|
|
79
|
+
end
|
|
80
|
+
true
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -15,124 +15,284 @@ shared_examples "opentok generates tokens" do
|
|
|
15
15
|
let(:api_secret) { "1234567890abcdef1234567890abcdef1234567890" }
|
|
16
16
|
let(:session_id) { "1_MX4xMjM0NTZ-flNhdCBNYXIgMTUgMTQ6NDI6MjMgUERUIDIwMTR-MC40OTAxMzAyNX4" }
|
|
17
17
|
let(:default_role) { :publisher }
|
|
18
|
+
let(:ist) { "project" }
|
|
19
|
+
let(:scope) { "session.connect" }
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
context "when token type is T1" do
|
|
22
|
+
it "generates plain tokens" do
|
|
23
|
+
plain_token = opentok.generate_token session_id, :token_type => "T1"
|
|
24
|
+
expect(plain_token).to be_an_instance_of String
|
|
25
|
+
expect(plain_token).to carry_t1_token_data :session_id => session_id
|
|
26
|
+
expect(plain_token).to carry_t1_token_data :api_key => api_key
|
|
27
|
+
expect(plain_token).to carry_t1_token_data :role => default_role
|
|
28
|
+
expect(plain_token).to carry_t1_token_data [:nonce, :create_time]
|
|
29
|
+
expect(plain_token).to carry_valid_t1_token_signature api_secret
|
|
30
|
+
end
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
it "generates tokens with an expire time" do
|
|
33
|
+
expire_time = Time.now + (60*60*24)
|
|
34
|
+
expiring_token = opentok.generate_token session_id, :expire_time => expire_time, :token_type => "T1"
|
|
35
|
+
expect(expiring_token).to be_an_instance_of String
|
|
36
|
+
expect(expiring_token).to carry_t1_token_data :session_id => session_id
|
|
37
|
+
expect(expiring_token).to carry_t1_token_data :api_key => api_key
|
|
38
|
+
expect(expiring_token).to carry_t1_token_data :role => default_role
|
|
39
|
+
expect(expiring_token).to carry_t1_token_data :expire_time => expire_time.to_i
|
|
40
|
+
expect(expiring_token).to carry_t1_token_data [:nonce, :create_time]
|
|
41
|
+
expect(expiring_token).to carry_valid_t1_token_signature api_secret
|
|
42
|
+
end
|
|
40
43
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
44
|
+
it "generates tokens with an integer expire time" do
|
|
45
|
+
expire_time = Time.now.to_i + (60*60*24)
|
|
46
|
+
expiring_token = opentok.generate_token session_id, :expire_time => expire_time, :token_type => "T1"
|
|
47
|
+
expect(expiring_token).to be_an_instance_of String
|
|
48
|
+
expect(expiring_token).to carry_t1_token_data :session_id => session_id
|
|
49
|
+
expect(expiring_token).to carry_t1_token_data :api_key => api_key
|
|
50
|
+
expect(expiring_token).to carry_t1_token_data :role => default_role
|
|
51
|
+
expect(expiring_token).to carry_t1_token_data :expire_time => expire_time
|
|
52
|
+
expect(expiring_token).to carry_t1_token_data [:nonce, :create_time]
|
|
53
|
+
expect(expiring_token).to carry_valid_t1_token_signature api_secret
|
|
54
|
+
end
|
|
52
55
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
56
|
+
it "generates tokens with a publisher role" do
|
|
57
|
+
role = :publisher
|
|
58
|
+
role_token = opentok.generate_token session_id, :role => role, :token_type => "T1"
|
|
59
|
+
expect(role_token).to be_an_instance_of String
|
|
60
|
+
expect(role_token).to carry_t1_token_data :session_id => session_id
|
|
61
|
+
expect(role_token).to carry_t1_token_data :api_key => api_key
|
|
62
|
+
expect(role_token).to carry_t1_token_data :role => role
|
|
63
|
+
expect(role_token).to carry_t1_token_data [:nonce, :create_time]
|
|
64
|
+
expect(role_token).to carry_valid_t1_token_signature api_secret
|
|
65
|
+
end
|
|
63
66
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
67
|
+
it "generates tokens with a subscriber role" do
|
|
68
|
+
role = :subscriber
|
|
69
|
+
role_token = opentok.generate_token session_id, :role => role, :token_type => "T1"
|
|
70
|
+
expect(role_token).to be_an_instance_of String
|
|
71
|
+
expect(role_token).to carry_t1_token_data :session_id => session_id
|
|
72
|
+
expect(role_token).to carry_t1_token_data :api_key => api_key
|
|
73
|
+
expect(role_token).to carry_t1_token_data :role => role
|
|
74
|
+
expect(role_token).to carry_t1_token_data [:nonce, :create_time]
|
|
75
|
+
expect(role_token).to carry_valid_t1_token_signature api_secret
|
|
76
|
+
end
|
|
74
77
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
78
|
+
it "generates tokens with a moderator role" do
|
|
79
|
+
role = :moderator
|
|
80
|
+
role_token = opentok.generate_token session_id, :role => role, :token_type => "T1"
|
|
81
|
+
expect(role_token).to be_an_instance_of String
|
|
82
|
+
expect(role_token).to carry_t1_token_data :session_id => session_id
|
|
83
|
+
expect(role_token).to carry_t1_token_data :api_key => api_key
|
|
84
|
+
expect(role_token).to carry_t1_token_data :role => role
|
|
85
|
+
expect(role_token).to carry_t1_token_data [:nonce, :create_time]
|
|
86
|
+
expect(role_token).to carry_valid_t1_token_signature api_secret
|
|
87
|
+
end
|
|
85
88
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
89
|
+
it "generates tokens with a publisheronly role" do
|
|
90
|
+
role = :publisheronly
|
|
91
|
+
role_token = opentok.generate_token session_id, :role => role, :token_type => "T1"
|
|
92
|
+
expect(role_token).to be_an_instance_of String
|
|
93
|
+
expect(role_token).to carry_t1_token_data :session_id => session_id
|
|
94
|
+
expect(role_token).to carry_t1_token_data :api_key => api_key
|
|
95
|
+
expect(role_token).to carry_t1_token_data :role => role
|
|
96
|
+
expect(role_token).to carry_t1_token_data [:nonce, :create_time]
|
|
97
|
+
expect(role_token).to carry_valid_t1_token_signature api_secret
|
|
98
|
+
end
|
|
96
99
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
100
|
+
it "generates tokens with data" do
|
|
101
|
+
data = "name=Johnny"
|
|
102
|
+
data_bearing_token = opentok.generate_token session_id, :data => data, :token_type => "T1"
|
|
103
|
+
expect(data_bearing_token).to be_an_instance_of String
|
|
104
|
+
expect(data_bearing_token).to carry_t1_token_data :session_id => session_id
|
|
105
|
+
expect(data_bearing_token).to carry_t1_token_data :api_key => api_key
|
|
106
|
+
expect(data_bearing_token).to carry_t1_token_data :role => default_role
|
|
107
|
+
expect(data_bearing_token).to carry_t1_token_data :data => data
|
|
108
|
+
expect(data_bearing_token).to carry_t1_token_data [:nonce, :create_time]
|
|
109
|
+
expect(data_bearing_token).to carry_valid_t1_token_signature api_secret
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it "generates tokens with initial layout classes" do
|
|
113
|
+
layout_classes = ["focus", "small"]
|
|
114
|
+
layout_class_bearing_token = opentok.generate_token session_id, :initial_layout_class_list => layout_classes, :token_type => "T1"
|
|
115
|
+
expect(layout_class_bearing_token).to be_an_instance_of String
|
|
116
|
+
expect(layout_class_bearing_token).to carry_t1_token_data :session_id => session_id
|
|
117
|
+
expect(layout_class_bearing_token).to carry_t1_token_data :api_key => api_key
|
|
118
|
+
expect(layout_class_bearing_token).to carry_t1_token_data :role => default_role
|
|
119
|
+
expect(layout_class_bearing_token).to carry_t1_token_data :initial_layout_class_list => layout_classes.join(' ')
|
|
120
|
+
expect(layout_class_bearing_token).to carry_t1_token_data [:nonce, :create_time]
|
|
121
|
+
expect(layout_class_bearing_token).to carry_valid_t1_token_signature api_secret
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it "generates tokens with one initial layout class" do
|
|
125
|
+
layout_class = "focus"
|
|
126
|
+
layout_class_bearing_token = opentok.generate_token session_id, :initial_layout_class_list => layout_class, :token_type => "T1"
|
|
127
|
+
expect(layout_class_bearing_token).to be_an_instance_of String
|
|
128
|
+
expect(layout_class_bearing_token).to carry_t1_token_data :session_id => session_id
|
|
129
|
+
expect(layout_class_bearing_token).to carry_t1_token_data :api_key => api_key
|
|
130
|
+
expect(layout_class_bearing_token).to carry_t1_token_data :role => default_role
|
|
131
|
+
expect(layout_class_bearing_token).to carry_t1_token_data :initial_layout_class_list => layout_class
|
|
132
|
+
expect(layout_class_bearing_token).to carry_t1_token_data [:nonce, :create_time]
|
|
133
|
+
expect(layout_class_bearing_token).to carry_valid_t1_token_signature api_secret
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
context "when the role is invalid" do
|
|
137
|
+
it "raises an error" do
|
|
138
|
+
expect { opentok.generate_token session_id, :role => :invalid_role, :token_type => "T1" }.to raise_error
|
|
139
|
+
end
|
|
140
|
+
end
|
|
107
141
|
end
|
|
108
142
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
143
|
+
context "when token type is JWT" do
|
|
144
|
+
it "generates plain tokens" do
|
|
145
|
+
plain_token = opentok.generate_token session_id, :token_type => "JWT"
|
|
146
|
+
expect(plain_token).to be_an_instance_of String
|
|
147
|
+
expect(plain_token).to carry_jwt_token_data :session_id => session_id
|
|
148
|
+
expect(plain_token).to carry_jwt_token_data :iss => api_key
|
|
149
|
+
expect(plain_token).to carry_jwt_token_data :ist => ist
|
|
150
|
+
expect(plain_token).to carry_jwt_token_data :scope => scope
|
|
151
|
+
expect(plain_token).to carry_jwt_token_data :role => default_role
|
|
152
|
+
expect(plain_token).to carry_jwt_token_data [:ist, :iat, :nonce]
|
|
153
|
+
expect(plain_token).to carry_valid_jwt_token_signature api_secret
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
it "generates tokens with a custom expire time" do
|
|
157
|
+
expire_time = Time.now + (60*60*24)
|
|
158
|
+
expiring_token = opentok.generate_token session_id, :expire_time => expire_time, :token_type => "JWT"
|
|
159
|
+
expect(expiring_token).to be_an_instance_of String
|
|
160
|
+
expect(expiring_token).to carry_jwt_token_data :session_id => session_id
|
|
161
|
+
expect(expiring_token).to carry_jwt_token_data :iss => api_key
|
|
162
|
+
expect(expiring_token).to carry_jwt_token_data :ist => ist
|
|
163
|
+
expect(expiring_token).to carry_jwt_token_data :scope => scope
|
|
164
|
+
expect(expiring_token).to carry_jwt_token_data :role => default_role
|
|
165
|
+
expect(expiring_token).to carry_jwt_token_data :exp => expire_time.to_i
|
|
166
|
+
expect(expiring_token).to carry_jwt_token_data [:ist, :iat, :nonce]
|
|
167
|
+
expect(expiring_token).to carry_valid_jwt_token_signature api_secret
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it "generates tokens with an integer expire time" do
|
|
171
|
+
expire_time = Time.now.to_i + (60*60*24)
|
|
172
|
+
expiring_token = opentok.generate_token session_id, :expire_time => expire_time, :token_type => "JWT"
|
|
173
|
+
expect(expiring_token).to be_an_instance_of String
|
|
174
|
+
expect(expiring_token).to carry_jwt_token_data :session_id => session_id
|
|
175
|
+
expect(expiring_token).to carry_jwt_token_data :iss => api_key
|
|
176
|
+
expect(expiring_token).to carry_jwt_token_data :ist => ist
|
|
177
|
+
expect(expiring_token).to carry_jwt_token_data :scope => scope
|
|
178
|
+
expect(expiring_token).to carry_jwt_token_data :role => default_role
|
|
179
|
+
expect(expiring_token).to carry_jwt_token_data :exp => expire_time
|
|
180
|
+
expect(expiring_token).to carry_jwt_token_data [:ist, :iat, :nonce]
|
|
181
|
+
expect(expiring_token).to carry_valid_jwt_token_signature api_secret
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it "generates tokens with a publisher role" do
|
|
185
|
+
role = :publisher
|
|
186
|
+
role_token = opentok.generate_token session_id, :role => role, :token_type => "JWT"
|
|
187
|
+
expect(role_token).to be_an_instance_of String
|
|
188
|
+
expect(role_token).to carry_jwt_token_data :session_id => session_id
|
|
189
|
+
expect(role_token).to carry_jwt_token_data :iss => api_key
|
|
190
|
+
expect(role_token).to carry_jwt_token_data :ist => ist
|
|
191
|
+
expect(role_token).to carry_jwt_token_data :scope => scope
|
|
192
|
+
expect(role_token).to carry_jwt_token_data :role => role
|
|
193
|
+
expect(role_token).to carry_jwt_token_data [:ist, :iat, :nonce]
|
|
194
|
+
expect(role_token).to carry_valid_jwt_token_signature api_secret
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
it "generates tokens with a subscriber role" do
|
|
198
|
+
role = :subscriber
|
|
199
|
+
role_token = opentok.generate_token session_id, :role => role, :token_type => "JWT"
|
|
200
|
+
expect(role_token).to be_an_instance_of String
|
|
201
|
+
expect(role_token).to carry_jwt_token_data :session_id => session_id
|
|
202
|
+
expect(role_token).to carry_jwt_token_data :iss => api_key
|
|
203
|
+
expect(role_token).to carry_jwt_token_data :ist => ist
|
|
204
|
+
expect(role_token).to carry_jwt_token_data :scope => scope
|
|
205
|
+
expect(role_token).to carry_jwt_token_data :role => role
|
|
206
|
+
expect(role_token).to carry_jwt_token_data [:ist, :iat, :nonce]
|
|
207
|
+
expect(role_token).to carry_valid_jwt_token_signature api_secret
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
it "generates tokens with a moderator role" do
|
|
211
|
+
role = :moderator
|
|
212
|
+
role_token = opentok.generate_token session_id, :role => role, :token_type => "JWT"
|
|
213
|
+
expect(role_token).to be_an_instance_of String
|
|
214
|
+
expect(role_token).to carry_jwt_token_data :session_id => session_id
|
|
215
|
+
expect(role_token).to carry_jwt_token_data :iss => api_key
|
|
216
|
+
expect(role_token).to carry_jwt_token_data :ist => ist
|
|
217
|
+
expect(role_token).to carry_jwt_token_data :scope => scope
|
|
218
|
+
expect(role_token).to carry_jwt_token_data :role => role
|
|
219
|
+
expect(role_token).to carry_jwt_token_data [:ist, :iat, :nonce]
|
|
220
|
+
expect(role_token).to carry_valid_jwt_token_signature api_secret
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
it "generates tokens with a publisheronly role" do
|
|
224
|
+
role = :publisheronly
|
|
225
|
+
role_token = opentok.generate_token session_id, :role => role, :token_type => "JWT"
|
|
226
|
+
expect(role_token).to be_an_instance_of String
|
|
227
|
+
expect(role_token).to carry_jwt_token_data :session_id => session_id
|
|
228
|
+
expect(role_token).to carry_jwt_token_data :iss => api_key
|
|
229
|
+
expect(role_token).to carry_jwt_token_data :ist => ist
|
|
230
|
+
expect(role_token).to carry_jwt_token_data :scope => scope
|
|
231
|
+
expect(role_token).to carry_jwt_token_data :role => role
|
|
232
|
+
expect(role_token).to carry_jwt_token_data [:ist, :iat, :nonce]
|
|
233
|
+
expect(role_token).to carry_valid_jwt_token_signature api_secret
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
it "generates tokens with data" do
|
|
237
|
+
data = "name=Johnny"
|
|
238
|
+
data_bearing_token = opentok.generate_token session_id, :data => data, :token_type => "JWT"
|
|
239
|
+
expect(data_bearing_token).to be_an_instance_of String
|
|
240
|
+
expect(data_bearing_token).to carry_jwt_token_data :session_id => session_id
|
|
241
|
+
expect(data_bearing_token).to carry_jwt_token_data :iss => api_key
|
|
242
|
+
expect(data_bearing_token).to carry_jwt_token_data :ist => ist
|
|
243
|
+
expect(data_bearing_token).to carry_jwt_token_data :scope => scope
|
|
244
|
+
expect(data_bearing_token).to carry_jwt_token_data :role => default_role
|
|
245
|
+
expect(data_bearing_token).to carry_jwt_token_data :connection_data => data
|
|
246
|
+
expect(data_bearing_token).to carry_jwt_token_data [:ist, :iat, :nonce]
|
|
247
|
+
expect(data_bearing_token).to carry_valid_jwt_token_signature api_secret
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
it "generates tokens with initial layout classes" do
|
|
251
|
+
layout_classes = ["focus", "small"]
|
|
252
|
+
layout_class_bearing_token = opentok.generate_token session_id, :initial_layout_class_list => layout_classes, :token_type => "JWT"
|
|
253
|
+
expect(layout_class_bearing_token).to be_an_instance_of String
|
|
254
|
+
expect(layout_class_bearing_token).to carry_jwt_token_data :session_id => session_id
|
|
255
|
+
expect(layout_class_bearing_token).to carry_jwt_token_data :iss => api_key
|
|
256
|
+
expect(layout_class_bearing_token).to carry_jwt_token_data :ist => ist
|
|
257
|
+
expect(layout_class_bearing_token).to carry_jwt_token_data :scope => scope
|
|
258
|
+
expect(layout_class_bearing_token).to carry_jwt_token_data :role => default_role
|
|
259
|
+
expect(layout_class_bearing_token).to carry_jwt_token_data :initial_layout_class_list => layout_classes.join(' ')
|
|
260
|
+
expect(layout_class_bearing_token).to carry_jwt_token_data [:ist, :iat, :nonce]
|
|
261
|
+
expect(layout_class_bearing_token).to carry_valid_jwt_token_signature api_secret
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
it "generates tokens with one initial layout class" do
|
|
265
|
+
layout_class = "focus"
|
|
266
|
+
layout_class_bearing_token = opentok.generate_token session_id, :initial_layout_class_list => layout_class, :token_type => "JWT"
|
|
267
|
+
expect(layout_class_bearing_token).to be_an_instance_of String
|
|
268
|
+
expect(layout_class_bearing_token).to carry_jwt_token_data :session_id => session_id
|
|
269
|
+
expect(layout_class_bearing_token).to carry_jwt_token_data :iss => api_key
|
|
270
|
+
expect(layout_class_bearing_token).to carry_jwt_token_data :ist => ist
|
|
271
|
+
expect(layout_class_bearing_token).to carry_jwt_token_data :scope => scope
|
|
272
|
+
expect(layout_class_bearing_token).to carry_jwt_token_data :role => default_role
|
|
273
|
+
expect(layout_class_bearing_token).to carry_jwt_token_data :initial_layout_class_list => layout_class
|
|
274
|
+
expect(layout_class_bearing_token).to carry_jwt_token_data [:ist, :iat, :nonce]
|
|
275
|
+
expect(layout_class_bearing_token).to carry_valid_jwt_token_signature api_secret
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
context "when the role is invalid" do
|
|
279
|
+
it "raises an error" do
|
|
280
|
+
expect { opentok.generate_token session_id, :role => :invalid_role, :token_type => "JWT" }.to raise_error
|
|
281
|
+
end
|
|
282
|
+
end
|
|
119
283
|
end
|
|
120
284
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
expect(layout_class_bearing_token).to carry_token_data :role => default_role
|
|
128
|
-
expect(layout_class_bearing_token).to carry_token_data :initial_layout_class_list => layout_class
|
|
129
|
-
expect(layout_class_bearing_token).to carry_token_data [:nonce, :create_time]
|
|
130
|
-
expect(layout_class_bearing_token).to carry_valid_token_signature api_secret
|
|
285
|
+
context "when token type is not specified" do
|
|
286
|
+
it "generates a JWT token by default" do
|
|
287
|
+
default_token = opentok.generate_token session_id
|
|
288
|
+
expect(default_token).to be_an_instance_of String
|
|
289
|
+
expect(default_token).to carry_valid_jwt_token_signature api_secret
|
|
290
|
+
end
|
|
131
291
|
end
|
|
132
292
|
|
|
133
|
-
context "when
|
|
293
|
+
context "when token type is invalid" do
|
|
134
294
|
it "raises an error" do
|
|
135
|
-
expect { opentok.generate_token session_id, :
|
|
295
|
+
expect { opentok.generate_token session_id, :token_type => "invalid_token_type" }.to raise_error
|
|
136
296
|
end
|
|
137
297
|
end
|
|
138
298
|
|
|
@@ -15,52 +15,124 @@ shared_examples "session generates tokens" do
|
|
|
15
15
|
let(:api_secret) { "1234567890abcdef1234567890abcdef1234567890" }
|
|
16
16
|
let(:session_id) { "1_MX4xMjM0NTZ-flNhdCBNYXIgMTUgMTQ6NDI6MjMgUERUIDIwMTR-MC40OTAxMzAyNX4" }
|
|
17
17
|
let(:default_role) { :publisher }
|
|
18
|
+
let(:ist) { "project" }
|
|
19
|
+
let(:scope) { "session.connect" }
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
context "when token type is T1" do
|
|
22
|
+
it "generates plain tokens" do
|
|
23
|
+
plain_token = session.generate_token :token_type => "T1"
|
|
24
|
+
expect(plain_token).to be_an_instance_of String
|
|
25
|
+
expect(plain_token).to carry_t1_token_data :session_id => session_id
|
|
26
|
+
expect(plain_token).to carry_t1_token_data :api_key => api_key
|
|
27
|
+
expect(plain_token).to carry_t1_token_data :role => default_role
|
|
28
|
+
expect(plain_token).to carry_t1_token_data [:nonce, :create_time]
|
|
29
|
+
expect(plain_token).to carry_valid_t1_token_signature api_secret
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "generates tokens with an expire time" do
|
|
33
|
+
expire_time = Time.now + (60*60*24)
|
|
34
|
+
expiring_token = session.generate_token :expire_time => expire_time, :token_type => "T1"
|
|
35
|
+
expect(expiring_token).to be_an_instance_of String
|
|
36
|
+
expect(expiring_token).to carry_t1_token_data :session_id => session_id
|
|
37
|
+
expect(expiring_token).to carry_t1_token_data :api_key => api_key
|
|
38
|
+
expect(expiring_token).to carry_t1_token_data :role => default_role
|
|
39
|
+
expect(expiring_token).to carry_t1_token_data :expire_time => expire_time.to_i
|
|
40
|
+
expect(expiring_token).to carry_t1_token_data [:nonce, :create_time]
|
|
41
|
+
expect(expiring_token).to carry_valid_t1_token_signature api_secret
|
|
42
|
+
end
|
|
28
43
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
44
|
+
it "generates tokens with a role" do
|
|
45
|
+
role = :moderator
|
|
46
|
+
role_token = session.generate_token :role => role, :token_type => "T1"
|
|
47
|
+
expect(role_token).to be_an_instance_of String
|
|
48
|
+
expect(role_token).to carry_t1_token_data :session_id => session_id
|
|
49
|
+
expect(role_token).to carry_t1_token_data :api_key => api_key
|
|
50
|
+
expect(role_token).to carry_t1_token_data :role => role
|
|
51
|
+
expect(role_token).to carry_t1_token_data [:nonce, :create_time]
|
|
52
|
+
expect(role_token).to carry_valid_t1_token_signature api_secret
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "generates tokens with data" do
|
|
56
|
+
data = "name=Johnny"
|
|
57
|
+
data_bearing_token = session.generate_token :data => data, :token_type => "T1"
|
|
58
|
+
expect(data_bearing_token).to be_an_instance_of String
|
|
59
|
+
expect(data_bearing_token).to carry_t1_token_data :session_id => session_id
|
|
60
|
+
expect(data_bearing_token).to carry_t1_token_data :api_key => api_key
|
|
61
|
+
expect(data_bearing_token).to carry_t1_token_data :role => default_role
|
|
62
|
+
expect(data_bearing_token).to carry_t1_token_data :data => data
|
|
63
|
+
expect(data_bearing_token).to carry_t1_token_data [:nonce, :create_time]
|
|
64
|
+
expect(data_bearing_token).to carry_valid_t1_token_signature api_secret
|
|
65
|
+
end
|
|
39
66
|
end
|
|
40
67
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
68
|
+
context "when token type is JWT" do
|
|
69
|
+
it "generates plain tokens" do
|
|
70
|
+
plain_token = session.generate_token :token_type => "JWT"
|
|
71
|
+
expect(plain_token).to be_an_instance_of String
|
|
72
|
+
expect(plain_token).to carry_jwt_token_data :session_id => session_id
|
|
73
|
+
expect(plain_token).to carry_jwt_token_data :iss => api_key
|
|
74
|
+
expect(plain_token).to carry_jwt_token_data :ist => ist
|
|
75
|
+
expect(plain_token).to carry_jwt_token_data :scope => scope
|
|
76
|
+
expect(plain_token).to carry_jwt_token_data :role => default_role
|
|
77
|
+
expect(plain_token).to carry_jwt_token_data [:ist, :iat, :nonce]
|
|
78
|
+
expect(plain_token).to carry_valid_jwt_token_signature api_secret
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "generates tokens with a custom expire time" do
|
|
82
|
+
expire_time = Time.now + (60*60*24)
|
|
83
|
+
expiring_token = session.generate_token :expire_time => expire_time, :token_type => "JWT"
|
|
84
|
+
expect(expiring_token).to be_an_instance_of String
|
|
85
|
+
expect(expiring_token).to carry_jwt_token_data :session_id => session_id
|
|
86
|
+
expect(expiring_token).to carry_jwt_token_data :iss => api_key
|
|
87
|
+
expect(expiring_token).to carry_jwt_token_data :ist => ist
|
|
88
|
+
expect(expiring_token).to carry_jwt_token_data :scope => scope
|
|
89
|
+
expect(expiring_token).to carry_jwt_token_data :role => default_role
|
|
90
|
+
expect(expiring_token).to carry_jwt_token_data :exp => expire_time.to_i
|
|
91
|
+
expect(expiring_token).to carry_jwt_token_data [:ist, :iat, :nonce]
|
|
92
|
+
expect(expiring_token).to carry_valid_jwt_token_signature api_secret
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it "generates tokens with a non-default role" do
|
|
96
|
+
role = :moderator
|
|
97
|
+
role_token = session.generate_token :role => role, :token_type => "JWT"
|
|
98
|
+
expect(role_token).to be_an_instance_of String
|
|
99
|
+
expect(role_token).to carry_jwt_token_data :session_id => session_id
|
|
100
|
+
expect(role_token).to carry_jwt_token_data :iss => api_key
|
|
101
|
+
expect(role_token).to carry_jwt_token_data :ist => ist
|
|
102
|
+
expect(role_token).to carry_jwt_token_data :scope => scope
|
|
103
|
+
expect(role_token).to carry_jwt_token_data :role => role
|
|
104
|
+
expect(role_token).to carry_jwt_token_data [:ist, :iat, :nonce]
|
|
105
|
+
expect(role_token).to carry_valid_jwt_token_signature api_secret
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it "generates tokens with data" do
|
|
109
|
+
data = "name=Johnny"
|
|
110
|
+
data_bearing_token = session.generate_token :data => data, :token_type => "JWT"
|
|
111
|
+
expect(data_bearing_token).to be_an_instance_of String
|
|
112
|
+
expect(data_bearing_token).to carry_jwt_token_data :session_id => session_id
|
|
113
|
+
expect(data_bearing_token).to carry_jwt_token_data :iss => api_key
|
|
114
|
+
expect(data_bearing_token).to carry_jwt_token_data :ist => ist
|
|
115
|
+
expect(data_bearing_token).to carry_jwt_token_data :scope => scope
|
|
116
|
+
expect(data_bearing_token).to carry_jwt_token_data :role => default_role
|
|
117
|
+
expect(data_bearing_token).to carry_jwt_token_data :connection_data => data
|
|
118
|
+
expect(data_bearing_token).to carry_jwt_token_data [:ist, :iat, :nonce]
|
|
119
|
+
expect(data_bearing_token).to carry_valid_jwt_token_signature api_secret
|
|
120
|
+
end
|
|
50
121
|
end
|
|
51
122
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
expect(data_bearing_token).to carry_token_data :role => default_role
|
|
59
|
-
expect(data_bearing_token).to carry_token_data :data => data
|
|
60
|
-
expect(data_bearing_token).to carry_token_data [:nonce, :create_time]
|
|
61
|
-
expect(data_bearing_token).to carry_valid_token_signature api_secret
|
|
123
|
+
context "when token type is not specified" do
|
|
124
|
+
it "generates a JWT token by default" do
|
|
125
|
+
default_token = session.generate_token
|
|
126
|
+
expect(default_token).to be_an_instance_of String
|
|
127
|
+
expect(default_token).to carry_valid_jwt_token_signature api_secret
|
|
128
|
+
end
|
|
62
129
|
end
|
|
63
130
|
|
|
131
|
+
context "when token type is invalid" do
|
|
132
|
+
it "raises an error" do
|
|
133
|
+
expect { session.generate_token :token_type => "invalid_token_type" }.to raise_error
|
|
134
|
+
end
|
|
135
|
+
end
|
|
64
136
|
|
|
65
137
|
# TODO a context about using a bad session_id
|
|
66
138
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: opentok
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Stijn Mathysen
|
|
@@ -12,7 +12,7 @@ authors:
|
|
|
12
12
|
autorequire:
|
|
13
13
|
bindir: bin
|
|
14
14
|
cert_chain: []
|
|
15
|
-
date:
|
|
15
|
+
date: 2025-02-06 00:00:00.000000000 Z
|
|
16
16
|
dependencies:
|
|
17
17
|
- !ruby/object:Gem::Dependency
|
|
18
18
|
name: bundler
|