summaryrefslogtreecommitdiffstats
path: root/pyload/webui/App/api.py
diff options
context:
space:
mode:
authorGravatar Walter Purcaro <vuolter@users.noreply.github.com> 2015-05-12 22:25:39 +0200
committerGravatar Walter Purcaro <vuolter@users.noreply.github.com> 2015-05-12 22:25:39 +0200
commit971754eba93701cfb22bc4399a37debf238eddf1 (patch)
treee3a36023f93b73a1621de0c6c9503ccbb301fb03 /pyload/webui/App/api.py
parentFix dict generators for python 2.5 (diff)
downloadpyload-971754eba93701cfb22bc4399a37debf238eddf1.tar.xz
General fixup (1)
Diffstat (limited to 'pyload/webui/App/api.py')
-rw-r--r--pyload/webui/App/api.py99
1 files changed, 99 insertions, 0 deletions
diff --git a/pyload/webui/App/api.py b/pyload/webui/App/api.py
new file mode 100644
index 000000000..31366b902
--- /dev/null
+++ b/pyload/webui/App/api.py
@@ -0,0 +1,99 @@
+# -*- coding: utf-8 -*-
+
+import itertools
+import traceback
+import urllib
+
+import SafeEval
+import bottle
+
+from pyload.Api import BaseObject
+from pyload.utils import json, json_dumps
+from pyload.webui import PYLOAD
+from pyload.webui.App.utils import toDict, set_session
+
+
+# json encoder that accepts TBase objects
+class TBaseEncoder(json.JSONEncoder):
+
+ def default(self, o):
+ if isinstance(o, BaseObject):
+ return toDict(o)
+ return json.JSONEncoder.default(self, o)
+
+
+# accepting positional arguments, as well as kwargs via post and get
+@bottle.route('/api/<func><args:re:[a-zA-Z0-9\-_/\"\'\[\]%{},]*>')
+@bottle.route('/api/<func><args:re:[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):
+ return bottle.HTTPError(403, json_dumps("Forbidden"))
+
+ if not PYLOAD.isAuthorized(func, {"role": s['role'], "permission": s['perms']}):
+ return bottle.HTTPError(401, json_dumps("Unauthorized"))
+
+ args = args.split("/")[1:]
+ kwargs = {}
+
+ for x, y in itertools.chain(request.GET.iteritems(), request.POST.iteritems()):
+ if x == "session":
+ continue
+ kwargs[x] = urllib.unquote(y)
+
+ try:
+ return callApi(func, *args, **kwargs)
+ except Exception, e:
+ traceback.print_exc()
+ return bottle.HTTPError(500, json_dumps({"error": e.message, "traceback": traceback.format_exc()}))
+
+
+def callApi(func, *args, **kwargs):
+ if not hasattr(PYLOAD.EXTERNAL, func) or func.startswith("_"):
+ print "Invalid API call", func
+ return bottle.HTTPError(404, json_dumps("Not Found"))
+
+ result = getattr(PYLOAD, func)(*[SafeEval.const_eval(x) for x in args],
+ **dict((x, SafeEval.const_eval(y)) for x, y in kwargs.iteritems()))
+
+ # null is invalid json response
+ return json_dumps(result or True, cls=TBaseEncoder)
+
+
+# post -> username, password
+@bottle.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 Exception:
+ return json_dumps(True)
+
+
+@bottle.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()