diff options
Diffstat (limited to 'module/web')
-rw-r--r-- | module/web/api_app.py | 107 | ||||
-rw-r--r-- | module/web/pyload_app.py | 12 | ||||
-rw-r--r-- | module/web/utils.py | 20 | ||||
-rw-r--r-- | module/web/webinterface.py | 1 |
4 files changed, 127 insertions, 13 deletions
diff --git a/module/web/api_app.py b/module/web/api_app.py new file mode 100644 index 000000000..7d1a95c58 --- /dev/null +++ b/module/web/api_app.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from urllib import unquote +from itertools import chain +from traceback import format_exc, print_exc + +from bottle import route, request, response, HTTPError + +from thrift.protocol.TBase import TBase + +from utils import toDict, set_session + +from webinterface import PYLOAD + +from module.common.json import json_dumps +from module.database.UserDatabase import ROLE + +try: + from ast import literal_eval +except ImportError: # python 2.5 + from module.lib.SafeEval import safe_eval as literal_eval + + +# convert to format serializable by json +def traverse(data): + if type(data) == list: + return [traverse(x) for x in data] + elif type(data) == dict: + return dict([(x, traverse(y)) for x, y in data.iteritems()]) + elif isinstance(data, TBase): + return toDict(data) + else: + return data + + +# accepting positional arguments, as well as kwargs via post and get + +@route("/api/:func:args#[a-zA-Z0-9\-_/\"'\[\]%{}]*#") +@route("/api/:func:args#[a-zA-Z0-9\-_/\"'\[\]%{}]*#", method="POST") +def call_api(func, args=""): + response.headers.replace("Content-type", "application/json") + response.headers.append("Cache-Control", "no-cache, must-revalidate") + + s = request.environ.get('beaker.session') + if 'session' in request.POST: + s = s.get_by_id(request.POST['session']) + + if not s or not s.get("authenticated", False) or s.get("role", -1) != ROLE.ADMIN: + return HTTPError(401, json_dumps("Unauthorized")) + + args = args.split("/")[1:] + kwargs = {} + + for x, y in chain(request.GET.iteritems(), request.POST.iteritems()): + if x == "session": continue + kwargs[x] = unquote(y) + + try: + return callApi(func, *args, **kwargs) + except Exception, e: + print_exc() + return HTTPError(500, json_dumps({"error": e.message, "traceback": format_exc()})) + + +def callApi(func, *args, **kwargs): + if not hasattr(PYLOAD.EXTERNAL, func) or func.startswith("_"): + print "Invalid API call", func + return HTTPError(404, json_dumps("Not Found")) + + result = getattr(PYLOAD, func)(*[literal_eval(x) for x in args], + **dict([(x, literal_eval(y)) for x, y in kwargs.iteritems()])) + + return json_dumps(traverse(result)) + + +#post -> username, password +@route("/api/login", method="POST") +def login(): + response.headers.replace("Content-type", "application/json") + response.headers.append("Cache-Control", "no-cache, must-revalidate") + + user = request.forms.get("username") + password = request.forms.get("password") + + info = PYLOAD.checkAuth(user, password) + + if not info: + return json_dumps(False) + + s = set_session(request, info) + + # get the session id by dirty way, documentations seems wrong + try: + sid = s._headers["cookie_out"].split("=")[1].split(";")[0] + return json_dumps(sid) + except: + return json_dumps(True) + + +@route("/api/logout") +def logout(): + response.headers.replace("Content-type", "application/json") + response.headers.append("Cache-Control", "no-cache, must-revalidate") + + s = request.environ.get('beaker.session') + s.delete() diff --git a/module/web/pyload_app.py b/module/web/pyload_app.py index 8d76d39ec..49568baad 100644 --- a/module/web/pyload_app.py +++ b/module/web/pyload_app.py @@ -32,7 +32,7 @@ from bottle import route, static_file, request, response, redirect, HTTPError, e from webinterface import PYLOAD, PYLOAD_DIR, PROJECT_DIR, SETUP from utils import render_to_response, parse_permissions, parse_userdata, \ - login_required, get_permission, set_permission, toDict + login_required, get_permission, set_permission, toDict, set_session from filters import relpath, unquotepath @@ -119,15 +119,7 @@ def login_post(): if not info: return render_to_response("login.html", {"errors": True}, [pre_processor]) - s = request.environ.get('beaker.session') - s["authenticated"] = True - s["id"] = info["id"] - s["name"] = info["name"] - s["role"] = info["role"] - s["perms"] = info["permission"] - s["template"] = info["template"] - s.save() - + set_session(request, info) return redirect("/") diff --git a/module/web/utils.py b/module/web/utils.py index b99736216..39ddb361f 100644 --- a/module/web/utils.py +++ b/module/web/utils.py @@ -52,6 +52,7 @@ def parse_permissions(session): return perms + def get_permission(perms, p): perms["add"] = has_permission(p, PERMS.ADD) perms["delete"] = has_permission(p, PERMS.DELETE) @@ -59,7 +60,7 @@ def get_permission(perms, p): perms["see_downloads"] = has_permission(p, PERMS.SEE_DOWNLOADS) perms["download"] = has_permission(p, PERMS.DOWNLOAD) perms["settings"] = has_permission(p, PERMS.SETTINGS) - perms["filemanager"] = has_permission(p, PERMS.FILEMANAGER) + perms["accounts"] = has_permission(p, PERMS.ACCOUNTS) def set_permission(perms): permission = 0 @@ -75,11 +76,24 @@ def set_permission(perms): permission |= PERMS.DOWNLOAD if perms["settings"]: permission |= PERMS.SETTINGS - if perms["filemanager"]: - permission |= PERMS.FILEMANAGER + if perms["accounts"]: + permission |= PERMS.ACCOUNTS return permission + +def set_session(request, info): + s = request.environ.get('beaker.session') + s["authenticated"] = True + s["user_id"] = info["id"] + s["name"] = info["name"] + s["role"] = info["role"] + s["perms"] = info["permission"] + s["template"] = info["template"] + s.save() + + return s + def parse_userdata(session): return {"name": session.get("name", "Anonymous"), "is_admin": True if session.get("role", 1) == 0 else False, diff --git a/module/web/webinterface.py b/module/web/webinterface.py index 4d07c436e..d2b96b03c 100644 --- a/module/web/webinterface.py +++ b/module/web/webinterface.py @@ -105,6 +105,7 @@ web = GZipMiddleWare(web) import pyload_app import json_app import cnl_app +import api_app def run_simple(host="0.0.0.0", port="8000"): run(app=web, host=host, port=port, quiet=True) |