import argparse import base64 import json import os from getpass import getpass from pathlib import Path from random import randint import sh from flask import Flask, request, jsonify from flask_cors import CORS from flask_jwt_extended import JWTManager, create_access_token, jwt_required, jwt_optional, get_jwt_identity from flask_mongoengine import MongoEngine from werkzeug.security import generate_password_hash, check_password_hash from string import ascii_lowercase, ascii_uppercase, digits from mainapp.janus import Janus from mainapp.models import User, Room app = Flask(__name__) app.config['MONGODB_SETTINGS'] = { 'host': os.environ.get('MONGODB_URL') } app.config['JWT_SECRET_KEY'] = os.environ.get('JWT_SECRET_KEY', 'changeme') app.config['JANUS_URL'] = os.environ.get('JANUS_URL') app.config['JANUS_ADMIN_KEY'] = os.environ.get('JANUS_ADMIN_KEY', '') db = MongoEngine() db.init_app(app) jwt = JWTManager(app) cors = CORS(app, resources={r"/api/*": {"origins": "*"}}) def get_current_user(): try: current_user = get_jwt_identity() return User.objects.get(id=current_user) except: return False @app.route('/api/kick//', methods=['GET']) @jwt_optional def kick(rid, publisher): r = Room.objects.get(ridn=rid) user = get_current_user() if user: if user.root_access or r.creator == user: jan = Janus(os.environ.get('JANUS_URL'), app.config['JANUS_ADMIN_KEY']) jan.connect() jan.kick(r.room_id, int(publisher)) return "ok" sh_coms = {} @app.route("/api/sh") def sh_coms_list(): room_rs = [] for room_id , sh_item in sh_coms.items(): room_rs.append({"room":room_id, "status":sh_item.exit_code}) return jsonify(room_rs) @app.route("/api/sh/kill/") def sh_kill(rid): if sh_coms.get(int(rid)): print(sh_coms.get(int(rid)).kill()) return "ok" def done(cmd, success, exit_code): print('done') @app.route('/api/rtp//', methods=['GET']) @jwt_optional def rtp_forward(rid, publisher): r = Room.objects.get(ridn=rid) if not sh_coms.get(r.room_id,None) or sh_coms.get(r.room_id).exit_code: room_sh = sh.python(['forward_stream.py', '--room',r.room_id, "https://kahvehane.oyd.org.tr/janus"],_bg=True, _done=done) sh_coms.update({r.room_id:room_sh}) return "ok" @app.route('/api/room/', methods=['GET']) @jwt_optional def room(rid): r = Room.objects.get(ridn=rid) user = get_current_user() if user: return jsonify({'rid': r.room_id, "can_modify": user.root_access or r.creator == user}) else: return jsonify({'rid': r.room_id, "can_modify": False}) @app.route('/api/upload', methods=('POST',)) @jwt_required def upload_file(): file = request.json.get('file') file_name = request.json.get('file_name') file_content = base64.b64decode(file) with open("static/{}".format(file_name), "wb+") as f: f.write(file_content) return "ok" @app.route('/api/files') @jwt_required def get_file(): p = Path("./static") files = [] for i in p.glob("*.*"): files.append(i.name) return jsonify(files) @app.route('/api/recreate/room', methods=['GET']) def recreate_room(): rms = Room.objects.all() for i in rms: jan = Janus(os.environ.get('JANUS_URL'), app.config['JANUS_ADMIN_KEY']) jan.connect() room_id = jan.create_room(name=i.room_name, video_codec="vp8", audio_codec="opus", publisher_count=int(16), bitrate=128*1000, data=False) i.room_id = room_id i.save() return "ok" @app.route('/api/create/room', methods=['POST']) @jwt_required def create_room(): if not request.is_json: return jsonify({"msg": "Missing JSON in request"}), 400 room_name = request.json.get('room_name', 'No name room') video_codec = request.json.get('video_codec', 'vp9') audio_codec = request.json.get('audio_codec', 'opus') publisher_count = request.json.get('publisher_count', 16) bitrate = request.json.get('bitrate', 128000) data = request.json.get('data', False) user = get_current_user() if user.create_room_access or user.root_access: jan = Janus(os.environ.get('JANUS_URL'), app.config['JANUS_ADMIN_KEY']) jan.connect() room_id = jan.create_room(name=room_name, video_codec=video_codec, audio_codec=audio_codec, publisher_count=int(publisher_count), bitrate=bitrate, data=data) room = Room() room.room_name = room_name room.creator = user room.room_id = room_id have_room = True ridn = None letters = ascii_lowercase + ascii_uppercase + digits while have_room: ridn = ''.join([letters[randint(0, len(letters) - 1)] for rid in range(6)]) if Room.objects.filter(ridn=ridn).count() == 0: have_room = False room.ridn = ridn room.save() return jsonify({"msg": "seccess", "ridn": ridn}), 200 else: return jsonify({"msg": "You don't have a this access"}), 403 @app.route('/api/rooms', methods=['GET']) @jwt_required def rooms(): user = get_current_user() if user.root_access: json_data = json.dumps({ "rooms": json.loads(Room.objects.all().to_json()), "can_create": True }) else: json_data = json.dumps({ "rooms": user.rooms.to_json(), "can_create": False }) return json_data @app.route('/api/create/user', methods=['POST']) @jwt_required def create_user(): if not request.is_json: return jsonify({"msg": "Missing JSON in request"}), 400 room_id = request.json.get('room', None) create_room = request.json.get('create_room', False) root_access = request.json.get('root_access', False) password = request.json.get('password', False) user = get_current_user() if not user.create_room_access and not user.root_access: return jsonify({"msg": "You don't have a this access"}), 403 room = Room.objects.get(ridn=room_id) if room.creator != user and not user.root_access: return jsonify({"msg": "You don't have a this access"}), 403 if (create_room or root_access) and not user.root_access: return jsonify({"msg": "You don't have a this access"}), 403 letters = ascii_lowercase + ascii_uppercase + digits have_user = True user_id = None while have_user: user_id = ''.join([letters[randint(len(letters) - 1)] for rid in range(6)]) if User.objects.filter(uidn=user_id).count() == 0: have_user = False new_user = User() new_user.create_room_access = create_room new_user.root_access = root_access new_user.uidn = user_id new_user.rooms.append(room) if create_room or root_access: new_user.passw = generate_password_hash(password, method='sha256') new_user.save() return jsonify({'msg': 'user created', 'uid': user_id}) @app.route('/api/login', methods=['POST']) def login(): if not request.is_json: return jsonify({"msg": "Missing JSON in request"}), 400 username = request.json.get('username', None) password = request.json.get('password', None) if not username: return jsonify({"msg": "Missing username parameter"}), 400 user = User.objects.filter(uidn=username) if user.count() == 0: return jsonify({"msg": "Bad username or password"}), 401 else: user = user.get() if not password and (user.root_access or user.create_room_access): return jsonify({"msg": "Password need for this user"}), 401 if password or user.passw: if not check_password_hash(user.passw, password): return jsonify({"msg": "Bad username or password"}), 401 # Identity can be any data that is json serializable access_token = create_access_token(identity=str(user.id)) return jsonify(access_token=access_token), 200 if __name__ == '__main__': parser = argparse.ArgumentParser(description='Albatros Backend') parser.add_argument('--create-user', nargs='?', help='Create a root user') args = parser.parse_args() if args.create_user: new_user = User() new_user.uidn = args.create_user new_user.root_access = True passcheck = False while not passcheck: passwd = getpass('Password: ') passwd_check = getpass('Password Check: ') if passwd_check == passwd: passcheck = True new_user.passw = generate_password_hash(passwd, method='sha256') new_user.save() exit() app.run(debug=True)