Skip to content

Commit

Permalink
Add an option to secure the session_token cookie
Browse files Browse the repository at this point in the history
Remove dedicated process for SSL redirect service
Move all hyperlinks from `PyStream` to `open-source`
  • Loading branch information
dormant-user committed Feb 19, 2024
1 parent 5cd74c7 commit a8aa05a
Show file tree
Hide file tree
Showing 12 changed files with 238 additions and 298 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ if __name__ == '__main__':
- **WORKERS**: Number of workers to spin up the `uvicorn` server. Defaults to `1`
- **WEBSITE**: List of websites (_supports regex_) to add to CORS configuration. _Required only if tunneled via CDN_
- **AUTO_THUMBNAIL**: Boolean flag to auto generate thumbnail images for preview. Defaults to `True`
- **SECURE_SESSION**: Boolean flag to secure the cookie `session_token` to restrict serving **_ONLY_** via **HTTPS**.
Defaults to `False`
- **KEY_FILE**: Path to the private key file for SSL certificate. Defaults to `None`
- **CERT_FILE**: Path to the full chain file for SSL certificate. Defaults to `None`
> :bulb:   `KEY_FILE` and `CERT_FILE` becomes mandatory when `VIDEO_PORT` is set to `443`
Expand Down
7 changes: 0 additions & 7 deletions doc_gen/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,6 @@ Images
:members:
:undoc-members:

Secure
======

.. automodule:: pystream.models.secure
:members:
:undoc-members:

Squire
======

Expand Down
24 changes: 5 additions & 19 deletions pystream/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import os
import ssl
from multiprocessing import Process

import uvicorn
from fastapi import FastAPI, Request
Expand All @@ -9,7 +8,7 @@

from pystream.logger import logger
from pystream.models import config
from pystream.routers import auth, basics, secure, video
from pystream.routers import auth, basics, video

app = FastAPI()
app.include_router(auth.router)
Expand Down Expand Up @@ -94,20 +93,15 @@ async def start(**kwargs) -> None:
argument_dict["ssl_keyfile"] = config.env.key_file
argument_dict["ssl_certfile"] = config.env.cert_file
uvicorn_config = uvicorn.Config(**argument_dict)
# Initiate a dedicated server listening to port 80 and redirect it to 443
# app.add_middleware(HTTPSRedirectMiddleware)
# is an alternate option but it won't have the server listening on port 80
# so only internal relative links for CSS and JS will work, not user level redirect
if config.env.video_port == 443:
http_redirect = dict(app=f"{secure.__name__}:app", port=80, host=config.env.video_host)
process = Process(target=uvicorn.run, kwargs=(http_redirect))
process.start()
logger.info("SSL redirect service started on PID: %d", process.pid)
elif config.env.video_port == 443:
raise RuntimeWarning(
"'video_port' was set to 443, however 'cert_file' and 'key_file' are missing."
)
else:
if config.env.secure_session:
logger.warning(
"Secure session is turned on! This means that the server can ONLY be hosted via HTTPS or localhost"
)
uvicorn_config = uvicorn.Config(**argument_dict)
uvicorn_server = uvicorn.Server(config=uvicorn_config)

Expand All @@ -120,14 +114,6 @@ async def start(**kwargs) -> None:
await uvicorn_server.serve()
except ssl.SSLError as error:
logger.critical(error)
if config.env.video_port == 443:
logger.error("Failed to start server on HTTPS")
process.kill()
raise

logger.info("Initiating shutdown tasks")
await shutdown_tasks()

if config.env.video_port == 443:
logger.info("Shutting down SSL redirect service")
process.kill()
1 change: 1 addition & 0 deletions pystream/models/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class EnvConfig(BaseSettings):
auto_thumbnail: bool = True
key_file: Union[FilePath, None] = None
cert_file: Union[FilePath, None] = None
secure_session: bool = False

class Config:
"""Environment variables configuration."""
Expand Down
13 changes: 8 additions & 5 deletions pystream/routers/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,14 @@ async def login(request: Request) -> JSONResponse:
response = JSONResponse(content={"redirect_url": config.static.home_endpoint}, status_code=status.HTTP_200_OK)
expiration = get_expiry(lease_start=auth_payload['timestamp'], lease_duration=config.env.session_duration)
logger.info("Session for '%s' will be valid until %s", auth_payload['username'], expiration)
response.set_cookie(key="session_token",
value=config.static.cipher_suite.encrypt(str(auth_payload).encode("utf-8")).decode(),
max_age=config.env.session_duration,
expires=expiration,
httponly=True)
cookie_kwargs = dict(key="session_token",
value=config.static.cipher_suite.encrypt(str(auth_payload).encode("utf-8")).decode(),
max_age=config.env.session_duration,
expires=expiration,
httponly=True)
if config.env.secure_session:
cookie_kwargs["secure"] = True
response.set_cookie(**cookie_kwargs)
return response


Expand Down
19 changes: 0 additions & 19 deletions pystream/routers/secure.py

This file was deleted.

45 changes: 20 additions & 25 deletions pystream/templates/index.html
Original file line number Diff line number Diff line change
@@ -1,37 +1,13 @@
<!DOCTYPE html>
<!--suppress JSUnresolvedLibraryURL -->
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>FastAPI video streaming</title>
<meta property="og:type" content="VideoStreaming">
<meta name="keywords" content="Python, streaming, fastapi, JavaScript, HTML, CSS">
<meta name="author" content="Vignesh Rao">
<meta name="image" property="og:image" content="https://thevickypedia.com/img/apple-touch-icon.jpg">
<meta content="width=device-width, initial-scale=1" name="viewport">
<noscript>
<style>
body {
width: 100%;
height: 100%;
overflow: hidden;
}
</style>
<div style="position: fixed; text-align:center;
height: 100%; width: 100%; background-image: url('https://vigneshrao.com/img/auth_server/bg.jpg')">
<h2 style="margin-top:5%">This page requires JavaScript
to be enabled.
<br><br>
Please refer <a href="https://www.enable-javascript.com/">enable-javascript</a> for how to.
</h2>
<p>
<img src="https://vigneshrao.com/img/auth_server/javascript.gif" width="230" height="200"
alt="loader" class="center">
</p>
<form>
<button type="submit" onClick="<meta httpEquiv='refresh' content='0'>">RETRY</button>
</form>
</div>
</noscript>
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.js"></script>
<!-- Disables 404 for favicon.ico which is a logo on top of the webpage tab -->
Expand Down Expand Up @@ -104,6 +80,25 @@ <h2 style="margin-top:5%">This page requires JavaScript
}

</style>
<noscript>
<style>
body {
width: 100%;
height: 100%;
overflow: hidden;
}
</style>
<div style="position: fixed; text-align:center; height: 100%; width: 100%; background-color: #151515;">
<h2 style="margin-top:5%">This page requires JavaScript
to be enabled.
<br><br>
Please refer <a href="https://www.enable-javascript.com/">enable-javascript</a> for how to.
</h2>
<form>
<button type="submit" onClick="<meta httpEquiv='refresh' content='0'>">RETRY</button>
</form>
</div>
</noscript>
</head>
<body>
<div class="container">
Expand Down
Loading

0 comments on commit a8aa05a

Please sign in to comment.