You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
260 lines
8.6 KiB
260 lines
8.6 KiB
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/<rid>/<publisher>', 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/<rid>")
|
|
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/<rid>/<publisher>', 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/<rid>', 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)
|
|
|