diff --git a/packages/slycat/web/server/handlers.py b/packages/slycat/web/server/handlers.py index f9aea5876..bef4c890d 100644 --- a/packages/slycat/web/server/handlers.py +++ b/packages/slycat/web/server/handlers.py @@ -675,7 +675,16 @@ def login(): and determins with the user can be authenticated with slycat :return: authentication status """ - cherrypy.response.status = "404 no auth found!!!" + + if "slycatauth" in cherrypy.request.cookie: + try: + sid = cherrypy.request.cookie["slycatauth"].value + couchdb = slycat.web.server.database.couchdb.connect() + session = couchdb.get("session", sid) + if session is not None: + couchdb.delete(session) + except: + pass # try and decode the username and password try: @@ -711,7 +720,7 @@ def login(): sid = uuid.uuid4().hex session = {"created": datetime.datetime.utcnow(), "creator": user_name} database = slycat.web.server.database.couchdb.connect() - #database.save({"_id": sid, "type": "session", "created": session["created"].isoformat(), "creator": session["creator"]}) + database.save({"_id": sid, "type": "session", "created": session["created"].isoformat(), "creator": session["creator"]}) login.sessions[sid] = session @@ -719,7 +728,10 @@ def login(): cherrypy.response.cookie["slycatauth"]["path"] = "/" cherrypy.response.cookie["slycatauth"]["secure"] = 1 cherrypy.response.cookie["slycatauth"]["httponly"] = 1 - #cherrypy.request.login = user_name + cherrypy.response.status = "200 OK" + cherrypy.request.login = user_name + else: + cherrypy.response.status = "404 no auth found!!!" return {'session': 'stuff','sid' : sid, 'user_name': user_name, 'password': password, 'success': success, 'groups': groups, 'ip': remote_ip} @@ -738,8 +750,8 @@ def logout(): sid = cherrypy.request.cookie["slycatauth"].value # expire the old cookie - # cherrypy.response.cookie["slycatauth"] = sid - # cherrypy.response.cookie["slycatauth"]['expires'] = 0 + cherrypy.response.cookie["slycatauth"] = sid + cherrypy.response.cookie["slycatauth"]['expires'] = 0 couchdb = slycat.web.server.database.couchdb.connect() session = couchdb.get("session", sid) @@ -751,7 +763,6 @@ def logout(): cherrypy.response.status = "403 Forbidden" except Exception as e: raise cherrypy.HTTPError("400 Bad Request") - #TODO: log the exception @cherrypy.tools.json_in(on = True) def put_model_inputs(mid): diff --git a/web-server/plugins/slycat-standard-authentication.py b/web-server/plugins/slycat-standard-authentication.py index 5970d8989..30a4246a4 100644 --- a/web-server/plugins/slycat-standard-authentication.py +++ b/web-server/plugins/slycat-standard-authentication.py @@ -34,119 +34,48 @@ def authenticate(realm, rules=None): session = None try: session = couchdb.get("session", sid) + started = session["created"] + if datetime.datetime.utcnow() - datetime.datetime.strptime(unicode(started), '%Y-%m-%dT%H:%M:%S.%f') > cherrypy.request.app.config["slycat"]["session-timeout"]: + couchdb.delete(session) + # expire the old cookie + cherrypy.response.cookie["slycatauth"] = sid + cherrypy.response.cookie["slycatauth"]['expires'] = 0 + session = None except Exception as e: cherrypy.log.error("@%s: could not get db session." % (e)) - # cherrypy.response.headers["www-authenticate"] = "Basic realm=\"%s\"" % realm - # raise cherrypy.HTTPError(401, "Authentication required.") - # TODO: add redirect - if sid in authenticate.sessions: - started = authenticate.sessions[sid]["created"] - if datetime.datetime.utcnow() - started > cherrypy.request.app.config["slycat"]["session-timeout"]: - del authenticate.sessions[sid] - elif session is None: - cherrypy.log.error("@%s: deleting local session." % (remote_ip)) - del authenticate.sessions[sid] - cherrypy.response.headers["www-authenticate"] = "Basic realm=\"%s\"" % realm - raise cherrypy.HTTPError(401, "Authentication required.") - else: - # Ensure that the user is logged correctly ... - cherrypy.request.login = authenticate.sessions[sid]["creator"] - return - else: - # Expired or forged cookie - cherrypy.log.error("@%s: expired/unknown session." % (remote_ip)) - - # If the client hasn't authenticated, tell them to do so. - authorization = cherrypy.request.headers.get("authorization") - if authorization is None: - #raise cherrypy.HTTPRedirect("/login.html", 307) - cherrypy.response.headers["www-authenticate"] = "Basic realm=\"%s\"" % realm - raise cherrypy.HTTPError(401, "Authentication required.") - - # Parse the client's authentication response. - try: - scheme, params = authorization.split(" ", 1) - except: - slycat.email.send_error("slycat-standard-authentication.py authenticate", "cherrypy.HTTPError 400") - raise cherrypy.HTTPError(400) - if scheme.lower() != "basic": - slycat.email.send_error("slycat-standard-authentication.py authenticate", "cherrypy.HTTPError 400") - raise cherrypy.HTTPError(400) - try: - username, password = base64_decode(params).split(":", 1) - except: - slycat.email.send_error("slycat-standard-authentication.py authenticate", "cherrypy.HTTPError 400") - raise cherrypy.HTTPError(400) - - cherrypy.log.error("%s@%s: Checking password." % (username, remote_ip)) - - if authenticate.password_check is None: - if "password-check" not in cherrypy.request.app.config["slycat-web-server"]: - raise cherrypy.HTTPError("500 No password check configured.") - plugin = cherrypy.request.app.config["slycat-web-server"]["password-check"]["plugin"] - args = cherrypy.request.app.config["slycat-web-server"]["password-check"].get("args", []) - kwargs = cherrypy.request.app.config["slycat-web-server"]["password-check"].get("kwargs", {}) - if plugin not in slycat.web.server.plugin.manager.password_checks.keys(): - slycat.email.send_error("slycat-standard-authentication.py authenticate", "cherrypy.HTTPError 500 no password check plugin found.") - raise cherrypy.HTTPError("500 No password check plugin found.") - authenticate.password_check = functools.partial(slycat.web.server.plugin.manager.password_checks[plugin], *args, **kwargs) - - success, groups = authenticate.password_check(realm, username, password) - if success: - # Apply (optional) authentication rules. - if rules is not None: - deny = None - for operation, category, members in rules: - if operation not in ["allow", "deny"]: - slycat.email.send_error("slycat-standard-authentication.py authenticate", "cherrypy.HTTPError 500 unknown operation: %s." % operation) - raise cherrypy.HTTPError("500 Unknown operation: %s." % operation) - if category not in ["users", "groups"]: - slycat.email.send_error("slycat-standard-authentication.py authenticate", "cherrypy.HTTPError 500 unknown category: %s." % category) - raise cherrypy.HTTPError("500 Unknown category: %s." % category) - - operation_default = True if operation == "allow" else False - operation_deny = False if operation == "allow" else True - - if deny is None: - deny = operation_default - if category == "users": - if username in members: - deny = operation_deny - elif category == "groups": - for group in groups: - if group in members: - deny = operation_deny - break - - if deny: - raise cherrypy.HTTPError("403 User denied by authentication rules.") - - # Successful authentication, create a session and return. - cherrypy.log.error("%s@%s: Password check succeeded." % (username, remote_ip)) - - sid = uuid.uuid4().hex - session = {"created": datetime.datetime.utcnow(), "creator": username} - database = slycat.web.server.database.couchdb.connect() - database.save({"_id": sid, "type": "session", "created": session["created"].isoformat(), "creator": session["creator"]}) - - authenticate.sessions[sid] = session - - cherrypy.response.cookie["slycatauth"] = sid - cherrypy.response.cookie["slycatauth"]["path"] = "/" - cherrypy.response.cookie["slycatauth"]["secure"] = 1 - cherrypy.response.cookie["slycatauth"]["httponly"] = 1 - cherrypy.request.login = username - return # successful authentication - - # Authentication failed, tell the client to try again. - cherrypy.log.error("%s@%s: Password check failed." % (username, remote_ip)) - cherrypy.response.headers["www-authenticate"] = "Basic realm=\"%s\"" % realm - slycat.email.send_error("slycat-standard-authentication.py authenticate", "cherrypy.HTTPError 401 authentication failed for user %s." % username) - raise cherrypy.HTTPError(401, "Authentication required.") - - authenticate.password_check = None - authenticate.sessions = {} - authenticate.session_cleanup = None + # there was no session time to authenticate + if session is None: + raise cherrypy.HTTPRedirect("/login/slycat-login.html", 307) + return + # # Apply (optional) authentication rules. + # if rules is not None: + # deny = None + # for operation, category, members in rules: + # if operation not in ["allow", "deny"]: + # slycat.email.send_error("slycat-standard-authentication.py authenticate", "cherrypy.HTTPError 500 unknown operation: %s." % operation) + # raise cherrypy.HTTPError("500 Unknown operation: %s." % operation) + # if category not in ["users", "groups"]: + # slycat.email.send_error("slycat-standard-authentication.py authenticate", "cherrypy.HTTPError 500 unknown category: %s." % category) + # raise cherrypy.HTTPError("500 Unknown category: %s." % category) + # + # operation_default = True if operation == "allow" else False + # operation_deny = False if operation == "allow" else True + # + # if deny is None: + # deny = operation_default + # if category == "users": + # if username in members: + # deny = operation_deny + # elif category == "groups": + # for group in groups: + # if group in members: + # deny = operation_deny + # break + # + # if deny: + # raise cherrypy.HTTPError("403 User denied by authentication rules.") + # + # # Successful authentication, create a session and return. context.register_tool("slycat-standard-authentication", "on_start_resource", authenticate)