Repository: opentok/Opentok-Python-SDK

Issue:
add an "iat" claim to opentok-auth tokens
something we overlooked before, but we're now trying to add into the OpenTok-Auth JWTs: https://tools.ietf.org/html/rfc7519#section-4.1.6.

Discussion:

Patch:
diff --git a/opentok/opentok.py b/opentok/opentok.py
index d3f855f..61899fd 100644
--- a/opentok/opentok.py
+++ b/opentok/opentok.py
@@ -275,7 +275,7 @@ class OpenTok(object):
         """For internal use."""
         return {
             'User-Agent': 'OpenTok-Python-SDK/' + __version__ + ' ' + platform.python_version(),
-            'X-TB-OPENTOK-AUTH': self._create_jwt_auth_header()
+            'X-OPENTOK-AUTH': self._create_jwt_auth_header()
         }
 
     def archive_headers(self):
@@ -451,7 +451,8 @@ class OpenTok(object):
         payload = {
                       'ist': 'project',
                       'iss': self.api_key,
-                      'exp': int(time.time()) + (60*5), # 5 minutes
+                      'iat': int(time.time()), # current time in unix time (seconds)
+                      'exp': int(time.time()) + (60*3), # 3 minutes in the future (seconds)
                       'jti': '{:f}'.format(random.random())
                   }
 


Test patch:
diff --git a/tests/test_archive.py b/tests/test_archive.py
index b4a5995..7307f62 100644
--- a/tests/test_archive.py
+++ b/tests/test_archive.py
@@ -57,7 +57,7 @@ class OpenTokArchiveTest(unittest.TestCase):
 
         archive.stop()
 
-        validate_jwt_header(self, httpretty.last_request().headers[u('x-tb-opentok-auth')])
+        validate_jwt_header(self, httpretty.last_request().headers[u('x-opentok-auth')])
         expect(httpretty.last_request().headers[u('user-agent')]).to.contain(u('OpenTok-Python-SDK/')+__version__)
         expect(httpretty.last_request().headers[u('content-type')]).to.equal(u('application/json'))
         expect(archive).to.be.an(Archive)
@@ -102,7 +102,7 @@ class OpenTokArchiveTest(unittest.TestCase):
 
         archive.delete()
 
-        validate_jwt_header(self, httpretty.last_request().headers[u('x-tb-opentok-auth')])
+        validate_jwt_header(self, httpretty.last_request().headers[u('x-opentok-auth')])
         expect(httpretty.last_request().headers[u('user-agent')]).to.contain(u('OpenTok-Python-SDK/')+__version__)
         expect(httpretty.last_request().headers[u('content-type')]).to.equal(u('application/json'))
         # TODO: test that the object is invalidated
diff --git a/tests/test_archive_api.py b/tests/test_archive_api.py
index f8f7ba9..e4aed1d 100644
--- a/tests/test_archive_api.py
+++ b/tests/test_archive_api.py
@@ -42,7 +42,7 @@ class OpenTokArchiveApiTest(unittest.TestCase):
 
         archive = self.opentok.start_archive(self.session_id)
 
-        validate_jwt_header(self, httpretty.last_request().headers[u('x-tb-opentok-auth')])
+        validate_jwt_header(self, httpretty.last_request().headers[u('x-opentok-auth')])
         expect(httpretty.last_request().headers[u('user-agent')]).to.contain(u('OpenTok-Python-SDK/')+__version__)
         expect(httpretty.last_request().headers[u('content-type')]).to.equal(u('application/json'))
         # non-deterministic json encoding. have to decode to test it properly
@@ -93,7 +93,7 @@ class OpenTokArchiveApiTest(unittest.TestCase):
 
         archive = self.opentok.start_archive(self.session_id, name=u('ARCHIVE NAME'))
 
-        validate_jwt_header(self, httpretty.last_request().headers[u('x-tb-opentok-auth')])
+        validate_jwt_header(self, httpretty.last_request().headers[u('x-opentok-auth')])
         expect(httpretty.last_request().headers[u('user-agent')]).to.contain(u('OpenTok-Python-SDK/')+__version__)
         expect(httpretty.last_request().headers[u('content-type')]).to.equal(u('application/json'))
         # non-deterministic json encoding. have to decode to test it properly
@@ -142,7 +142,7 @@ class OpenTokArchiveApiTest(unittest.TestCase):
 
         archive = self.opentok.start_archive(self.session_id, name=u('ARCHIVE NAME'), has_video=False)
 
-        validate_jwt_header(self, httpretty.last_request().headers[u('x-tb-opentok-auth')])
+        validate_jwt_header(self, httpretty.last_request().headers[u('x-opentok-auth')])
         expect(httpretty.last_request().headers[u('user-agent')]).to.contain(u('OpenTok-Python-SDK/')+__version__)
         expect(httpretty.last_request().headers[u('content-type')]).to.equal(u('application/json'))
         # non-deterministic json encoding. have to decode to test it properly
