diff options
-rw-r--r-- | cgi/modapi.py | 128 |
1 files changed, 83 insertions, 45 deletions
diff --git a/cgi/modapi.py b/cgi/modapi.py index c76cb8b..9b94c0f 100644 --- a/cgi/modapi.py +++ b/cgi/modapi.py @@ -9,30 +9,9 @@ from post import * def api(self, path_split): - validated = False - staff_account = None - - manage_cookie = getCookie(self, 'weabot_manage') - if manage_cookie: - staff_account = validateSession(manage_cookie) - if not staff_account: - self.output = api_error("error", "Session expired") - deleteCookie(self, 'weabot_manage') - - if staff_account: - validated = True - if 'session_id' in staff_account: - renewSession(staff_account['session_id']) - - UpdateDb('UPDATE `staff` SET `lastactive` = ' + str(timestamp() - ) + ' WHERE `id` = ' + staff_account['id'] + ' LIMIT 1') - if len(path_split) > 2: try: - if validated: - self.output = api_process(self, path_split) - else: - self.output = api_error("error", "No has iniciado sesión ") + self.output = api_process(self, path_split) except APIError, e: self.output = api_error("error", e.message) except UserError, e: @@ -56,29 +35,63 @@ def api_process(self, path_split): method = path_split[2] values = {'state': 'success'} - if method == 'news': - news = FetchAll( - "SELECT * FROM `news` WHERE type = 1 ORDER BY `timestamp` DESC") - values['news'] = news - elif method == 'reports': - reports = FetchAll( - "SELECT id, timestamp, timestamp_formatted, postid, parentid, link, board, INET6_NTOA(ip) AS ip, reason, INET6_NTOA(repip) AS repip FROM `reports` ORDER BY `timestamp` DESC") - values['reports'] = reports - elif method == 'logs': - logs = FetchAll("SELECT * FROM `logs` ORDER BY `timestamp` DESC") - values['logs'] = logs - elif method == 'staffPosts': - posts = FetchAll( - "SELECT * FROM `news` WHERE type = '0' ORDER BY `timestamp` DESC") - values['posts'] = posts - elif method == 'login': - # testing - username = formdata.get('username') - password = formdata.get('password') - values['username'] = username - values['password'] = password + validated = False + staff_account = None + + token = formdata.get("token") + if token: + staff_account = validateSession(token) + if not staff_account: + self.output = api_error("error", "Session expired") + + if staff_account: + validated = True + if 'session_id' in staff_account: + renewSession(staff_account['session_id']) + + UpdateDb('UPDATE `staff` SET `lastactive` = ' + str(timestamp() + ) + ' WHERE `id` = ' + staff_account['id'] + ' LIMIT 1') + + if validated == False: + if method == 'login': + if 'username' in self.formdata and 'password' in self.formdata: + staff_account = verifyPasswd( + formdata.get("username"), formdata.get("password")) + if staff_account: + session_uuid = newSession(staff_account['id']) + values["token"] = session_uuid + UpdateDb('DELETE FROM `logs` WHERE `timestamp` < ' + + str(timestamp() - 604800)) # one week + else: + logAction('', 'Failed log-in. Username:'+_mysql.escape_string( + self.formdata['username'])+' IP:'+self.environ["REMOTE_ADDR"]) + raise APIError, "Incorrect username/password." + else: + raise APIError, "Not authenticated" else: - raise APIError, "Invalid method" + if method == 'news': + news = FetchAll( + "SELECT * FROM `news` WHERE type = 1 ORDER BY `timestamp` DESC") + values['news'] = news + elif method == 'reports': + reports = FetchAll( + "SELECT id, timestamp, timestamp_formatted, postid, parentid, link, board, INET6_NTOA(ip) AS ip, reason, INET6_NTOA(repip) AS repip FROM `reports` ORDER BY `timestamp` DESC") + values['reports'] = reports + elif method == 'logs': + logs = FetchAll("SELECT * FROM `logs` ORDER BY `timestamp` DESC") + values['logs'] = logs + elif method == 'staffPosts': + posts = FetchAll( + "SELECT * FROM `news` WHERE type = '0' ORDER BY `timestamp` DESC") + values['posts'] = posts + elif method == 'login': + # testing + username = formdata.get('username') + password = formdata.get('password') + values['username'] = username + values['password'] = password + else: + raise APIError, "Invalid method" values['time'] = int(t) return json.dumps(values, sort_keys=True, separators=(',', ':')) @@ -149,7 +162,32 @@ def cleanSessions(): def logAction(staff, action): InsertDb("INSERT INTO `logs` (`timestamp`, `staff`, `action`) VALUES (" + str(timestamp()) + - ", '" + _mysql.escape_string(staff) + "\', \'" + _mysql.escape_string(action) + "\')") + ", '" + _mysql.escape_string(staff) + "\', \' [API] " + _mysql.escape_string(action) + "\')") + + +def verifyPasswd(username, passwd): + import argon2 + ph = argon2.PasswordHasher() + + param_username = _mysql.escape_string(username) + staff_account = FetchOne( + "SELECT * FROM staff WHERE username = '%s'" % param_username) + if not staff_account: + return None + + try: + ph.verify(staff_account['password'], passwd) + except argon2.exceptions.VerifyMismatchError: + return None + except argon2.exceptions.InvalidHash: + raise UserError, "Hash obsoleto o inválido. Por favor contacte al administrador." + + if ph.check_needs_rehash(staff_account['password']): + param_new_hash = ph.hash(staff_acount['password']) + UpdateDb("UPDATE staff SET password = '%s' WHERE id = %s" % + (param_new_hash, staff_account['id'])) + + return staff_account class APIError(Exception): |