Skip to content

Commit

Permalink
fix + access_token tests
Browse files Browse the repository at this point in the history
  • Loading branch information
theomonnom committed Nov 14, 2023
1 parent b8b9e5b commit 05a234c
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 19 deletions.
4 changes: 2 additions & 2 deletions livekit-api/livekit/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@
from livekit.protocol import models
from livekit.protocol import room

from .api import LiveKitAPI
from .access_token import VideoGrants, AccessToken
from .livekit_api import LiveKitAPI
from .access_token import VideoGrants, AccessToken, TokenVerifier
from .version import __version__
42 changes: 27 additions & 15 deletions livekit-api/livekit/api/access_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@

import calendar
import dataclasses
import re
import datetime
import os

import jwt

DEFAULT_TTL = datetime.timedelta(hours=6)
Expand Down Expand Up @@ -64,6 +64,11 @@ class VideoGrants:

@dataclasses.dataclass
class Claims:
exp: int = 0
iss: str = "" # api key
nbf: int = 0
sub: str = "" # identity

name: str = ""
video: VideoGrants = dataclasses.field(default_factory=VideoGrants)
metadata: str = ""
Expand Down Expand Up @@ -111,17 +116,12 @@ def with_sha256(self, sha256: str) -> "AccessToken":
return self

def to_jwt(self) -> str:
def camel_case_dict(data) -> dict:
return {
"".join(
word if i == 0 else word.title()
for i, word in enumerate(key.split("_"))
): value
for key, value in data
if value is not None
}
video = self.claims.video
if video.room_join and (not self.identity or not video.room):
raise ValueError("identity and room must be set when joining a room")

claims = dataclasses.asdict(self.claims)
claims = {camel_to_snake(k): v for k, v in claims.items()}
claims.update(
{
"sub": self.identity,
Expand All @@ -130,9 +130,6 @@ def camel_case_dict(data) -> dict:
"exp": calendar.timegm(
(datetime.datetime.utcnow() + self.ttl).utctimetuple()
),
"video": dataclasses.asdict(
self.claims.video, dict_factory=camel_case_dict
),
}
)

Expand All @@ -144,16 +141,31 @@ def __init__(
self,
api_key: str = os.getenv("LIVEKIT_API_KEY", ""),
api_secret: str = os.getenv("LIVEKIT_API_SECRET", ""),
*,
leeway: datetime.timedelta = DEFAULT_LEEWAY,
) -> None:
self.api_key = api_key
self.api_secret = api_secret
self._leeway = leeway

def verify(self, token: str) -> Claims:
claims = jwt.decode(
token,
self.api_secret,
issuer=self.api_key,
algorithms=["HS256"],
leeway=DEFAULT_LEEWAY.total_seconds(),
leeway=self._leeway.total_seconds(),
)
return Claims(**claims)
c = Claims(**claims)

video = claims["video"]
video = {camel_to_snake(k): v for k, v in video.items()}
c.video = VideoGrants(**video)
return c


def camel_to_snake(str):
return re.sub(r'(?<!^)(?=[A-Z])', '_', str).lower()

def snake_to_camel(str):
return ''.join(word.title() for word in name.split('_'))

Check failure on line 171 in livekit-api/livekit/api/access_token.py

View workflow job for this annotation

GitHub Actions / build

Ruff (F821)

livekit-api/livekit/api/access_token.py:171:45: F821 Undefined name `name`
4 changes: 2 additions & 2 deletions livekit-api/livekit/api/egress_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def __init__(
super().__init__(session, url, api_key, api_secret)

async def start_room_composite_egress(
self, start: proto_egress.StartRoomCompositeEgressRequest
self, start: proto_egress.RoomCompositeEgressRequest
) -> proto_egress.EgressInfo:
return await self._client.request(
SVC,
Expand All @@ -24,7 +24,7 @@ async def start_room_composite_egress(
)

async def start_web_egress(
self, start: proto_egress.StartWebEgressRequest
self, start: proto_egress.WebEgressRequest
) -> proto_egress.EgressInfo:
return await self._client.request(
SVC,
Expand Down
File renamed without changes.
49 changes: 49 additions & 0 deletions livekit-api/tests/test_access_token.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import pytest
import datetime
from livekit.api import AccessToken, TokenVerifier, VideoGrants

TEST_API_KEY = "myapikey"
TEST_API_SECRET = "thiskeyistotallyunsafe"


def test_verify_token():
grants = VideoGrants(room_join=True, room="test_room")

token = (
AccessToken(TEST_API_KEY, TEST_API_SECRET)
.with_identity("test_identity")
.with_metadata("test_metadata")
.with_grants(grants)
.to_jwt()
)

token_verifier = TokenVerifier(TEST_API_KEY, TEST_API_SECRET)
claims = token_verifier.verify(token)

assert claims.sub == "test_identity"
assert claims.metadata == "test_metadata"
assert claims.video == grants


def test_verify_token_invalid():
token = (
AccessToken(TEST_API_KEY, TEST_API_SECRET)
.with_identity("test_identity")
.to_jwt()
)

token_verifier = TokenVerifier(TEST_API_KEY, "invalid_secret")
with pytest.raises(Exception):
token_verifier.verify(token)

def test_verify_token_expired():
token = (
AccessToken(TEST_API_KEY, TEST_API_SECRET)
.with_identity("test_identity")
.with_ttl(datetime.timedelta(seconds=0))
.to_jwt()
)

token_verifier = TokenVerifier(TEST_API_KEY, TEST_API_SECRET, leeway=datetime.timedelta(seconds=0))
with pytest.raises(Exception):
token_verifier.verify(token)

0 comments on commit 05a234c

Please sign in to comment.