remove own auth impl in favor of ldap
This commit is contained in:
parent
8245ee3ab4
commit
fb1ba3a391
|
@ -0,0 +1,35 @@
|
||||||
|
DOCUMENTAÇÃO STREAM ALICE:
|
||||||
|
|
||||||
|
|
||||||
|
PACOTES ENVOLVIDOS:
|
||||||
|
NGINX
|
||||||
|
APACHE
|
||||||
|
|
||||||
|
NGINX:
|
||||||
|
Compilado e instalado manualmente em /usr/local/nginx
|
||||||
|
Binário: /usr/local/nginx/sbin/nginx
|
||||||
|
Conf: /usr/local/nginx/conf/nginx.conf
|
||||||
|
Serviço: TODO
|
||||||
|
Exemplo/Tutorial usado: https://www.digitalocean.com/community/tutorials/how-to-set-up-a-video-streaming-server-using-nginx-rtmp-on-ubuntu-20-04
|
||||||
|
|
||||||
|
Server RTMP
|
||||||
|
Porta: 33000
|
||||||
|
DASH (arquivo de vídeo): /var/www/html/stream
|
||||||
|
Revese proxy apache (substitua VIDEO pela chave usada no OBS): https://alice.dcomp.ufsj.edu.br/cast/dash/VIDEO.mpd
|
||||||
|
|
||||||
|
Player HTML:
|
||||||
|
Porta: 44000
|
||||||
|
Root: /var/www/html/stream/dash_player
|
||||||
|
Revese proxy apache: https://alice.dcomp.ufsj.edu.br/cast/player
|
||||||
|
TODO: /VIDEO apos player para pegar a CHAVE
|
||||||
|
|
||||||
|
APACHE:
|
||||||
|
Reverse proxy:
|
||||||
|
Config em: /etc/apache2/sites-enabled/alice.dcomp.ufsj.edu.br.conf
|
||||||
|
ProxyPass: /cast http://localhost:44000
|
||||||
|
|
||||||
|
OBS:
|
||||||
|
Configurações>Transmissão>
|
||||||
|
Serviço: Personalizado
|
||||||
|
Servidor: rtmp://alice.dcomp.ufsj.edu.br:33000/live
|
||||||
|
Chave (por enquanto apenas a chave 'test'): A chave será o arquivo gerado na pasta /var/www/html/stream/CHAVE.mpd
|
|
@ -10,7 +10,7 @@ db = TinyDB(settings.USER_DATABASE)
|
||||||
query = Query()
|
query = Query()
|
||||||
|
|
||||||
|
|
||||||
def create_user(username: str, password: str):
|
def create_user(username: str):
|
||||||
'''
|
'''
|
||||||
Creates a new unique user, with a unique stream_key
|
Creates a new unique user, with a unique stream_key
|
||||||
'''
|
'''
|
||||||
|
@ -18,7 +18,7 @@ def create_user(username: str, password: str):
|
||||||
if len(db.search(query.username == username)) != 0:
|
if len(db.search(query.username == username)) != 0:
|
||||||
raise ValueError("Username already exists.")
|
raise ValueError("Username already exists.")
|
||||||
|
|
||||||
user = User(username, password)
|
user = User(username)
|
||||||
while db.search(query.stream_key == user.stream_key):
|
while db.search(query.stream_key == user.stream_key):
|
||||||
user.regenerate_stream_key()
|
user.regenerate_stream_key()
|
||||||
|
|
||||||
|
@ -30,7 +30,8 @@ def search_user(username: str):
|
||||||
'''
|
'''
|
||||||
Search for a specific stream key
|
Search for a specific stream key
|
||||||
'''
|
'''
|
||||||
return db.search(query.username == username)
|
seuser = db.search(query.username == username)[0]
|
||||||
|
return User(seuser['username'], seuser['stream_key'])
|
||||||
|
|
||||||
|
|
||||||
def search_stream_key(stream_key: str):
|
def search_stream_key(stream_key: str):
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
import ldap
|
||||||
|
# import logging
|
||||||
|
|
||||||
|
SERVER = "ldap://localhost"
|
||||||
|
BASE_DN = "dc=alice,dc=ufsj,dc=edu,dc=br"
|
||||||
|
|
||||||
|
def authenticate(username, password):
|
||||||
|
user_dn= f"cn={username},ou=User,{BASE_DN}"
|
||||||
|
try:
|
||||||
|
l = ldap.initialize(SERVER)
|
||||||
|
l.protocol_version = ldap.VERSION3
|
||||||
|
l.simple_bind_s(user_dn, password)
|
||||||
|
except ldap.INVALID_CREDENTIALS:
|
||||||
|
# logging.warning("PASSWORDS DO NOT MATCH")
|
||||||
|
return False
|
||||||
|
except ldap.SERVER_DOWN:
|
||||||
|
# logging.warning("LDAP SERVER DOWN")
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
# authenticate('emanuels','123123')
|
|
@ -10,12 +10,24 @@ from stream_auth.middlewares import jwt
|
||||||
STREAM_KEY_LENGTH = 64
|
STREAM_KEY_LENGTH = 64
|
||||||
|
|
||||||
|
|
||||||
def generate_stream_key(key_length: int):
|
# def generate_stream_key(key_length: int):
|
||||||
'''
|
# '''
|
||||||
Generate a new stream key
|
# Generate a new stream key
|
||||||
'''
|
# '''
|
||||||
key_types = string.ascii_letters + string.digits
|
# key_types = string.ascii_letters + string.digits
|
||||||
return ''.join(random.choice(key_types) for i in range(key_length))
|
# return ''.join(random.choice(key_types) for i in range(key_length))
|
||||||
|
|
||||||
|
|
||||||
|
# def hash_password(password: str):
|
||||||
|
# salt = bcrypt.gensalt()
|
||||||
|
# password = str(bcrypt.hashpw(password.encode('utf-8'), salt), 'utf-8')
|
||||||
|
# return password
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# def check_password(password: str, hash_password: str):
|
||||||
|
# input_pass = password.encode('utf-8')
|
||||||
|
# result = bcrypt.checkpw(input_pass, hash_password.encode('utf-8'))
|
||||||
|
# return result
|
||||||
|
|
||||||
|
|
||||||
class User:
|
class User:
|
||||||
|
@ -23,31 +35,31 @@ class User:
|
||||||
User class, for managing a specific user
|
User class, for managing a specific user
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, username: str, password: str):
|
def __init__(self, username: str, stream_key: str = None):
|
||||||
salt = bcrypt.gensalt()
|
# salt = bcrypt.gensalt()
|
||||||
self.username = username
|
# self.password = hash_password(password)
|
||||||
self.password = str(bcrypt.hashpw(password.encode('utf-8'), salt), 'utf-8')
|
|
||||||
# self.stream_key = generate_stream_key(STREAM_KEY_LENGTH)
|
# self.stream_key = generate_stream_key(STREAM_KEY_LENGTH)
|
||||||
self.stream_key = jwt.create_stream_key(username)
|
self.username = username
|
||||||
self.live = False
|
self.stream_key = jwt.create_stream_key(username) if stream_key is None else stream_key
|
||||||
|
# self.live = False
|
||||||
|
|
||||||
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.encode('utf-8'))
|
# 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):
|
||||||
'''
|
# '''
|
||||||
Changes user defualt password
|
# Changes user defualt password
|
||||||
'''
|
# '''
|
||||||
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.encode('utf-8'))
|
# 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):
|
def regenerate_stream_key(self):
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -7,7 +7,8 @@ from flask import Blueprint, Response, request, redirect
|
||||||
from stream_auth.middlewares.auth import auth
|
from stream_auth.middlewares.auth import auth
|
||||||
from stream_auth.middlewares import jwt
|
from stream_auth.middlewares import jwt
|
||||||
from stream_auth.models.stream import Stream as StreamModel
|
from stream_auth.models.stream import Stream as StreamModel
|
||||||
from stream_auth.database import user
|
from stream_auth.models import ldap
|
||||||
|
from stream_auth.database import user as userdb
|
||||||
|
|
||||||
stream = Blueprint('stream', __name__)
|
stream = Blueprint('stream', __name__)
|
||||||
|
|
||||||
|
@ -22,27 +23,40 @@ def create_stream():
|
||||||
StreamModel(username, title, description)
|
StreamModel(username, title, description)
|
||||||
|
|
||||||
|
|
||||||
|
# @user.route('/validate', methods=['POST'])
|
||||||
@stream.route('/publish_check', methods=['POST'])
|
@stream.route('/publish_check', methods=['POST'])
|
||||||
def publish_check():
|
def publish_check():
|
||||||
|
|
||||||
# TODO: check if user created stream
|
|
||||||
|
|
||||||
# get user
|
|
||||||
stream_key = request.form.get('stream_key')
|
|
||||||
username = request.form.get('name')
|
username = request.form.get('name')
|
||||||
print(username, stream_key)
|
password = request.form.get('password')
|
||||||
try:
|
|
||||||
stream_user = user.search_user(username)[0]
|
|
||||||
|
|
||||||
if username != stream_user['username'] or not jwt.verify_stream_key(stream_key):
|
if ldap.authenticate(username, password) is False:
|
||||||
raise ValueError('Invalid Token')
|
logging.info('User or password incorrect', username)
|
||||||
|
return Response('User or password incorrect', 401)
|
||||||
except (IndexError, ValueError):
|
|
||||||
return Response('Invalid Stream Key', 401)
|
|
||||||
|
|
||||||
return Response('OK', 200)
|
return Response('OK', 200)
|
||||||
|
|
||||||
|
|
||||||
|
# @stream.route('/publish_check', methods=['POST'])
|
||||||
|
# def publish_check():
|
||||||
|
#
|
||||||
|
# # TODO: check if user created stream
|
||||||
|
#
|
||||||
|
# # get user
|
||||||
|
# stream_key = request.form.get('stream_key')
|
||||||
|
# username = request.form.get('name')
|
||||||
|
# print(username, stream_key)
|
||||||
|
# try:
|
||||||
|
# stream_user = userdb.search_user(username)
|
||||||
|
#
|
||||||
|
# if username != stream_user.username or not jwt.verify_stream_key(stream_key):
|
||||||
|
# raise ValueError('Invalid Token')
|
||||||
|
#
|
||||||
|
# except (IndexError, ValueError):
|
||||||
|
# return Response('Invalid Stream Key', 401)
|
||||||
|
#
|
||||||
|
# return Response('OK', 200)
|
||||||
|
|
||||||
|
|
||||||
@stream.route('/test')
|
@stream.route('/test')
|
||||||
def test():
|
def test():
|
||||||
|
|
||||||
|
|
|
@ -5,67 +5,95 @@ For controlling user routes
|
||||||
import logging
|
import logging
|
||||||
from flask import Blueprint, Response, request, jsonify, make_response
|
from flask import Blueprint, Response, request, jsonify, make_response
|
||||||
from stream_auth.models.user import User
|
from stream_auth.models.user import User
|
||||||
|
from stream_auth.models import ldap
|
||||||
from stream_auth.database import user as userdb
|
from stream_auth.database import user as userdb
|
||||||
from stream_auth.middlewares import jwt
|
from stream_auth.middlewares import jwt
|
||||||
|
|
||||||
user = Blueprint('user', __name__)
|
user = Blueprint('user', __name__)
|
||||||
|
|
||||||
|
|
||||||
@user.route('/signin', methods=['POST'])
|
# @user.route('/signin', methods=['POST'])
|
||||||
def create():
|
# def create():
|
||||||
'''
|
# '''
|
||||||
Create a new user
|
# Create a new user
|
||||||
'''
|
# '''
|
||||||
|
#
|
||||||
|
# json = request.get_json()
|
||||||
|
# username = json['username']
|
||||||
|
# password = json['password']
|
||||||
|
#
|
||||||
|
# new_user = userdb.create_user(username, password)
|
||||||
|
#
|
||||||
|
# logging.info('User %s created with stream key %s',
|
||||||
|
# new_user.username, new_user.stream_key)
|
||||||
|
#
|
||||||
|
# res = {'username': new_user.username, 'stream_key': new_user.stream_key}
|
||||||
|
# return make_response(jsonify(res), 200)
|
||||||
|
|
||||||
|
|
||||||
|
@user.route('/validate', methods=['POST'])
|
||||||
|
def validate():
|
||||||
json = request.get_json()
|
json = request.get_json()
|
||||||
username = json['username']
|
username = json['username']
|
||||||
password = json['password']
|
password = json['password']
|
||||||
|
|
||||||
new_user = userdb.create_user(username, password)
|
if ldap.authenticate(username, password) is False:
|
||||||
|
logging.info('User or password incorrect', username)
|
||||||
|
return Response('User or password incorrect', 401)
|
||||||
|
|
||||||
|
# logging.info('User %s valid', username)
|
||||||
|
|
||||||
logging.info('User %s created with stream key %s',
|
try:
|
||||||
new_user.username, new_user.stream_key)
|
logging.info('User %s valid', username)
|
||||||
|
log_user = userdb.search_user(username)
|
||||||
|
print(log_user)
|
||||||
|
# return Response(f'User {username} valid')
|
||||||
|
|
||||||
res = {'username': new_user.username, 'stream_key': new_user.stream_key}
|
except IndexError:
|
||||||
|
logging.info('User %s first login, creating stream key', username)
|
||||||
|
log_user = userdb.create_user(username)
|
||||||
|
|
||||||
|
print(log_user)
|
||||||
|
res = {'username': log_user.username, 'stream_key': log_user.stream_key}
|
||||||
return make_response(jsonify(res), 200)
|
return make_response(jsonify(res), 200)
|
||||||
|
|
||||||
|
|
||||||
@user.route('/login', methods=['POST'])
|
# @user.route('/login', methods=['POST'])
|
||||||
def login():
|
# def login():
|
||||||
'''
|
# '''
|
||||||
User log in
|
# User log in
|
||||||
'''
|
# '''
|
||||||
|
#
|
||||||
json = request.get_json()
|
# json = request.get_json()
|
||||||
username = json['username']
|
# username = json['username']
|
||||||
password = json['password']
|
# password = json['password']
|
||||||
|
#
|
||||||
try:
|
# try:
|
||||||
log_user = userdb.search_user(username)[0]
|
# log_user = userdb.search_user(username)[0]
|
||||||
except IndexError:
|
# except IndexError:
|
||||||
return Response('User or password incorrect', 401)
|
# return Response('User or password incorrect', 401)
|
||||||
|
#
|
||||||
if not log_user.check_password(password):
|
# if not check_password(password, log_user['password']):
|
||||||
return Response('User or password incorrect', 401)
|
# return Response('User or password incorrect', 401)
|
||||||
|
#
|
||||||
token = jwt.create_token(log_user.username, log_user.stream_key)
|
# token = jwt.create_token(log_user['username'], log_user['stream_key'])
|
||||||
logging.info('User %s logged in', log_user.username)
|
# logging.info('User %s logged in', log_user['username'])
|
||||||
|
#
|
||||||
return make_response(jsonify({'token': token}), 201)
|
# return make_response(jsonify({'token': token}), 201)
|
||||||
|
#
|
||||||
|
#
|
||||||
@user.route('/logout', methods=['POST'])
|
# @user.route('/logout', methods=['POST'])
|
||||||
def logout():
|
# def logout():
|
||||||
'''
|
# '''
|
||||||
Create a new user
|
# Create a new user
|
||||||
'''
|
# '''
|
||||||
|
#
|
||||||
json = request.get_json()
|
# json = request.get_json()
|
||||||
username = json['username']
|
# username = json['username']
|
||||||
password = json['password']
|
# password = json['password']
|
||||||
|
#
|
||||||
new_user = User(username, password)
|
# new_user = User(username, password)
|
||||||
|
#
|
||||||
logging.info('User %s logged out', new_user.username)
|
# logging.info('User %s logged out', new_user.username)
|
||||||
|
#
|
||||||
return Response('OK', 200)
|
# return Response('OK', 200)
|
||||||
|
|
|
@ -4,7 +4,7 @@ Settings file, where all globals should be
|
||||||
import os
|
import os
|
||||||
|
|
||||||
HOST = '0.0.0.0'
|
HOST = '0.0.0.0'
|
||||||
PORT = 8080
|
PORT = 33003
|
||||||
|
|
||||||
APP_DIR = os.path.dirname(os.path.realpath(__file__))
|
APP_DIR = os.path.dirname(os.path.realpath(__file__))
|
||||||
KEY_DIR = os.path.join(APP_DIR, 'keys')
|
KEY_DIR = os.path.join(APP_DIR, 'keys')
|
||||||
|
|
Loading…
Reference in New Issue