@@ -193,7 +193,7 @@ class OpenTokArchiveApiTest(unittest.TestCase):
 
         archive = self.opentok.start_archive(self.session_id, name=u('ARCHIVE NAME'), output_mode=OutputModes.individual)
 
-        validate_jwt_header(self, httpretty.last_request().headers[u('x-tb-opentok-auth')])
+        validate_jwt_header(self, httpretty.last_request().headers[u('x-opentok-auth')])
         expect(httpretty.last_request().headers[u('user-agent')]).to.contain(u('OpenTok-Python-SDK/')+__version__)
         expect(httpretty.last_request().headers[u('content-type')]).to.equal(u('application/json'))
         # non-deterministic json encoding. have to decode to test it properly
@@ -245,7 +245,7 @@ class OpenTokArchiveApiTest(unittest.TestCase):
 
         archive = self.opentok.start_archive(self.session_id, name=u('ARCHIVE NAME'), output_mode=OutputModes.composed)
 
-        validate_jwt_header(self, httpretty.last_request().headers[u('x-tb-opentok-auth')])
+        validate_jwt_header(self, httpretty.last_request().headers[u('x-opentok-auth')])
         expect(httpretty.last_request().headers[u('user-agent')]).to.contain(u('OpenTok-Python-SDK/')+__version__)
         expect(httpretty.last_request().headers[u('content-type')]).to.equal(u('application/json'))
         # non-deterministic json encoding. have to decode to test it properly
@@ -298,7 +298,7 @@ class OpenTokArchiveApiTest(unittest.TestCase):
 
         archive = self.opentok.stop_archive(archive_id)
 
-        validate_jwt_header(self, httpretty.last_request().headers[u('x-tb-opentok-auth')])
+        validate_jwt_header(self, httpretty.last_request().headers[u('x-opentok-auth')])
         expect(httpretty.last_request().headers[u('user-agent')]).to.contain(u('OpenTok-Python-SDK/')+__version__)
         expect(httpretty.last_request().headers[u('content-type')]).to.equal(u('application/json'))
         expect(archive).to.be.an(Archive)
@@ -325,7 +325,7 @@ class OpenTokArchiveApiTest(unittest.TestCase):
 
         self.opentok.delete_archive(archive_id)
 
-        validate_jwt_header(self, httpretty.last_request().headers[u('x-tb-opentok-auth')])
+        validate_jwt_header(self, httpretty.last_request().headers[u('x-opentok-auth')])
         expect(httpretty.last_request().headers[u('user-agent')]).to.contain(u('OpenTok-Python-SDK/')+__version__)
         expect(httpretty.last_request().headers[u('content-type')]).to.equal(u('application/json'))
 
@@ -354,7 +354,7 @@ class OpenTokArchiveApiTest(unittest.TestCase):
 
         archive = self.opentok.get_archive(archive_id)
 
-        validate_jwt_header(self, httpretty.last_request().headers[u('x-tb-opentok-auth')])
+        validate_jwt_header(self, httpretty.last_request().headers[u('x-opentok-auth')])
         expect(httpretty.last_request().headers[u('user-agent')]).to.contain(u('OpenTok-Python-SDK/')+__version__)
         expect(httpretty.last_request().headers[u('content-type')]).to.equal(u('application/json'))
         expect(archive).to.be.an(Archive)
@@ -469,7 +469,7 @@ class OpenTokArchiveApiTest(unittest.TestCase):
 
         archive_list = self.opentok.get_archives()
 
-        validate_jwt_header(self, httpretty.last_request().headers[u('x-tb-opentok-auth')])
+        validate_jwt_header(self, httpretty.last_request().headers[u('x-opentok-auth')])
         expect(httpretty.last_request().headers[u('user-agent')]).to.contain(u('OpenTok-Python-SDK/')+__version__)
         expect(httpretty.last_request().headers[u('content-type')]).to.equal(u('application/json'))
         expect(archive_list).to.be.an(ArchiveList)
@@ -529,7 +529,7 @@ class OpenTokArchiveApiTest(unittest.TestCase):
 
         archive_list = self.opentok.get_archives(offset=3)
 
