From cb2db16ad096de898d9e10a49a7448adef2991f4 Mon Sep 17 00:00:00 2001 From: Hailey Clark Date: Thu, 22 Oct 2020 02:36:22 -0700 Subject: [PATCH] Syntax cleaning A lot of cleaning of syntax after re-installing my computer and having to re-setup mariadb. I will try and make a dump of the example database. --- app_auth.py | 70 ++++++----- app_settings.py | 41 ++++--- appdb.py | 273 +++++++++++++++++++++++++++---------------- appsms.py | 27 +++-- callback_sms.py | 32 ++--- database.sql | 1 + smsproj.py | 213 ++++++++++++++++++++++++--------- templates/inbox.html | 73 +++++++++++- 8 files changed, 510 insertions(+), 220 deletions(-) diff --git a/app_auth.py b/app_auth.py index 9db3fb5..40a0a28 100644 --- a/app_auth.py +++ b/app_auth.py @@ -1,29 +1,31 @@ -import hashlib, binascii, os +import hashlib import flask -from flask import Flask, request, redirect, url_for -import hashlib, binascii -from passlib.hash import pbkdf2_sha256 +from flask import request, redirect +import binascii +# from passlib.hash import functools import os -salt = os.urandom(32) import appdb import pprint -#import google_auth +# import google_auth import configparser +salt = os.urandom(32) config = configparser.ConfigParser() config.read('config.ini') -app_debug = config.get("app","debug") -app_salt = config.get("auth","FN_FLASK_SECRET_KEY") +app_debug = config.get("app", "debug") +app_salt = config.get("auth", "FN_FLASK_SECRET_KEY") login_redirect = "/" app = flask.Blueprint('app_auth', __name__) app.debug = True + def no_cache(view): @functools.wraps(view) def no_cache_impl(*args, **kwargs): response = flask.make_response(view(*args, **kwargs)) + response.headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0' response.headers['Pragma'] = 'no-cache' response.headers['Expires'] = '-1' @@ -31,27 +33,35 @@ def no_cache(view): return functools.update_wrapper(no_cache_impl, view) + def is_logged_in(): - return True if 'loginid' in flask.session else False - if flask.session.loggedin: + if flask.session.get('loginid'): pprint.pprint('Flask session loginhash:') - pprint.pprint(flask.session.loggedin) - return True + pprint.pprint(flask.session.get('loginid')) + if appdb.verify_id( + flask.session.get('email'), + flask.session.get('loginid')) is True: + return True + return False return False + def verify_login(email, password): result = appdb.verify_login(email, password) if result: return True return False + @app.route('/auth/login', methods=['POST']) @no_cache def auth_login(): """Login using provided credentials""" - #pprint.pprint('Got credentials offff') - #pprint.pprint(request.form) - if appdb.verify_login(request.form['email'],hash_password(request.form['passwd'].encode('ascii'))): + # pprint.pprint('Got credentials offff') + # pprint.pprint(request.form) + if appdb.verify_login( + request.form['email'], + hash_password(request.form['passwd'].encode('ascii'))): pprint.pprint("got variables") uniqueID = appdb.generate_id(request.form['email']) flask.session['loggedin'] = True @@ -61,50 +71,58 @@ def auth_login(): flask.session['password'] = request.form['passwd'] return "/" return "error" - #return login_redirect + # return login_redirect + @app.route('/auth/register', methods=['POST']) @no_cache def auth_register_login(): """Create a login using the supplied credentials in request.form""" - #pprint.pprint('Got credentials offff') - #pprint.pprint(request.form) + # pprint.pprint('Got credentials offff') + # pprint.pprint(request.form) return "DISABLED" + @app.route('/auth/updatepw', methods=['POST']) @no_cache def auth_updatepw(): - '''This takes three post variables to match the old password then match two passwords - forms then update password if it all checks out.''' + '''This takes three post variables to match the old password then match two + passwords forms then update password if it all checks out.''' + if not is_logged_in(): return "error" if flask.session['loginid']: - user_info = appdb.getUserInfo(flask.session['email'],flask.session['loginid']) + user_info = appdb.getUserInfo( + flask.session['email'], flask.session['loginid']) passzero = request.form['passwdzero'] passone = request.form['passwdone'] orighash = hash_password(passzero.encode('ascii')) newhash = hash_password(passone.encode('ascii')) - if (appdb.updatePass(user_info[0],orighash,newhash)): + if (appdb.updatePass(user_info[0], orighash, newhash)): return '200' return "error" + @app.route('/auth/logout') @no_cache def auth_logout(): flask.session.clear() return redirect('/') + def hash_password(password): """Hash a password for storing.""" - pwdhash = hashlib.pbkdf2_hmac('sha512', password, app_salt.encode('ascii'), 100000) - #hash = pbkdf2_sha256.encrypt(password, rounds=200000, salt_size=16) + pwdhash = hashlib.pbkdf2_hmac( + 'sha512', password, app_salt.encode('ascii'), 100000) + # hash = pbkdf2_sha256.encrypt(password, rounds=200000, salt_size=16) pwdhash = binascii.hexlify(pwdhash).decode('ascii') return pwdhash + def verify_password(stored_password, provided_password): """Verify a stored password against one provided by user""" - pwdhash = hashlib.pbkdf2_hmac('sha512', provided_password, - app_salt.encode('ascii'), 100000) + pwdhash = hashlib.pbkdf2_hmac( + 'sha512', provided_password, app_salt.encode('ascii'), 100000) pwdhash = binascii.hexlify(pwdhash).decode('ascii') return pwdhash == stored_password diff --git a/app_settings.py b/app_settings.py index 3ad0b59..a35fc74 100644 --- a/app_settings.py +++ b/app_settings.py @@ -1,18 +1,19 @@ #!/usr/bin/env python3 -#app_settings.py +# app_settings.py -import functools -import os +# import functools +# import os import pprint import configparser import json import flask -import appdb, app_auth +import appdb +import app_auth config = configparser.ConfigParser() config.read('config.ini') -app_debug = config.get("app","debug") +app_debug = config.get("app", "debug") app = flask.Blueprint('app_settings', __name__) if app_debug == '1': @@ -20,29 +21,34 @@ if app_debug == '1': else: app.debug = False + @app.route('/settings') def appsettings(): - '''This function pulls some information and then renders the settings or error template''' + '''This function pulls some information and then renders the settings or + error template''' if flask.session.get('loginid'): - user_info = appdb.getUserInfo(flask.session['email'],flask.session['loginid']) + user_info = appdb.getUserInfo(flask.session['email'], + flask.session['loginid']) loggedin = True else: user_info = False - indbRes = False - return flask.render_template('deny.html', denymsg = "I don't know who you are so I can't help you with your user settings. :(", loggedin = False) + # indbRes = False + return flask.render_template('deny.html', + denymsg="I don't know who you are so I can't help you with your user settings. :(", loggedin = False) if user_info: rows = appdb.getDIDsbyAccount(user_info[0]) pprint.pprint(user_info) accountInfo = appdb.getInfobyEmail(user_info[2]) - pprint.pprint(accountInfo) else: - return 'error'; + # loggedin = False + return flask.render_template('homepage.html', loggedin=False) return flask.render_template('settings.html', - user_info = user_info, - account_info = accountInfo, - dids = rows, - loggedin = True) + user_info=user_info, + account_info=accountInfo, + dids=rows, + loggedin=True) + @app.route('/checkUsername/', methods=['GET']) def checkUsername(username): @@ -53,13 +59,14 @@ def checkUsername(username): return json.dumps({'error': 'Username already exists, please choose another.'}) return json.dumps({'name': 'Available'}) + @app.route('/createUser', methods=['POST']) def createUser(): '''Create the rest of the db entry for the user''' username = flask.request.form['username'] password = flask.request.form['password'] email = flask.request.form['email'] - #user_info = google_auth.get_user_info() + # user_info = google_auth.get_user_info() if appdb.isUserExist(username): return json.dumps({'error': 'Username already exists. Please choose another.'}) @@ -72,7 +79,7 @@ def createUser(): passwd = app_auth.hash_password(password.encode('ascii')) res = appdb.finalizeNewUser(email, username, passwd) if app_debug == '1': - pprint.pprint('Updating email, username, passwd' + email ) + pprint.pprint('Updating email, username, passwd' + email) if res: return json.dumps({'msg': 'Success!'}) return json.dumps({'error': 'There is an error in processing the request.'}) diff --git a/appdb.py b/appdb.py index 8582b39..311fdd2 100755 --- a/appdb.py +++ b/appdb.py @@ -1,39 +1,43 @@ #!/usr/bin/env python3 -#appdb.py -#We connect to our database and any database calls are put into functions here. +# appdb.py +# We connect to our database and any database calls are put here. import pymysql import pymysql.cursors import pprint import uuid -#import time +# import time import configparser config = configparser.ConfigParser() config.read('config.ini') -sqlhost = config.get("sql","sqlhost") -sqlport = int(config.get("sql","sqlport")) -sqluser = config.get("sql","sqluser") -sqlpass = config.get("sql","sqlpass") -sqldb = config.get("sql","sqldb") -app_debug = config.get("app","debug") - - -def logsms_db(msg_id, msg_ts, direction, to_did, from_did, cost, status, msg, account_id): - #This statement logs a SMS to the smslog table. - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) +sqlhost = config.get("sql", "sqlhost") +sqlport = int(config.get("sql", "sqlport")) +sqluser = config.get("sql", "sqluser") +sqlpass = config.get("sql", "sqlpass") +sqldb = config.get("sql", "sqldb") +app_debug = config.get("app", "debug") + + +def logsms_db(msg_id, msg_ts, direction, to_did, from_did, cost, status, msg, + account_id): + '''This statement logs a SMS to the smslog table.''' + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() - cur.execute("INSERT INTO messages (`timestamp`, `provider_timestamp`,`direction`, `source_number`, `dest_number`, `cost`,`pid`,`status`, `body`, `account_id`)VALUES \ - (now(), %s, %s, %s, %s, %s, %s, %s, %s, %s)",(msg_ts, direction, from_did, to_did, cost, msg_id, status, msg, account_id)) + cur.execute("INSERT INTO messages (`timestamp`, `provider_timestamp`, `direction`, `source_number`, `dest_number`, `cost`, `pid`, `status`, `body`, `account_id`) VALUES (now(), %s, %s, %s, %s, %s, %s, %s, %s, %s)", + (msg_ts, direction, from_did, to_did, cost, msg_id, status, msg, account_id)) db.commit() db.close() return True + def getUserInfobyID(id): '''This pulls * from 'account' and returns it if it matches an email.''' - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() - cur.execute("SELECT * FROM account WHERE id=%s LIMIT 1",(id)) + cur.execute("SELECT * FROM account WHERE id=%s LIMIT 1", (id)) data = cur.fetchone() db.close() if app_debug == '1': @@ -43,72 +47,76 @@ def getUserInfobyID(id): return False return data -def isGUserinDB(google_id): - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) + +def isUserinDB(id): + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() - cur.execute("SELECT * FROM account WHERE google_id=%s LIMIT 1" % google_id) + cur.execute("SELECT * FROM account WHERE id=%s LIMIT 1" % id) data = cur.fetchone() db.close() if data: pprint.pprint(data) - return True + return data else: return False -def isUserinDB(id): - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) - cur = db.cursor() - cur.execute("SELECT * FROM account WHERE id=%s LIMIT 1" % id) - data = cur.fetchone() - db.close() - if data: - pprint.pprint(data) - return data - else: - return False def isUserExist(email): - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() - cur.execute("SELECT email FROM account WHERE email=%s",(name)) + cur.execute("SELECT email FROM account WHERE email=%s", (email)) data = cur.fetchone() db.close() if data: return True return False + def generate_id(email): - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() newID = uuid.uuid4().hex - cur.execute("UPDATE account SET loginid=%s WHERE email=%s LIMIT 1",(newID, email)) + cur.execute("UPDATE account SET loginid=%s WHERE email=%s LIMIT 1", + (newID, email)) db.commit() db.close() return newID def verify_id(email, uniqueid): - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() - cur.execute("SELECT email FROM account WHERE email=%s AND loginid=%s LIMIT 1",(email, uniqueid)) + cur.execute( + "SELECT email FROM account WHERE email=%s AND loginid=%s LIMIT 1", + (email, uniqueid)) data = cur.fetchone() db.close() if data: return True return False + def verify_login(email, password): - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() - cur.execute("SELECT email FROM account WHERE email=%s AND passwd=%s LIMIT 1",(email, password)) + cur.execute( + "SELECT email FROM account WHERE email=%s AND passwd=%s LIMIT 1", + (email, password)) data = cur.fetchone() db.close() if data: return data return False + def getUserInfo(email, uniqueid): - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() cur.execute("SELECT * FROM account WHERE email=%s AND loginid=%s LIMIT 1",(email, uniqueid)) data = cur.fetchone() @@ -119,9 +127,12 @@ def getUserInfo(email, uniqueid): if data: return data return False + + def isUserVerfied(google_id): - #This checks to see if the account is set to verified true - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) + '''This checks to see if the account is set to verified true''' + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() cur.execute("SELECT verified_email FROM account WHERE google_id=%s",(google_id)) data = cur.fetchone() @@ -131,18 +142,22 @@ def isUserVerfied(google_id): else: return False + def registerUser(email, password): - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() - #cur.execute("INSERT INTO account (`name`, `email`, `refresh_token`, `user_id`, `verified_email`, `created`, `last_modified`) VALUES \ + # cur.execute("INSERT INTO account (`name`, `email`, `refresh_token`, `user_id`, `verified_email`, `created`, `last_modified`) VALUES \ # (%s, %s, %s, %s, %s, NOW(), NOW())",(name, email, refresh_token, user_id, verified)) db.commit() db.close() return "Success!" + def setNewUser(user_id, refresh_token, name, email, verified): - #This statement is for creating a user into the account table. - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) + '''This statement is for creating a user into the account table.''' + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() cur.execute("INSERT INTO account (`name`, `email`, `refresh_token`, `user_id`, `verified_email`, `created`, `last_modified`) VALUES \ (%s, %s, %s, %s, %s, NOW(), NOW())",(name, email, refresh_token, user_id, verified)) @@ -150,10 +165,13 @@ def setNewUser(user_id, refresh_token, name, email, verified): db.close() return True + def finalizeNewUser(email, username, passwd): - '''Finalizes a user creation after calling setNewUser(), this requires a password already converted to a - safe hash of the password. Don't store plaintext passwords in this please''' - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) + '''Finalizes a user creation after calling setNewUser(), this requires a + password already converted to a safe hash of the password. Don't store + plaintext passwords in this please''' + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() rows = cur.execute("UPDATE account SET username=%s, passwd=%s, verified_email=%s, last_modified=NOW() WHERE email=%s LIMIT 1",(username, passwd,2, email)) db.commit() @@ -163,11 +181,13 @@ def finalizeNewUser(email, username, passwd): else: return False + def getInfobyEmail(email): '''This pulls * from 'account' and returns it if it matches an email.''' - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() - cur.execute("SELECT * FROM account WHERE email=%s LIMIT 1",(email)) + cur.execute("SELECT * FROM account WHERE email=%s LIMIT 1", (email)) data = cur.fetchone() db.close() if app_debug == '1': @@ -177,53 +197,49 @@ def getInfobyEmail(email): return False return data + def getUserIdFromRT(refreshtoken): - #This pulls an UserID from a Refresh Token - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) + '''This pulls an UserID from a Refresh Token''' + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() - cur.execute("SELECT id FROM account WHERE refresh_token=%s",(refreshtoken)) + cur.execute("SELECT id FROM account WHERE loginid=%s", (refreshtoken)) data = cur.fetchone() db.close() if not data: return False return data[0] -def getUserIDfromGoogleID(google_id): - #This pulls an UserID from a Google ID - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) - cur = db.cursor() - cur.execute("SELECT id FROM account WHERE google_id=%s",(google_id)) - data = cur.fetchone() - db.close() - if not data: - return False - return data[0] def getAccountbyDID(did): - #This function pulls the account id for the DID in the query. - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) + '''This function pulls the account id for the DID in the query.''' + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() - cur.execute("SELECT account_id FROM dids WHERE number=%s LIMIT 1",(did)) + cur.execute("SELECT account_id FROM dids WHERE number=%s LIMIT 1", (did)) data = cur.fetchone() db.close() if not data: return False return data[0] + def getDIDsbyAccount(account_id): - #DIDs that are assigned to an account. - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) + '''DIDs that are assigned to an account.''' + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() - cur.execute("SELECT number,provider FROM dids WHERE account_id=%s",(account_id)) + cur.execute("SELECT number,provider FROM dids WHERE account_id=%s", (account_id)) rows = cur.fetchall() db.close() return rows -def authIdforDID(account_id,did): - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) +def authIdforDID(account_id, did): + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() - cur.execute("SELECT account.id FROM dids,account WHERE dids.account_id=account.id AND account.id=%s AND dids.number=%s LIMIT 1",(account_id,did)) + cur.execute("SELECT account.id FROM dids,account WHERE dids.account_id=account.id AND account.id=%s AND dids.number=%s LIMIT 1", (account_id,did)) data = cur.fetchone() db.close() pprint.pprint("Printing AUTH ID") @@ -232,17 +248,22 @@ def authIdforDID(account_id,did): else: return False + def setRefreshToken(refresh_token, google_id): - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() pprint.pprint("Setting new refresh token of " + google_id + " and " + refresh_token) - cur.execute("UPDATE account SET refresh_token=%s WHERE google_id=%s",(refresh_token, google_id)) + cur.execute("UPDATE account SET refresh_token=%s WHERE google_id=%s", + (refresh_token, google_id)) db.commit() db.close() return True + def getAccountId(uniqueID): - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() cur.execute("SELECT id FROM account WHERE loginid=%s LIMIT 1", uniqueID) rows = cur.fetchall() @@ -251,72 +272,122 @@ def getAccountId(uniqueID): return rows return False + def getAllSMSLog(limit=5, order='desc'): - #This gets the last X amount of logs from all numbers. - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) + '''This gets the last X amount of logs from all numbers.''' + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() - cur.execute("SELECT * FROM messages ORDER BY timestamp DESC LIMIT %s",(limit)) + cur.execute("SELECT * FROM messages ORDER BY timestamp DESC LIMIT %s", + (limit)) rows = cur.fetchall() db.close() return rows + def getSMSbyAccount(account_id, limit=5): - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() cur.execute("SELECT messages.* FROM messages, account WHERE messages.account_id=account.id AND ACCOUNT.loginid=%s ORDER BY id DESC LIMIT %s",(account_id, limit)) rows = cur.fetchall() db.close() return rows + def getNumSMSLog(did, limit=5): - #This gets the last X amount of logs from all numbers. - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) + '''This gets the last X amount of logs from all numbers.''' + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() cur.execute("SELECT * FROM messages WHERE source_number=%s OR dest_number=%s ORDER BY timestamp DESC LIMIT %s",(did,did,limit)) rows = cur.fetchall() - #for row in rows: - #pprint.pprint(row) + # for row in rows: + # pprint.pprint(row) db.close() return rows + +def updateReadStatus(msg_id, isread): + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) + cur = db.cursor() + affected_count = cur.execute("UPDATE messages SET is_read=%s WHERE id=%s", + (isread, msg_id)) + db.commit() + db.close() + return affected_count + + +def updateMarkAllRead(account_id): + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) + cur = db.cursor() + affected_count = cur.execute("UPDATE messages SET is_read=1 WHERE account_id=%s", + (account_id)) + db.commit() + db.close() + return affected_count + + +def updateMarkAllUnread(account_id): + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) + cur = db.cursor() + affected_count = cur.execute("UPDATE messages SET is_read=0 WHERE account_id=%s", + (account_id)) + db.commit() + db.close() + return affected_count + + def updateMsgStatus(msg_id, status, msg_timestamp): - #Update the delivered field in the database based on delivery reports. - #UPDATE messages SET delivered='success' WHERE pid='mdr2-46999f9ce19e11e99074722a1f1f4bb4' - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) + '''Update the delivered field in the database based on delivery reports.''' + + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() - affected_count = cur.execute("UPDATE `messages` SET status=%s, `provider_timestamp`=%s WHERE `pid`=%s",(status, msg_timestamp ,msg_id)) + affected_count = cur.execute("UPDATE `messages` SET status=%s, `provider_timestamp`=%s WHERE `pid`=%s", + (status, msg_timestamp, msg_id)) db.commit() db.close() return affected_count + def updateMsgTimestamp(msg_id, timestamp): - #This changes the timestamp of the msg_id to the timestamp provided by the provider. - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) + '''This changes the timestamp of the msg_id to the timestamp provided by + the provider.''' + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() affected_count = cur.execute("UPDATE `messages` SET `provider_timestamp`=%s WHERE `pid`=%s",(timestamp,msg_id)) db.commit() db.close() return affected_count -def updatePass(account_id, origpass,newpass): - '''updatePass(origpass, newpass) this assumes newpass has been verified twice - and origpass equals the current password. Returns the amount of rows updated which should - always be 1 or 0.''' - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) + +def updatePass(account_id, origpass, newpass): + '''updatePass(origpass, newpass) this assumes newpass has been verified + twice and origpass equals the current password. Returns the amount of rows + updated which should always be 1 or 0.''' + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() - #pprint.pprint("Updating the following %s with old pass %s",(account_id, origpass)) + # pprint.pprint("Updating the following %s with old pass %s",(account_id, origpass)) affected_count = cur.execute("UPDATE account SET passwd=%s WHERE id=%s AND passwd=%s LIMIT 1",(newpass,account_id,origpass)) db.commit() db.close() return affected_count + def validateFrom(did): - # Looks up in the DB to see if a DID is a valid DID - db = pymysql.connect(host=sqlhost, port=sqlport, user=sqluser, passwd=sqlpass, db=sqldb) + '''Looks up in the DB to see if a DID is a valid DID''' + db = pymysql.connect(host=sqlhost, port=sqlport, + user=sqluser, passwd=sqlpass, db=sqldb) cur = db.cursor() cur.execute("SELECT number FROM dids WHERE number=%s LIMIT 1" % did) data = cur.fetchone() db.close() - if data != None and int(data[0]) == int(did): + if data is not None and int(data[0]) == int(did): return True return False diff --git a/appsms.py b/appsms.py index 449e471..ef8af1c 100644 --- a/appsms.py +++ b/appsms.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -#appsms.py -import time +# appsms.py +# import time import re import configparser from flowroutenumbersandmessaging.flowroutenumbersandmessaging_client import FlowroutenumbersandmessagingClient @@ -9,22 +9,31 @@ fr_api_url = "https://api.flowroute.com/v2.2/messages" config = configparser.ConfigParser() config.read('config.ini') -basic_auth_user_name = config.get("flowroute","fr_access_key") -basic_auth_password = config.get("flowroute","fr_secret_key") +basic_auth_user_name = config.get("flowroute", "fr_access_key") +basic_auth_password = config.get("flowroute", "fr_secret_key") -client = FlowroutenumbersandmessagingClient(basic_auth_user_name, basic_auth_password) +client = FlowroutenumbersandmessagingClient( + basic_auth_user_name, basic_auth_password) messages_controller = client.messages + def prettyPhone(phonenumber): - result = re.search('1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})?',str(phonenumber)) - prettystr = "(" + result.group(1) + ") " + result.group(2) + "-" + result.group(3) + result = re.search( + '1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})?', + str(phonenumber)) + prettystr = "(" + result.group(1) + ") " +\ + result.group(2) + "-" + result.group(3) return prettystr + def uglyPhone(phonenumber): - result = re.search('1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})?',str(phonenumber)) + result = re.search( + '1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})?', + str(phonenumber)) uglystr = "1" + result.group(1) + result.group(2) + result.group(3) return uglystr + def sendsms(reply_to, reply_from, msg): request_body = '{ \ "data": { "type": "message", \ @@ -35,7 +44,7 @@ def sendsms(reply_to, reply_from, msg): } } }' result = messages_controller.send_a_message(request_body) - if result: + if result: msg_id = result['data']['id'] return msg_id return False diff --git a/callback_sms.py b/callback_sms.py index ee16fad..3cfd2ce 100644 --- a/callback_sms.py +++ b/callback_sms.py @@ -1,13 +1,14 @@ #!/usr/bin/env python3 -import os -import urllib -import json +# import os +# import urllib +# import json import pprint -import time -import datetime -import string -import appdb, appsms +# import time +# import datetime +# import string +import appdb +# import appsms import configparser import flask @@ -18,10 +19,11 @@ app = flask.Blueprint('callback-sms', __name__) # This is so bare I don't need a config right now. config = configparser.ConfigParser() config.read('config.ini') -app_debug = config.get("app","debug") +app_debug = config.get("app", "debug") + ############################# -## Callback defs go here +# Callback defs go here def prettyStatus(status): if status == 'message buffered': return 'Delivered' @@ -36,9 +38,11 @@ def prettyStatus(status): elif status == 'smsc intermediate notifications': return 'Sent' + @app.route('/sms-inbound', methods=['POST']) def smsinbound(): - #extract attributes from POSTed JSON of inbound SMS + '''extract attributes from POSTed JSON of inbound SMS''' + json_content = flask.request.json reply_to = json_content['data']['attributes']['from'] reply_from = json_content['data']['attributes']['to'] @@ -48,12 +52,14 @@ def smsinbound(): smsRate = json_content['data']['attributes']['amount_display'].replace('$','') status = 'Delivered' account_id = appdb.getAccountbyDID(reply_from) - appdb.logsms_db(msg_id, msg_timestamp, 'inbound', reply_from, reply_to, smsRate, status, body, account_id) # Lets log to our silly db. + appdb.logsms_db(msg_id, msg_timestamp, 'inbound', reply_from, reply_to, + smsRate, status, body, account_id) # Lets log to our silly db. return "200" -@app.route('/dlr', methods=['POST','GET']) + +@app.route('/dlr', methods=['POST', 'GET']) def deliveryReport(): - #This is the delivery report callback function. + '''This is the delivery report callback function.''' json_content = flask.request.json pprint.pprint(json_content) msg_id = json_content['data']['id'] diff --git a/database.sql b/database.sql index 09b1d55..b14e099 100644 --- a/database.sql +++ b/database.sql @@ -119,3 +119,4 @@ ALTER TABLE account DROP COLUMN `username`; ALTER TABLE account DROP COLUMN `refresh_token`; ALTER TABLE account ADD COLUMN `loginid` VARCHAR(255) NULL UNIQUE; ALTER TABLE account ADD COLUMN `picture_url` VARCHAR(255) NULL; +ALTER TABLE messages ADD COLUMN `is_read` BOOL NOT NULL DEFAULT '0'; diff --git a/smsproj.py b/smsproj.py index 0375e5a..54cccf4 100644 --- a/smsproj.py +++ b/smsproj.py @@ -1,26 +1,27 @@ #!/usr/bin/env python3 -# This program runs a flask daemon to provide communications with flowroute n stuff. +# This program runs a flask daemon to provide communications with flowroute n +# stuff. import time -import datetime +# import datetime import pprint import configparser import json -import re +# import re import flask -#from authlib.client import OAuth2Session -#import google.oauth2.credentials -#import googleapiclient.discovery -import appdb, appsms, app_settings, app_auth -#import google_auth + +import appdb +import appsms +import app_settings +import app_auth import callback_sms config = configparser.ConfigParser() config.read('config.ini') -app_debug = config.get("app","debug") +app_debug = config.get("app", "debug") app = flask.Flask(__name__) -app.secret_key = config.get("auth","FN_FLASK_SECRET_KEY") +app.secret_key = config.get("auth", "FN_FLASK_SECRET_KEY") app.register_blueprint(callback_sms.app) app.register_blueprint(app_settings.app) @@ -33,64 +34,83 @@ if app_debug == '1': else: app.debug = False + @app.route('/') def index(): '''This is the root index. If not logged in it displays homepage.html''' if flask.session.get('loginid'): - user_info = appdb.getUserInfo(flask.session['email'],flask.session['loginid']) - loggedin = True + user_info = appdb.getUserInfo( + flask.session['email'], flask.session['loginid']) + if not user_info: - return flask.render_template('homepage.html', loggedin = False) + return flask.render_template('homepage.html', loggedin=False) rows = appdb.getDIDsbyAccount(flask.session['account_id']) return flask.render_template('index.html', - name = user_info[2], - picture = user_info[8], - dids = rows, - loggedin = True) + name=user_info[2], + picture=user_info[8], + dids=rows, + loggedin=True) else: - return flask.render_template('homepage.html', loggedin = False) + return flask.render_template('homepage.html', loggedin=False) + @app.route('/landing') def landingPage(): '''This renders the landing page''' - #user_info = google_auth.get_user_info() + # user_info = google_auth.get_user_info() if flask.session['loginid']: - user_info = appdb.getUserInfo(flask.session['email'],flask.session['loginid']) - #Going to replace google_auth with a local authentication. + user_info = appdb.getUserInfo( + flask.session['email'], flask.session['loginid']) + # Going to replace google_auth with a local authentication. if app_auth.is_logged_in(): loggedin = True else: loggedin = False - return flask.render_template('landing.html', user_info = user_info, loggedin = loggedin) + return flask.render_template( + 'landing.html', user_info=user_info, loggedin=loggedin) + @app.route('/single/', methods=['GET']) def manageSingleSMS(number): - '''This renders a view for a single SMS number and its associated messages''' + '''This renders a view for a single SMS number and its + associated messages''' if not app_auth.is_logged_in(): - return flask.render_template('deny.html',denymsg = loginMsg, loggedin = False) + return flask.render_template( + 'deny.html', denymsg=loginMsg, loggedin=False) if flask.session['loginid']: - user_info = appdb.getUserInfo(flask.session['email'],flask.session['loginid']) + user_info = appdb.getUserInfo( + flask.session['email'], flask.session['loginid']) - result = appdb.authIdforDID(user_info[0],number) + result = appdb.authIdforDID(user_info[0], number) prettynum = appsms.prettyPhone(number) if appdb.validateFrom(int(number)) and result: - return flask.render_template('single.html',srcnumber = number, prettynum = prettynum, loggedin = True) + return flask.render_template( + 'single.html', + srcnumber=number, + prettynum=prettynum, + loggedin=True) else: - return flask.render_template('notvalid.html', srcnumber = number, prettynum = prettynum, loggedin = True) + return flask.render_template( + 'notvalid.html', + srcnumber=number, + prettynum=prettynum, + loggedin=True) #Gotta redo this logic @app.route('/getNumber/',methods=['GET']) def getNumMessages(number): '''Return the messages from a single DID in json form''' - #This gets the mssages based on the provided from or two DID + # This gets the mssages based on the provided from or two DID if not app_auth.is_logged_in(): return json.dumps({'error': 'Unable to send SMS, you are not logged in'}) + # We need to take and compare the authIDforDID, gotta add use id + # to getNumSMSLog and pull the id from result. userid = flask.session['account_id'] - result = appdb.authIdforDID(userid,number) - smslog = appdb.getNumSMSLog(number,10) + result = appdb.authIdforDID(userid, number) + smslog = appdb.getNumSMSLog(number, 10) i = 0 msgjson = "" @@ -98,14 +118,61 @@ def getNumMessages(number): prettyto = appsms.prettyPhone(line[7]) prettyfrom = appsms.prettyPhone(line[6]) if i >= 1: - msgjson = msgjson + ',' + json.dumps({'to':prettyto,'from':prettyfrom,'body':line[9],'timestamp': line[4],'status': line[10]}) + msgjson = msgjson + ',' + json.dumps({'to': prettyto, + 'from': prettyfrom, + 'body': line[9], + 'timestamp': line[4], + 'status': line[10]}) else: - msgjson = json.dumps({'to':prettyto,'from':prettyfrom,'body':line[9],'timestamp': line[4], 'status': line[10]}) + msgjson = json.dumps({'to': prettyto, + 'from': prettyfrom, + 'body': line[9], + 'timestamp': line[4], + 'status': line[10]}) i += 1 + msgArrayJson = '[' + msgjson + ']' + return msgArrayJson - msgArrayJson = '['+msgjson +']' - return msgArrayJson +@app.route('/markread/', methods=['GET']) +def markread(msg_id): + '''This will mark the id for the message as read.''' + if not app_auth.is_logged_in(): + return json.dumps({'error': 'Unable to send SMS, you are not logged in'}) + if appdb.updateReadStatus(msg_id, 1) == 0: + return json.dumps({'error': 'Unable to update the read status.'}) + else: + return json.dumps({'status': 'success'}) + + +@app.route('/markallread', methods=['GET']) +def markallread(): + '''This will mark every EVERY I said, message for the user id which should + be pulled from session info.''' + if not app_auth.is_logged_in(): + return json.dumps({'error': 'Unable to send SMS, you are not logged in'}) + userid = flask.session['account_id'] + if appdb.updateMarkAllRead(userid) == 0: + return json.dumps({'error': + 'Nothing to update or error updating the read status.'}) + else: + return json.dumps({'status': 'success'}) + return False + + +@app.route('/markallunread', methods=['GET']) +def markallunread(): + '''This will mark every EVERY I said, message for the user id which should + be pulled from session info.''' + if not app_auth.is_logged_in(): + return json.dumps({'error': 'Unable to send SMS, you are not logged in'}) + userid = flask.session['account_id'] + if appdb.updateMarkAllUnread(userid) == 0: + return json.dumps({'error': 'Nothing to update or error updating the read status.'}) + else: + return json.dumps({'status':'success'}) + return False + @app.route('/submitMessage', methods=['POST']) def submitMessage(): @@ -118,31 +185,40 @@ def submitMessage(): fromDid = flask.request.form['fromdid'] targetDid = flask.request.form['targetdid'] - user_info = appdb.getUserInfo(flask.session['email'],flask.session['loginid']) + # user_info = appdb.getUserInfo( + # flask.session['email'], + # flask.session['loginid']) userid = flask.session['account_id'] - result = appdb.authIdforDID(userid,fromDid) + result = appdb.authIdforDID(userid, fromDid) if userid != result: - return json.dumps({'error': 'Unauthorized UserID of ' + str(userid) + " and DID id of " + str(result) + " and fromDID " + str(fromDid)}) + return json.dumps({'error': 'Unauthorized UserID of ' + str(userid) + + " and DID id of " + str(result) + " and fromDID " + + str(fromDid)}) - if appdb.validateFrom(fromDid) == False: + if appdb.validateFrom(fromDid) is False: return json.dumps({'error': 'Unauthorized source phone number.'}) uglyphone = appsms.uglyPhone(targetDid) - #pprint.pprint('Got ' + message + ',' + fromDid) - msg_id = appsms.sendsms(uglyphone,fromDid,message) - if msg_id == False: #This sends the sms! + # pprint.pprint('Got ' + message + ',' + fromDid) + msg_id = appsms.sendsms(uglyphone, fromDid, message) + if msg_id is False: # This sends the sms! returndata = json.dumps({'error': 'Unable to send SMS'}) else: - msgTS = time.strftime("%Y-%m-%dT%H:%m:%SZ") - appdb.logsms_db(msg_id, msgTS, 'outbound', uglyphone, fromDid, 0.0040, 'pending', message, result) - returndata = json.dumps({"msg" : message, "fromdid" : fromDid, 'targetdid' : targetDid}) + msgTS = time.strftime("%Y-%m-%dT%H:%m:%S+00:00") + appdb.logsms_db(msg_id, msgTS, 'outbound', uglyphone, fromDid, + 0.0040, 'pending', message, result) + returndata = json.dumps({"msg": message, + "fromdid": fromDid, + "targetdid": targetDid}) return returndata + @app.route('/testAjax') def testAjax(): - return json.dumps({"msg" : 'Success!'}) + return json.dumps({"msg": 'Success!'}) + @app.route('/inbox') def inbox(): @@ -150,21 +226,49 @@ def inbox(): loggedin = True else: loggedin = False - loginId = flask.session['loginid'] - results = appdb.getSMSbyAccount(loginId,10) - pprint.pprint(results) return flask.render_template('inbox.html', loggedin=loggedin) + +@app.route('/getInbox') +def returnInbox(): + if not app_auth.is_logged_in(): + return json.dumps({'error': + 'Unable to send SMS, you are not logged in'}) + + # userid = flask.session['account_id'] + loginId = flask.session['loginid'] + results = appdb.getSMSbyAccount(loginId, 20) + # pprint.pprint(results) + jsonresult = '' + i = 0 + for x in results: + if i >= 1: + jsonresult += ',' + json.dumps({"msg": x[9], + "fromdid": x[6], + "targetdid": x[7]}) + else: + jsonresult = json.dumps({"msg": x[9], + "fromdid": x[6], + "targetdid": x[7]}) + i += 1 + return jsonresult + + @app.route('/launch') def launchPage(): + if app_debug == '1': + pprint.pprint(flask.session) if app_auth.is_logged_in(): loggedin = True else: loggedin = False + if app_debug == '1': pprint.pprint(loggedin) pprint.pprint("loggedin") - return flask.render_template('launch.html',loggedin=loggedin) + + return flask.render_template('launch.html', loggedin=loggedin) + @app.route('/pp') def PrivacyPolicy(): @@ -174,7 +278,8 @@ def PrivacyPolicy(): loggedin = True else: loggedin = False - return flask.render_template('pp.html',loggedin=loggedin) + return flask.render_template('pp.html', loggedin=loggedin) + @app.route('/tos') def tos(): @@ -182,7 +287,8 @@ def tos(): loggedin = True else: loggedin = False - return flask.render_template('tos.html',loggedin=loggedin) + return flask.render_template('tos.html', loggedin=loggedin) + @app.route('/about') def about(): @@ -190,7 +296,8 @@ def about(): loggedin = True else: loggedin = False - return flask.render_template('about.html',loggedin=loggedin) + return flask.render_template('about.html', loggedin=loggedin) + if __name__ == '__main__': app.run( diff --git a/templates/inbox.html b/templates/inbox.html index 6f41a0c..b76328a 100644 --- a/templates/inbox.html +++ b/templates/inbox.html @@ -1,12 +1,83 @@ {% include 'include/header.html' %} -Login Methods +Inbox {% include 'include/navblock.html' %}

UNDER CONSTRUCTION

+
+
+ | + | + +
+
+ +
+ {% for n in results %} +
+
+ {{n[2]}} Status: {{n[5]}} {{n[0]}} +
+ {{n[6]}} to {{n[7]}} + {% if n[11] == 1 %} + Read + {% else %} + Unread + {% endif %} +
{{n[9]}}
+
+ {% endfor %}
{% include 'include/footer.html' %}