This commit is contained in:
Carneiro 2023-10-04 08:43:58 -03:00
parent 87c4aa1cde
commit 1a89736c83
9 changed files with 147 additions and 9 deletions

View File

@ -1,2 +1,4 @@
bcrypt bcrypt
flask flask
pyjwt
tinydb

View File

@ -1,3 +1,33 @@
''' '''
For managing users For managing users
''' '''
from tinydb import TinyDB, Query
from stream_auth.models.user import User
from stream_auth import settings
db = TinyDB(settings.USER_DATABASE)
query = Query()
def create_user(username: str, hash_pass: str):
'''
Creates a new unique user, with a unique stream_key
'''
if len(db.search(query.username == username)) != 0:
raise ValueError("Username already exists.")
user = User(username, hash_pass)
while db.search(query.stream_key == user.stream_key):
user.regenerate_stream_key()
db.insert(user.__dict__)
return user
def search_stream_key(stream_key: str):
'''
Search for a specific stream key
'''
return db.search(query.stream_key == stream_key)

View File

View File

@ -0,0 +1,23 @@
'''
Middleware for checking if access is authorized
'''
from functools import wraps
from flask import request, abort
from stream_auth.middlewares import jwt
def auth(route_func):
'''
Decorator to verify JWT in http header
'''
@wraps(route_func)
def wrapper(*args, **kwargs):
token = request.headers.get('Token')
if token is None or jwt.verify(token):
abort(401)
return route_func(*args, **kwargs)
return wrapper

View File

@ -0,0 +1,32 @@
import time
import jwt
from stream_auth import settings
def read_key(path):
with open(path, 'r', encoding='utf-8') as file:
content = file.read()
return content
JWT_PRIV_KEY = read_key(settings.JWT_PRIV_PATH)
JWT_PUB_KEY = read_key(settings.JWT_PUB_PATH)
def create_token(username: str, stream_key: str):
exp = time.time() + settings.JWT_EXP_TIME
payload = {'username': username, 'stream_key': stream_key, 'exp': exp}
return jwt.encode(payload, JWT_PRIV_KEY, algorithm="RS256")
def verify(token: str):
try:
jwt.decode(token, JWT_PUB_KEY, algorithms=["RS256"])
except (jwt.exceptions.ExpiredSignatureError, jwt.InvalidTokenError):
return False
return True
def decode_token(token: str):
return jwt.decode(token, JWT_PUB_KEY, algorithms=["RS256"])

View File

@ -0,0 +1,21 @@
class Stream:
'''
A single stream
'''
def __init__(self, name: str, description: str, username: str):
self.name = name
self.description = description
self.user = username
def start(self):
'''
To be called when a stream starts
'''
def stop(self):
'''
To be called when a stream stops
'''

View File

@ -25,18 +25,12 @@ class User:
def __init__(self, username: str, password: str): def __init__(self, username: str, password: str):
salt = bcrypt.gensalt() salt = bcrypt.gensalt()
self.username = username self.username = username
self.password = bcrypt.hashpw(password.encode('utf-8'), salt) self.password = str(bcrypt.hashpw(password.encode('utf-8'), salt), 'utf-8')
self.stream_key = generate_stream_key(STREAM_KEY_LENGTH)
def regenerate_stream_key(self):
'''
Recreate stream_key
'''
self.stream_key = generate_stream_key(STREAM_KEY_LENGTH) self.stream_key = generate_stream_key(STREAM_KEY_LENGTH)
def check_passwrod(self, password: str): def check_passwrod(self, password: str):
input_pass = password.encode('utf-8') input_pass = password.encode('utf-8')
result = bcrypt.checkpw(input_pass, self.password) result = bcrypt.checkpw(input_pass, self.password.encode('utf-8'))
return result return result
def change_password(self, current_password: str, new_password: str): def change_password(self, current_password: str, new_password: str):
@ -45,9 +39,15 @@ class User:
''' '''
ecpass = current_password.encode('utf-8') ecpass = current_password.encode('utf-8')
enpass = new_password.encode('utf-8') enpass = new_password.encode('utf-8')
result = bcrypt.checkpw(ecpass, self.password) result = bcrypt.checkpw(ecpass, self.password.encode('utf-8'))
if not result: if not result:
logging.warning("PASSWORDS DO NOT MATCH") logging.warning("PASSWORDS DO NOT MATCH")
salt = bcrypt.gensalt() salt = bcrypt.gensalt()
self.password = bcrypt.hashpw(enpass, salt) self.password = bcrypt.hashpw(enpass, salt)
def regenerate_stream_key(self):
'''
Recreate stream_key
'''
self.stream_key = generate_stream_key(STREAM_KEY_LENGTH)

View File

@ -44,3 +44,22 @@ def login():
# new_user.username, new_user.stream_key) # new_user.username, new_user.stream_key)
return Response('OK', 200) return Response('OK', 200)
@user.route("/logout", methods=["POST"])
def logout():
'''
Create a new user
'''
json = request.get_json()
username = json['username']
password = json['password']
# TODO: actully do this
new_user = User(username, password)
# logging.info('User %s created with stream key %s',
# new_user.username, new_user.stream_key)
return Response('OK', 200)

View File

@ -1,6 +1,17 @@
''' '''
Settings file, where all globals should be Settings file, where all globals should be
''' '''
import os
HOST = '0.0.0.0' HOST = '0.0.0.0'
PORT = 8080 PORT = 8080
APP_DIR = os.path.dirname(os.path.realpath(__file__))
KEY_DIR = os.path.join(APP_DIR, 'keys')
JWT_PRIV_PATH = os.path.join(KEY_DIR, 'jwtRS256.key')
JWT_PUB_PATH = os.path.join(KEY_DIR, 'jwtRS256.key.pub')
JWT_EXP_TIME = 2592000
USER_DATABASE = '/home/gabriel/db.json'
STREAM_KEY_LENGTH = 32