-        validate_jwt_header(self, httpretty.last_request().headers[u('x-tb-opentok-auth')])
+        validate_jwt_header(self, httpretty.last_request().headers[u('x-opentok-auth')])
         expect(httpretty.last_request().headers[u('user-agent')]).to.contain(u('OpenTok-Python-SDK/')+__version__)
         expect(httpretty.last_request().headers[u('content-type')]).to.equal(u('application/json'))
         expect(httpretty.last_request()).to.have.property("querystring").being.equal({
@@ -579,7 +579,7 @@ class OpenTokArchiveApiTest(unittest.TestCase):
 
         archive_list = self.opentok.get_archives(count=2)
 
-        validate_jwt_header(self, httpretty.last_request().headers[u('x-tb-opentok-auth')])
+        validate_jwt_header(self, httpretty.last_request().headers[u('x-opentok-auth')])
         expect(httpretty.last_request().headers[u('user-agent')]).to.contain(u('OpenTok-Python-SDK/')+__version__)
         expect(httpretty.last_request().headers[u('content-type')]).to.equal(u('application/json'))
         expect(httpretty.last_request()).to.have.property("querystring").being.equal({
@@ -655,7 +655,7 @@ class OpenTokArchiveApiTest(unittest.TestCase):
 
         archive_list = self.opentok.get_archives(count=4, offset=2)
 
-        validate_jwt_header(self, httpretty.last_request().headers[u('x-tb-opentok-auth')])
+        validate_jwt_header(self, httpretty.last_request().headers[u('x-opentok-auth')])
         expect(httpretty.last_request().headers[u('user-agent')]).to.contain(u('OpenTok-Python-SDK/')+__version__)
         expect(httpretty.last_request().headers[u('content-type')]).to.equal(u('application/json'))
         expect(httpretty.last_request()).to.have.property("querystring").being.equal({
diff --git a/tests/test_session_creation.py b/tests/test_session_creation.py
index 804e348..e25c717 100644
--- a/tests/test_session_creation.py
+++ b/tests/test_session_creation.py
@@ -23,7 +23,7 @@ class OpenTokSessionCreationTest(unittest.TestCase):
 
         session = self.opentok.create_session()
 
-        validate_jwt_header(self, httpretty.last_request().headers[u('x-tb-opentok-auth')])
+        validate_jwt_header(self, httpretty.last_request().headers[u('x-opentok-auth')])
         expect(httpretty.last_request().headers[u('user-agent')]).to.contain(u('OpenTok-Python-SDK/')+__version__)
         body = parse_qs(httpretty.last_request().body)
         expect(body).to.have.key(b('p2p.preference')).being.equal([b('enabled')])
@@ -42,7 +42,7 @@ class OpenTokSessionCreationTest(unittest.TestCase):
 
         session = self.opentok.create_session(media_mode=MediaModes.routed)
 
-        validate_jwt_header(self, httpretty.last_request().headers[u('x-tb-opentok-auth')])
+        validate_jwt_header(self, httpretty.last_request().headers[u('x-opentok-auth')])
         expect(httpretty.last_request().headers[u('user-agent')]).to.contain(u('OpenTok-Python-SDK/')+__version__)
         body = parse_qs(httpretty.last_request().body)
         expect(body).to.have.key(b('p2p.preference')).being.equal([b('disabled')])
@@ -61,7 +61,7 @@ class OpenTokSessionCreationTest(unittest.TestCase):
 
         session = self.opentok.create_session(location='12.34.56.78')
 
-        validate_jwt_header(self, httpretty.last_request().headers[u('x-tb-opentok-auth')])
+        validate_jwt_header(self, httpretty.last_request().headers[u('x-opentok-auth')])
         expect(httpretty.last_request().headers[u('user-agent')]).to.contain(u('OpenTok-Python-SDK/')+__version__)
         # ordering of keys is non-deterministic, must parse the body to see if it is correct
         body = parse_qs(httpretty.last_request().body)
@@ -81,7 +81,7 @@ class OpenTokSessionCreationTest(unittest.TestCase):
 
         session = self.opentok.create_session(location='12.34.56.78', media_mode=MediaModes.routed)
 
-        validate_jwt_header(self, httpretty.last_request().headers[u('x-tb-opentok-auth')])
+        validate_jwt_header(self, httpretty.last_request().headers[u('x-opentok-auth')])
         expect(httpretty.last_request().headers[u('user-agent')]).to.contain(u('OpenTok-Python-SDK/')+__version__)
         # ordering of keys is non-deterministic, must parse the body to see if it is correct
         body = parse_qs(httpretty.last_request().body)
@@ -101,7 +101,7 @@ class OpenTokSessionCreationTest(unittest.TestCase):
 
         session = self.opentok.create_session(media_mode=MediaModes.routed, archive_mode=ArchiveModes.manual)
 
-        validate_jwt_header(self, httpretty.last_request().headers[u('x-tb-opentok-auth')])
+        validate_jwt_header(self, httpretty.last_request().headers[u('x-opentok-auth')])
         expect(httpretty.last_request().headers[u('user-agent')]).to.contain(u('OpenTok-Python-SDK/')+__version__)
         body = parse_qs(httpretty.last_request().body)
         expect(body).to.have.key(b('p2p.preference')).being.equal([b('disabled')])
@@ -120,7 +120,7 @@ class OpenTokSessionCreationTest(unittest.TestCase):
 
         session = self.opentok.create_session(media_mode=MediaModes.routed, archive_mode=ArchiveModes.always)
 
-        validate_jwt_header(self, httpretty.last_request().headers[u('x-tb-opentok-auth')])
+        validate_jwt_header(self, httpretty.last_request().headers[u('x-opentok-auth')])
         expect(httpretty.last_request().headers[u('user-agent')]).to.contain(u('OpenTok-Python-SDK/')+__version__)
         body = parse_qs(httpretty.last_request().body)
         expect(body).to.have.key(b('p2p.preference')).being.equal([b('disabled')])