opentok 4.8.1 → 4.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +1 -1
- data/CHANGES.md +8 -0
- data/Gemfile +2 -0
- data/README.md +10 -0
- data/lib/opentok/constants.rb +1 -1
- 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 +269 -71
- data/spec/shared/session_generates_tokens.rb +110 -38
- metadata +3 -3
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,11 @@
|
|
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
|
+
|
5
|
+
# 4.9.0
|
6
|
+
|
7
|
+
* Adds the `publisheronly` role for client token creation. See [#272](https://github.com/opentok/OpenTok-Ruby-SDK/pull/272)
|
8
|
+
|
1
9
|
# 4.8.1
|
2
10
|
|
3
11
|
* Fixes a bug with the `Archives#create` method. See [#269](https://github.com/opentok/OpenTok-Ruby-SDK/pull/269) and [#270](https://github.com/opentok/OpenTok-Ruby-SDK/pull/270)
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -20,6 +20,16 @@ The OpenTok Ruby SDK provides methods for:
|
|
20
20
|
* Working with OpenTok [Experience Composers](https://tokbox.com/developer/guides/experience-composer)
|
21
21
|
* Working with OpenTok [Audio Connector](https://tokbox.com/developer/guides/audio-connector)
|
22
22
|
|
23
|
+
## Note!
|
24
|
+
|
25
|
+
This library is designed to work with the Tokbox/OpenTok platform, part of the Vonage Video API. If you are looking to use the Vonage Video API and using the Vonage Customer Dashboard, you will want to install the [Vonage Server SDK for Ruby](https://github.com/Vonage/vonage-ruby-sdk), which includes support for the Vonage Video API.
|
26
|
+
|
27
|
+
Not sure which exact platform you are using? Take a look at [this guide](https://api.support.vonage.com/hc/en-us/articles/10817774782492).
|
28
|
+
|
29
|
+
If you are using the Tokbox platform, do not worry! The Tokbox platform is not going away, and this library will continue to be updated. While we encourage customers to check out the new Unified platform, there is no rush to switch. Both platforms run the exact same infrastructure and capabilities, with the main difference is a unified billing interface and easier access to [Vonage’s other CPaaS APIs](https://www.vonage.com/communications-apis/).
|
30
|
+
|
31
|
+
If you are new to the Vonage Video API, head on over to the [Vonage Customer Dashboard](https://dashboard.vonage.com) to sign up for a developer account and check out the [Vonage Server SDK for Ruby](https://github.com/Vonage/vonage-ruby-sdk).
|
32
|
+
|
23
33
|
## Installation
|
24
34
|
|
25
35
|
### Bundler (recommended):
|
data/lib/opentok/constants.rb
CHANGED
@@ -2,7 +2,7 @@ module OpenTok
|
|
2
2
|
require "set"
|
3
3
|
API_URL = "https://api.opentok.com"
|
4
4
|
TOKEN_SENTINEL = "T1=="
|
5
|
-
ROLES = { subscriber: "subscriber", publisher: "publisher", moderator: "moderator" }
|
5
|
+
ROLES = { subscriber: "subscriber", publisher: "publisher", moderator: "moderator", publisheronly: "publisheronly" }
|
6
6
|
ARCHIVE_MODES = ::Set.new([:manual, :always])
|
7
7
|
AUTH_EXPIRE = 300
|
8
8
|
end
|
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,88 +15,286 @@ 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
|
66
|
+
|
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
|
77
|
+
|
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
|
63
88
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
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
|
99
|
+
|
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
|
74
141
|
end
|
75
142
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
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
|
86
283
|
end
|
87
284
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
expect(layout_class_bearing_token).to carry_token_data :role => default_role
|
95
|
-
expect(layout_class_bearing_token).to carry_token_data :initial_layout_class_list => layout_class
|
96
|
-
expect(layout_class_bearing_token).to carry_token_data [:nonce, :create_time]
|
97
|
-
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
|
98
291
|
end
|
99
292
|
|
293
|
+
context "when token type is invalid" do
|
294
|
+
it "raises an error" do
|
295
|
+
expect { opentok.generate_token session_id, :token_type => "invalid_token_type" }.to raise_error
|
296
|
+
end
|
297
|
+
end
|
100
298
|
|
101
299
|
# TODO a context about using a bad session_id
|
102
300
|
end
|
@@ -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
|
@@ -355,7 +355,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
355
355
|
- !ruby/object:Gem::Version
|
356
356
|
version: '0'
|
357
357
|
requirements: []
|
358
|
-
rubygems_version: 3.5.
|
358
|
+
rubygems_version: 3.5.4
|
359
359
|
signing_key:
|
360
360
|
specification_version: 4
|
361
361
|
summary: Ruby gem for the OpenTok API
|