def get_id_label_list(self): """ Liefert eine Id List anhand des Tabellennamens Args: sql_where: Optional - Ein SQL-Where Statement zum filtern der Liste Returns: list: Die Id Liste """ connection = self.get_connection() cursor = connection.cursor(prepared=True) id_label_list = [(0, 'Nichts ausgewählt')] try: table = self.table_name sql = """SELECT id,label FROM {0}""".format(table) if self.put_into_trash: sql += " WHERE ctrl_deleted = 0 " cursor.execute(sql) rows = cursor.fetchall() for row in rows: id_label_list.append(row) except Exception as error: my_logger.log(10, error) finally: self.close_connection(cursor) return id_label_list
def id_list(self, sql_where): """ Liefert eine Id List anhand des Tabellennamens Args: sql_where: Optional - Ein SQL-Where Statement zum filtern der Liste Returns: list: Die Id Liste """ connection = self.get_connection() cursor = connection.cursor(prepared=True) self.list = list() try: table = self.table_name if len(sql_where) > 0: sql = """SELECT id FROM {0} WHERE %s""".format(table) if self.put_into_trash: sql += " AND ctrl_deleted = 0 " cursor.execute(sql, [sql_where]) else: sql = """SELECT id FROM {0} """.format(table) if self.put_into_trash: sql += " WHERE ctrl_deleted = 0 " cursor.execute(sql) rows = cursor.fetchall() for row in rows: if row[0]: self.list.append(row[0]) except Exception as error: my_logger.log(10, error) finally: self.close_connection(cursor) return self.list
def create_instance_by(self, key="username"): """ Args: key (string): Returns: self|bool """ connection = self.get_connection() cursor = connection.cursor(prepared=True) rows = None try: value = self.get(key) table = self.table_name sql = """SELECT id FROM {0} WHERE {1} = %s""".format(table, key) cursor.execute(sql, [value]) rows = cursor.fetchone() except Exception as error: my_logger.log(10, error) finally: self.close_connection(cursor) if rows is not None: id = rows[0] if id > 0: self.set("id", id) self.load() return True return False
def get_child_pages(self, id=0): """ Liefert die Unterseiten für eine Top-Level Seite Returns: list: Die IDs der Unterseiten """ connection = self.get_connection() cursor = connection.cursor(prepared=True) table = self.table_name result = list() if id > 0: sql = """SELECT id FROM {0} WHERE parent_id = %s AND ctrl_deleted = 0""".format( table) try: cursor.execute(sql, [id]) for row in cursor: result.append(row) except Exception as error: my_logger.log(10, error) finally: self.close_connection(cursor) return result
def is_sub_page(self, id=0): """ Args: id (): Returns: """ if id > 0: connection = self.get_connection() cursor = connection.cursor(prepared=True) table = self.table_name if id > 0: sql = """SELECT id FROM {0} WHERE parent_id = %s AND ctrl_deleted = 0""".format( table) try: cursor.execute(sql, [id]) rows = cursor.fetchall() if len(rows) > 0: return True except Exception as error: my_logger.log(10, error) finally: self.close_connection(cursor) return False
def get_start_page(self): """ Liefert die Startseite Returns: """ connection = self.get_connection() cursor = connection.cursor(prepared=True) page = None try: table = self.table_name sql = """SELECT id FROM {0} WHERE parent_id = 0 AND ctrl_deleted = 0 AND ctrl_start = 1""".format( table) cursor.execute(sql) rows = cursor.fetchall() for row in rows: page = Page() page.set_id(row[0]) page.load() except Exception as error: my_logger.log(10, error) finally: self.close_connection(cursor) return page
def decrypt(data): """ Entschlüsselt den übergebenen String mit dem symmetrischen Schlüssel Args: data: Der String der entschlüsselt werden soll Returns: Den entschlüsselten String insofern die Entschlüsselung erfolgreich war Ansonsten wird der übergebene String zurück gegeben """ if data == "" or data is None: return "" try: box = nacl.secret.SecretBox(Encryption.get_sym_key()) data_decrypted = box.decrypt(bytes(data, encoding="utf-8"), nonce=None, encoder=encoding.Base64Encoder) return data_decrypted.decode('utf-8') except Exception as error: my_logger.log(10, error) return data
def is_ip_address(self, value): try: ipaddress.ip_address(value) return True except Exception as error: my_logger.log(10, error) finally: return False
def delete(self): """ Löscht ein Datenbankobjekt Wenn self.put_into_trash auf True gesetzt wird, wird das Objekt im Papierkorb abgelegt. Andernfalls wird das Objekt direkt gelöscht. Returns: bool: True wenn das Objekt direkt aus der Datenbank gelöscht wurde andernfalls False """ connection = self.get_connection() cursor = connection.cursor(prepared=True) success = False table = self.table_name id = self.get_id() if id > 0: try: if self.put_into_trash: sql = """UPDATE {0} SET ctrl_deleted = 1 WHERE id = %s;""".format( table) trash = Trash() trash.set("item_id", id) trash.set("item_table", table) trash.set("user_id", current_user.get_id()) if trash.save(): flash( """{0} mit der ID {1} erfolgreich in den Papierkorb verschoben""" .format(self.class_label, id), "success") else: flash( """{0} mit der ID {1} konnte nicht in den Papierkorb verschoben werden""" .format(self.class_label, id), "danger") else: sql = """DELETE FROM {0} WHERE id = %s;""".format(table) cursor.execute(sql, [id]) connection.commit() row = cursor.rowcount if self.table_name != "session": if row > 0 and not self.put_into_trash: flash( """{0} mit der ID {1} erfolgreich gelöscht""". format(self.class_label, id), "success") elif row <= 0 and not self.put_into_trash: flash( """{0} mit der ID {1} konnte nicht gelöscht werden""" .format(self.class_label, id), "danger") if row > 0: success = True except Exception as error: my_logger.log(10, error) finally: self.close_connection(cursor) return success
def send_message(self): try: mail = Mail() mail.connect() message = Message(self.get_subject(), recipients=[self.get_receiver()]) message.html = self.get_message() mail.send(message) self.save() except Exception as error: my_logger.log(10, error) return False
def username_exists(self, name): connection = self.get_connection() cursor = connection.cursor(prepared=True) rows = None try: table = self.table_name sql = """SELECT id FROM {0} WHERE username = %s""".format(table) cursor.execute(sql, [name]) rows = cursor.fetchone() except Exception as error: my_logger.log(10, error) finally: self.close_connection(cursor) if rows is not None: return rows[0] return 0
def insert(self): """ Generische Insert Funktion Aus arrData werden die Key/Value Paare extrahiert und in einen String, durch Komma getrennt, gespeichert Die Platzhalter für das Prepared Statement werden anhand der Länge von arrData erstellt Das Tuple mit den Values wird beim ausführen an das Statement gebunden Returns: bool: False wenn das Objekt nicht eingetragen werden konnte int: Die Id des Objekts wenn es erfolgreich eingetragen wurde """ connection = self.get_connection() cursor = connection.cursor(prepared=True) success = False try: table = self.table_name data = self.encrypt_data() columns = ','.join(data.keys()) placeholders = ','.join(['%s'] * len(data)) values = list(data.values()) sql = """INSERT INTO {0} ({1}) VALUES ({2});""".format( table, columns, placeholders) cursor.execute(sql, values) row = cursor.lastrowid connection.commit() if row > 0: self.set_id(row) success = row if row > 0 and self.item_editable: flash( "{0} mit der ID {1} wurde erfolgreich erstellt".format( self.class_label, self.get_id()), "success") elif row <= 0 and self.item_editable: flash( "{0} mit der ID {1} konnte nicht erstellt werden".format( self.class_label, self.get_id()), "success") except Exception as error: my_logger.log(10, error) finally: self.close_connection(cursor) return success
def login(): """ Login Endpunkt Returns: Rendert das Login Template oder leitet an das Dashboard weiter nach erfolgreichem Login """ form = LoginForm() if request.method == "POST": if form.validate_on_submit(): be_user = BeUser() be_user.set("username", escape(request.form["username"])) be_user.temp_password = escape(request.form["password"]) if be_user.validate_login(): be_user.load() session = Session() session.set_user_id(be_user.get_id()) if session.session_exists(): session.delete() session = Session() session.set_user_id(be_user.get_id()) ip_address = escape(request.remote_addr) user_agent = escape(request.user_agent) token = session.encryption.create_random_token(32) session.set_ip_address(ip_address) session.set_user_agent(user_agent) session.set_token(token) session.set_timestamp(be_user.get_ctrl_last_login()) if session.save() is not False: session_user = be_user.create_session_user() if login_user(session_user): my_logger.log( 10, "User mit der ID {0} eingeloggt".format( session_user.get_id())) return redirect(url_for("backend.dashboard")) else: failed_login_record = FailedLoginRecord() failed_login_record.set_user_id(be_user.get_id()) failed_login_record.set_username(be_user.get_username()) failed_login_record.set_ip_address(request.remote_addr) failed_login_record.set_user_agent(str(request.user_agent)) failed_login_record.save() return render_template("login.html", form=form)
def delete_final(self): connection = self.get_connection() cursor = connection.cursor(prepared=True) row = 0 try: item_id = self.get_item_id() item_table = self.get_item_table() sql = """DELETE FROM {0} WHERE id = %s""".format(item_table) cursor.execute(sql, item_id) connection.commit() row = cursor.lastrowid except Exception as error: my_logger.log(10, error) finally: self.close_connection(cursor) if row > 0: return True return False
def load(self): """ Generische Funktion zum Laden eines Datenbank-Objekts Die SQL Query wird anhand der gesetzten Werte in arrData automatisch angepasst. Returns: bool: True wenn das Objekt erfolgreich geladen wurde andernfalls False """ connection = self.get_connection() cursor = connection.cursor(prepared=True) table = self.table_name id = 0 sql = "" if self.get_id() > 0: id = self.get_id() sql = """SELECT * FROM {0} WHERE id = %s""".format(table) elif self.get_user_id() > 0: id = self.get_user_id() sql = """SELECT * FROM {0} WHERE user_id = %s""".format(table) try: if id > 0: cursor.execute(sql, [id]) result = dict() columns = tuple([str(d[0]) for d in cursor.description]) for row in cursor: result = dict(zip(columns, row)) self.arrData = result for key in self.arrData: try: if isinstance(self.get(key), bytearray): self.set(key, self.get(key).decode('utf-8')) except Exception as error: my_logger.log(10, error) self.decrypt_data() return True except Exception as error: my_logger.log(10, error) finally: self.close_connection(cursor) return False
def validate_hash(hash_string, string): """ Validiert einen String und Hash Args: hash_string: Der Hash gegen den die Validierung durchgeführt wird string: Das übergebene Klartext Passwort Returns: bool: True wenn das Passwort mit dem Hash übereinstimmt andernfalls False """ try: if nacl.pwhash.verify(bytes(hash_string, encoding="utf8"), bytes(string, encoding="utf8")): return True except Exception as error: my_logger.log(10, error) return False
def get_columns(self): table = self.table_name connection = self.get_connection() cursor = connection.cursor(prepared=True) columns = list() try: sql = "SHOW COLUMNS FROM {0}".format(table) cursor.execute(sql) rows = cursor.fetchall() for d in rows: column = d[0] try: column.decode("utf-8") except Exception as error: my_logger.log(10, error) columns.append(column) except Exception as error: my_logger.log(10, error) finally: self.close_connection(cursor) return columns
def encrypt(data): """ Verschlüsselt den übergebenen String mit dem symmetrischen Schlüssel Args: data: Der String der verschlüsselt werden soll Returns: str: Der verschlüsselte String oder der übergebene String wenn die Verschlüsselung fehlgeschlagen ist """ if data == "" or data is None: return "" try: box = nacl.secret.SecretBox(Encryption.get_sym_key()) data_encrypted = box.encrypt(bytes(data, encoding="utf-8"), nonce=None, encoder=encoding.Base64Encoder) return data_encrypted.decode('utf-8') except Exception as error: my_logger.log(10, error) return data
def get_top_level_pages(self): """ Liefert die Top-Level Seiten Returns: list: Die Id Liste """ connection = self.get_connection() cursor = connection.cursor(prepared=True) id_label_list = [] try: table = self.table_name sql = """SELECT id FROM {0} WHERE parent_id = 0 AND ctrl_deleted = 0""".format( table) cursor.execute(sql) rows = cursor.fetchall() for row in rows: id_label_list.append(row) except Exception as error: my_logger.log(10, error) finally: self.close_connection(cursor) return id_label_list
def is_valid(self, user_hash): datetime_now = datetime.datetime.now() session_time = self.get_timestamp() difference_minute = 9999999 if isinstance(session_time, datetime.datetime): difference = datetime_now.timestamp() - session_time.timestamp() difference_minute = difference / 60 if difference_minute <= 30: my_logger.log( 10, """Session mit der User ID {0} ist noch nicht abgelaufen""". format(self.get_user_id())) hash_session = self.encryption.get_generic_hash( self.get_session_hash_string()) if sodium_memcmp(hash_session, user_hash): my_logger.log( 10, """Session mit der User ID {0} ist valid""".format( self.get_user_id())) return True my_logger.log( 10, """Session abgelaufen. User mit der ID {0} muss ausgeloggt werden.""" .format(self.get_user_id())) return False
def update(self): """ Generische Update Funktion Aus arrData werden die Key/Value Paare extrahiert und in einen String, durch Komma getrennt, gespeichert Die Platzhalter für das Prepared Statement werden anhand der Länge von arrData erstellt Das Tuple mit den Values wird beim ausführen an das Statement gebunden Returns: bool: True wenn das Update erfolgreich ausgeführt wurde andernfalls False """ connection = self.get_connection() cursor = connection.cursor(prepared=True) success = False try: table = self.table_name id = self.get("id") data = self.encrypt_data() for key in data: try: if isinstance(data[key], bytearray): data[key] = data[key].decode('utf-8') except Exception as error: my_logger.log(10, error) update_string = "" columns = data.keys() max_keys = len(data.keys()) i = 1 for column in columns: update_string += column update_string += " = " update_string += " %s" if i < max_keys: update_string += ", " i += 1 data["last_id"] = id values = list(data.values()) sql = """UPDATE {0} SET {1} WHERE id = %s """.format( table, update_string) cursor.execute(sql, values) rowcount = cursor.rowcount connection.commit() if rowcount > 0: success = True if rowcount > 0 and self.item_editable: flash( "{0} mit der ID {1} wurde erfolgreich aktualisiert {2}". format(self.class_label, self.get_id(), self.table_name), "success") elif rowcount <= 0 and self.item_editable: flash( "{0} mit der ID {1} konnte nicht aktualisiert werden {2}". format(self.class_label, self.get_id(), self.table_name), "success") except Exception as error: my_logger.log(10, error) success = False finally: self.close_connection(cursor) return success