diff options
Diffstat (limited to 'module/web/api_app.py')
-rw-r--r-- | module/web/api_app.py | 47 |
1 files changed, 28 insertions, 19 deletions
diff --git a/module/web/api_app.py b/module/web/api_app.py index 1629c1677..b2d7fa5b6 100644 --- a/module/web/api_app.py +++ b/module/web/api_app.py @@ -7,10 +7,11 @@ from traceback import format_exc, print_exc from bottle import route, request, response, HTTPError -from utils import toDict, set_session +from utils import set_session, get_user_api from webinterface import PYLOAD from module.common.json_layer import json +from module.utils import remove_chars, to_dict from module.lib.SafeEval import const_eval as literal_eval from module.Api import BaseObject @@ -19,26 +20,32 @@ class TBaseEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, BaseObject): - return toDict(o) + return to_dict(o) return json.JSONEncoder.default(self, o) -# accepting positional arguments, as well as kwargs via post and get +def add_header(r): + r.headers.replace("Content-type", "application/json") + r.headers.append("Cache-Control", "no-cache, must-revalidate") + r.headers.append("Access-Control-Allow-Origin", "*") # allow xhr requests -@route("/api/:func:args#[a-zA-Z0-9\-_/\"'\[\]%{}]*#") -@route("/api/:func:args#[a-zA-Z0-9\-_/\"'\[\]%{}]*#", method="POST") +# accepting positional arguments, as well as kwargs via post and get +# only forbidden path symbol are "?", which is used to separate GET data and # +@route("/api/<func><args:re:[^#?]*>") +@route("/api/<func><args:re:[^#?]*>", method="POST") def call_api(func, args=""): - response.headers.replace("Content-type", "application/json") - response.headers.append("Cache-Control", "no-cache, must-revalidate") + add_header(response) s = request.environ.get('beaker.session') if 'session' in request.POST: - s = s.get_by_id(request.POST['session']) + # removes "' so it works on json strings + s = s.get_by_id(remove_chars(request.POST['session'], "'\"")) - if not s or not s.get("authenticated", False): + api = get_user_api(s) + if not api: return HTTPError(403, json.dumps("Forbidden")) - if not PYLOAD.isAuthorized(func, {"role": s["role"], "permission": s["perms"]}): + if not PYLOAD.isAuthorized(func, api.user): return HTTPError(401, json.dumps("Unauthorized")) args = args.split("/")[1:] @@ -54,16 +61,18 @@ def call_api(func, args=""): print_exc() return HTTPError(500, json.dumps({"error": e.message, "traceback": format_exc()})) +# Better error codes on invalid input 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")) + # TODO: encoding result = getattr(PYLOAD, func)(*[literal_eval(x) for x in args], **dict([(x, literal_eval(y)) for x, y in kwargs.iteritems()])) - # null is invalid json response + # null is invalid json response if result is None: result = True return json.dumps(result, cls=TBaseEncoder) @@ -72,31 +81,31 @@ def callApi(func, *args, **kwargs): #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") + add_header(response) - user = request.forms.get("username") + username = request.forms.get("username") password = request.forms.get("password") - info = PYLOAD.checkAuth(user, password) + user = PYLOAD.checkAuth(username, password) - if not info: + if not user: return json.dumps(False) - s = set_session(request, info) + s = set_session(request, user) # 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: + print "Could not get session" return json.dumps(True) @route("/api/logout") +@route("/api/logout", method="POST") def logout(): - response.headers.replace("Content-type", "application/json") - response.headers.append("Cache-Control", "no-cache, must-revalidate") + add_header(response) s = request.environ.get('beaker.session') s.delete() |