#################### # # file is replaced by FlowerServices.py # 1= # intentional python syntax error # ##################### from Crypto.Cipher import AES from Crypto.Hash import MD5 import base64 from Log import Log from Config import * import pymysql as mdb #encryption stuff SECRET='HSPh1O5vc6YY2Xt8jUxlTp' BLOCK_SIZE = 32 PADDING='_' # one-liner to sufficiently pad the text to be encrypted pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING def md5(message): hash = MD5.new() hash.update(message.encode('utf-8')) return hash.hexdigest() class Flower(): def __init__(self, user, pwd): self.db = 'Flowers' self.db_username = user + '_' self.db_password = md5(pwd) self.customer_table = self.db_username self.cipher = AES.new(pad(SECRET + pwd)) def encode(self, s): return str(base64.b64encode(self.cipher.encrypt(pad(s))).decode("utf-8")) def decode(self, e): return str(self.cipher.decrypt(base64.b64decode(e)).decode("utf-8")).rstrip(PADDING) def add(self, organization, myname, myid, secret, deleted=0, timestamp=None): ''' POST a new flower ''' if len(organization)>MINFIELDLEN and len(myid)>MINFIELDLEN and len(secret)>MINFIELDLEN: sql = "INSERT INTO {} (organization ,myID ,myName ,mySecret, deleted) VALUES ('{}', '{}', '{}', '{}', {})".format(self.customer_table, organization, self.encode(myid), self.encode(myname), self.encode(secret), deleted) if timestamp is not None: sql = "INSERT INTO {} (organization ,myID ,myName ,mySecret, deleted, dateCreated) VALUES ('{}', '{}', '{}', '{}', {}, '{}')".format(self.customer_table, organization, self.encode(myid), self.encode(myname), self.encode(secret), deleted, timestamp) result, data = self.do_db_commit(sql) Log.debug(result) if result==1: return {'organization': organization, 'dateCreated': 'STORED', 'myID': myid, 'myName': myname,'mySecret': secret} return {'organization': organization, 'dateCreated': 'FAILED', 'myID': myid, 'myName': myname,'mySecret': secret} def all(self, isdeleted=0): ''' GET flowers list ''' #sql = "SELECT organization, myID, myName, dateCreated FROM %s " % (self.customer_table) sql = """ select uniqueflowers.organization, uniqueflowers.myID, uniqueflowers.dateCreated from {0} as uniqueflowers inner join ( select organization, max(dateCreated) as lastCreated from {0} group by organization order by dateCreated DESC) allflowers on allflowers.organization=uniqueflowers.organization and lastCreated=uniqueflowers.dateCreated where uniqueflowers.deleted={1} """.format(self.customer_table, isdeleted) result, data = self.do_db_allrows(sql) #Log.debug(sql_result) all_flowers=[] if result==1: for row in data: all_flowers.append({'organization': str(row[0]), 'myID': self.decode(row[1]), 'dateCreated': str(row[2])}) return all_flowers def one(self, organization, datetimestamp ): ''' flower for user, org and datetime ''' result = -1 secret = ':-(' sql = "SELECT mySecret, myID, myName FROM %s where organization='%s' and dateCreated='%s' order by dateCreated DESC limit 1" % (self.customer_table, organization, datetimestamp) result, data = self.do_db_1row(sql) if result == 1: return {'organization': organization, 'dateCreated': datetimestamp, 'myID': self.decode(data[1]), 'myName': self.decode(data[2]),'mySecret': self.decode(data[0])} return {'organization': organization, 'dateCreated': datetimestamp, 'myID': '', 'myName': '','mySecret': '-- Not found --'} def deactivate(self, organization, datetimestamp ): ''' flower for user, org and datetime ''' result = -1 secret = ':-(' sql = "update {} set deleted=1 where organization='{}' and dateCreated='{}' ".format(self.customer_table, organization, datetimestamp) result, data = self.do_db_commit(sql) if result == 1: secret = '- DELETED -' return {'organization': organization, 'dateCreated': datetimestamp, 'myID': '', 'myName': '','mySecret': secret} def empty(self): ''' empty flower ''' return {'organization': '', 'dateCreated': '', 'myID': '', 'myName': '','mySecret': ''} def numberOfEntries(self): ''' GET login info, check if its valid ''' sql = "SELECT count(*) FROM {};".format(self.customer_table) result, data = self.do_db_1row(sql) if result == 1: return(data[0]) return -1 def update_pwd(self, new_pwd): newcipher = AES.new(pad(SECRET + new_pwd)) def new_encode(s): return str(base64.b64encode(newcipher.encrypt(pad(s))).decode("utf-8")) end_result = "ERROR updating hushes\n" sql = """ select myID, myName, mySecret, organization, dateCreated from {0}""".format(self.customer_table) result, data = self.do_db_allrows(sql) # Log.debug(sql_result) if result == 1: # convert all hushes sql = "" for row in data: sql += "update {} set myID='{}', myName='{}', mySecret='{}' where organization='{}' and dateCreated='{}';\n".\ format(self.customer_table, new_encode(self.decode(row[0])), new_encode(self.decode(row[1])), new_encode(self.decode(row[2])),row[3], row[4]) result, data = self.do_db_commit(sql) if result == 1: end_result = "ERROR updating user-password\n" # update the password of the user sql = "SET PASSWORD FOR '{}'@'localhost' = PASSWORD('{}'); ".format(self.db_username, md5(new_pwd)) result, data = self.do_db_commit(sql) if result == 1: end_result = "SUCCESSFULLY updated, now login again\n" return end_result def do_db_commit(self, sql): Log.debug('INSc: '+sql) result = 0 data = '' con = None try: con = mdb.connect(host='localhost', passwd=self.db_password, user=self.db_username, db=self.db); cur = con.cursor() if ";\n" in sql: for s in sql.split(";\n"): if len(s)>1: cur.execute(s) else: cur.execute(sql) cur.close() con.commit() result = 1 except mdb.Error as e: m = "Error %d: %s" % (e.args[0],e.args[1]) data = {'message': m} Log.debug(m) result = -1 finally: if con: con.close() return result, data def do_db_1row(self, sql): Log.debug('1row sql: '+sql) result = 0 con = None try: con = mdb.connect(host='localhost', passwd=self.db_password, user=self.db_username, db=self.db); cur = con.cursor() cur.execute(sql) data = cur.fetchone() if data: result = 1 except mdb.Error as e: m = "Error %d: %s" % (e.args[0],e.args[1]) data = {'message': m} Log.debug(m) result = -1 finally: if con: con.close() return result, data def do_db_allrows(self, sql): Log.debug('all rows sql: '+sql) result = 0 con = None try: con = mdb.connect(host='localhost', passwd=self.db_password, user=self.db_username, db=self.db); cur = con.cursor() cur.execute(sql) data = cur.fetchall() if data: result = 1 except mdb.Error as e: m = "Error %d: %s" % (e.args[0],e.args[1]) data = {'message': m} Log.debug(m) result = -1 finally: if con: con.close() return result, data class SuperFlower(Flower): def __init__(self, customer, pwd): super().__init__(customer, pwd) self.customer_name = customer + '_' self.customer_pwd = pwd self.db_username = 'flower' self.db_password = md5('flower') def createNewTable(self): # create new table and user sql = """ CREATE TABLE `{}` ( `organization` varchar(80) NOT NULL, `myID` varchar(129) NOT NULL, `myName` varchar(129) NOT NULL, `mySecret` varchar(65) NOT NULL, `dateCreated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `deleted` int(11) DEFAULT '0', PRIMARY KEY (`organization`,`dateCreated`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;""".format(self.customer_table) result, data = self.do_db_1row(sql) if result < 0: Log.info("SQL ERROR:") Log.info(data) return 0 sql = """create user {}@localhost identified by '{}';""".format(self.customer_name, md5(self.customer_pwd)) result, data = self.do_db_1row(sql) if result < 0: Log.info("SQL ERROR:") Log.info(data) return 0 sql = """grant select,update,insert on Flowers.{} to {}@localhost;""".format(self.customer_table, self.customer_name) result, data = self.do_db_1row(sql) if result < 0: Log.info("SQL ERROR:") Log.info(data) return 0 self.flush_privs() return 1 def flush_privs(self): sql = """flush privileges;""" result, data = self.do_db_1row(sql) if result < 0: Log.info("SQL ERROR:") Log.info(data) return 0 return 1 def migrate(self, old_customer_name): OLDSECRET = 'HSPh1O5vc6YY2Xt8jUxlTpd*DZsjMMAH' OLDCIPHER = AES.new(OLDSECRET) old_DecodeAES = lambda e: str(OLDCIPHER.decrypt(base64.b64decode(e)).decode("utf-8")).rstrip(PADDING) def sql_datetime(datetime_type): return datetime_type.strftime("%Y-%m-%d %H:%M:%S") end_result = "ERROR creting new table\n" if self.createNewTable(): end_result = "ERROR updating hushes\n" sql = """ select myID, myName, mySecret, organization, dateCreated, deleted from {0}""".format(old_customer_name) # 0 1 2 3 4 5 result, data = self.do_db_allrows(sql) # Log.debug(sql_result) if result == 1: # convert all hushes sql = "" for row in data: #sql += "insert {} set organization='{}', myID='{}', myName='{}', mySecret='{}', deleted={}, dateCreated='{}' where organization='{}' and dateCreated='{}';\n". \ sql += "INSERT INTO {} (organization ,myID ,myName ,mySecret, deleted, dateCreated) VALUES ('{}', '{}', '{}', '{}', {}, '{}') ;\n".\ format(self.customer_table, row[3], self.encode(row[0]), self.encode(row[1]), self.encode(old_DecodeAES(row[2])), row[5], sql_datetime(row[4])) result, data = self.do_db_commit(sql) if result == 1: end_result = "SUCCESSFULLY updated, now login again\n" return end_result if __name__ == '__main__': print("this is a library, sorry dude")