Skip to content

Commit

Permalink
refactor jwt package, get tests passing
Browse files Browse the repository at this point in the history
  • Loading branch information
maxkahan committed May 15, 2024
1 parent 445cab8 commit a7a686c
Show file tree
Hide file tree
Showing 12 changed files with 60 additions and 33 deletions.
16 changes: 16 additions & 0 deletions jwt/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
resource(name='pyproject', source='pyproject.toml')
file(name='readme', source='README.md')

files(sources=['tests/data/*'])

python_distribution(
name='vonage-jwt',
dependencies=[
':pyproject',
':readme',
'jwt/src/vonage_jwt',
],
provides=python_artifact(),
generate_setup=False,
repositories=['@pypi'],
)
4 changes: 4 additions & 0 deletions jwt/CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 1.1.1
- Exceptions inherit from `VonageError`
- Moving the package into the Vonage Python SDK monorepo

# 1.1.0
- Add new module with method to verify JWT signatures, `verify_jwt.verify_signature`

Expand Down
8 changes: 4 additions & 4 deletions jwt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

This package (`vonage-jwt`) provides functionality to generate a JWT in Python code.

It is used by the [Vonage Python SDK](https://github.com/Vonage/vonage-python-sdk), specifically by the `vonage-http-client` package, to generate JWTs for authentication. Thus, it doesn't require manual installation or configuration unless you're using this package independently of a SDK.
It is used by the [Vonage Python SDK](https://github.com/Vonage/vonage-python-sdk), specifically by the `vonage-http-client` package, to generate JWTs for authentication. Thus, it doesn't require manual installation or configuration unless you're using this package independently of an SDK.

For full API documentation, refer to the [Vonage Developer documentation](https://developer.vonage.com).
For full API documentation, refer to the [Vonage developer documentation](https://developer.vonage.com).

- [Installation](#installation)
- [Generating JWTs](#generating-jwts)
Expand All @@ -27,7 +27,7 @@ It can also be used as a standalone JWT generator for use with Vonage APIs, like
### Import the `JwtClient` object

```python
from vonage_jwt.jwt import JwtClient
from vonage_jwt import JwtClient
```

### Create a `JwtClient` object
Expand All @@ -54,7 +54,7 @@ jwt_client.generate_application_jwt(claims)
You can use the `verify_jwt.verify_signature` method to verify a JWT signature is valid.

```python
from vonage_jwt.verify_jwt import verify_signature
from vonage_jwt import verify_signature

verify_signature(TOKEN, SIGNATURE_SECRET) # Returns a boolean
```
4 changes: 1 addition & 3 deletions jwt/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ description = "Tooling for working with JWTs for Vonage APIs in Python."
readme = "README.md"
authors = [{ name = "Vonage", email = "devrel@vonage.com" }]
requires-python = ">=3.8"
dependencies = [
"pyjwt[crypto] >=1.6.4"
]
dependencies = ["vonage-utils>=1.1.2", "pyjwt[crypto]>=1.6.4"]
classifiers = [
"Programming Language :: Python",
"Programming Language :: Python :: 3",
Expand Down
5 changes: 3 additions & 2 deletions jwt/src/vonage_jwt/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .jwt import JwtClient, VonageJwtError
from .errors import VonageJwtError, VonageVerifyJwtError
from .jwt import JwtClient
from .verify_jwt import verify_signature

__all__ = ['JwtClient', 'VonageJwtError', 'verify_signature']
__all__ = ['JwtClient', 'VonageJwtError', 'VonageVerifyJwtError', 'verify_signature']
9 changes: 9 additions & 0 deletions jwt/src/vonage_jwt/errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from vonage_utils import VonageError


class VonageJwtError(VonageError):
"""An error relating to the Vonage JWT Generator."""


class VonageVerifyJwtError(VonageError):
"""The signature could not be verified."""
15 changes: 7 additions & 8 deletions jwt/src/vonage_jwt/jwt.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import re
from time import time
from jwt import encode
from uuid import uuid4
from typing import Union
from uuid import uuid4

from jwt import encode

from .errors import VonageJwtError


class JwtClient:
Expand All @@ -22,8 +25,8 @@ def __init__(self, application_id: str, private_key: str):
)

def generate_application_jwt(self, jwt_options: dict = {}):
"""
Generates a JWT for the specified Vonage application.
"""Generates a JWT for the specified Vonage application.
You can override values for application_id and private_key on the JWTClient object by
specifying them in the `jwt_options` dict if required.
"""
Expand Down Expand Up @@ -51,7 +54,3 @@ def _set_private_key(self, key: Union[str, bytes]):
)
else:
self._private_key = key


class VonageJwtError(Exception):
"""An error relating to the Vonage JWT Generator."""
10 changes: 3 additions & 7 deletions jwt/src/vonage_jwt/verify_jwt.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from jwt import InvalidSignatureError, decode

from .errors import VonageVerifyJwtError


def verify_signature(token: str, signature_secret: str = None) -> bool:
"""
Method to verify that an incoming JWT was sent by Vonage.
"""
"""Method to verify that an incoming JWT was sent by Vonage."""

try:
decode(token, signature_secret, algorithms='HS256')
Expand All @@ -13,7 +13,3 @@ def verify_signature(token: str, signature_secret: str = None) -> bool:
return False
except Exception as e:
raise VonageVerifyJwtError(repr(e))


class VonageVerifyJwtError(Exception):
"""The signature could not be verified."""
2 changes: 1 addition & 1 deletion jwt/tests/BUILD
Original file line number Diff line number Diff line change
@@ -1 +1 @@
python_tests(dependencies=['messages', 'testutils'])
python_tests(dependencies=['jwt', 'testutils'])
16 changes: 9 additions & 7 deletions jwt/tests/test_jwt_generator.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
from vonage_jwt.jwt import JwtClient, VonageJwtError
from os import environ
from os.path import dirname, join
from time import time

import os
from jwt.exceptions import ImmatureSignatureError
from pytest import raises
from vonage_jwt.jwt import JwtClient, VonageJwtError

from jwt import decode
from jwt.exceptions import ImmatureSignatureError
from time import time

# Ensure the client isn't being configured with real values
os.environ.clear()
environ.clear()


def read_file(path):
with open(os.path.join(os.path.dirname(__file__), path)) as input_file:
with open(join(dirname(__file__), path)) as input_file:
return input_file.read()


application_id = 'asdf1234'
private_key_string = read_file('data/private_key.txt')
private_key_file_path = './tests/data/private_key.txt'
private_key_file_path = 'jwt/tests/data/private_key.txt'
jwt_client = JwtClient(application_id, private_key_file_path)

public_key = read_file('data/public_key.txt')
Expand Down
3 changes: 2 additions & 1 deletion jwt/tests/test_verify_jwt.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from vonage_jwt.verify_jwt import verify_signature, VonageVerifyJwtError
import pytest
from vonage_jwt.errors import VonageVerifyJwtError
from vonage_jwt.verify_jwt import verify_signature

token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2OTc2MzQ2ODAsImV4cCI6MzMyNTQ1NDA4MjgsImF1ZCI6IiIsInN1YiI6IiJ9.88vJc3I2HhuqEDixHXVhc9R30tA6U_HQHZTC29y6CGM'
valid_signature = "qwertyuiopasdfghjklzxcvbnm123456"
Expand Down
1 change: 1 addition & 0 deletions pants.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ filter = [
'vonage/src',
'http_client/src',
'application/src',
'jwt/src',
'messages/src',
'number_insight/src',
'number_insight_v2/src',
Expand Down

0 comments on commit a7a686c

Please sign in to comment.