summaryrefslogtreecommitdiffstats
path: root/module/web
diff options
context:
space:
mode:
Diffstat (limited to 'module/web')
-rw-r--r--module/web/api_app.py107
-rw-r--r--module/web/pyload_app.py12
-rw-r--r--module/web/utils.py20
-rw-r--r--module/web/webinterface.py1
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)