From 2202af78264d8f47027242db8937533f8ee89d08 Mon Sep 17 00:00:00 2001 From: Darksider3 Date: Wed, 16 Oct 2019 12:33:07 +0200 Subject: [PATCH] Introduce imports, which comes with a new flag(--Import) --Import depends on --file being present pointing to a valid CSV-file that contains unique users with id's. When a user already exists with his id, the script will fail. It is also Backup.py-only which is reflected in the help message --- private/Backup.py | 95 ++++++++++++++++++++++++++++++++++++++++------ private/lib/CFG.py | 5 +++ 2 files changed, 89 insertions(+), 11 deletions(-) diff --git a/private/Backup.py b/private/Backup.py index 9a33128..6710fbb 100644 --- a/private/Backup.py +++ b/private/Backup.py @@ -4,23 +4,96 @@ import ListUsers import csv import io import lib.CFG as CFG +import os + + +class Backup: + filename: str + quoting: int + dialect: str + field_names: tuple + + def __init__(self, fname: str = CFG.args.file, quoting: int = csv.QUOTE_NONNUMERIC, dialect: str = "excel"): + self.setFilename(fname) + self.setQuoting(quoting) + self.setDialect(dialect) + self.setFieldnames(tuple(['id', 'username', 'email', 'name', 'pubkey', 'timestamp', 'status'])) + + def setDialect(self, dialect: str): + self.dialect = dialect + + def setQuoting(self, quoting: int): + self.quoting = quoting + + def setFilename(self, filename: str): + self.filename = filename + + def setFieldnames(self, f_names: tuple): + self.field_names = f_names + + def BackupToFile(self, fetched: list): + returner = io.StringIO() + write_csv = csv.DictWriter(returner, fieldnames=self.field_names, quoting=self.quoting, dialect=self.dialect) + write_csv.writeheader() + write_csv.writerows(fetched) + + if self.filename == "stdout": + print(returner.getvalue()) + else: + with open(self.filename, "w") as f: + print(returner.getvalue(), file=f) + return True + + @staticmethod + def ImportFromFile(fname: str = CFG.args.file, db: str = CFG.REG_FILE, userids: tuple = tuple([])): + if not os.path.isfile(fname): + return None # @TODO maybe some better output here + if not os.path.isfile(db): + return None # @TODO maybe some better output here + if userids: + pass # empty tuple means everything + try: + with open(fname, 'r', newline='') as f: + import lib.sqlitedb as sql + import lib.System + sysctl = lib.System.System() + sql = lib.sqlitedb.SQLitedb(CFG.REG_FILE) + reader = csv.DictReader(f) # @TODO csv.Sniffer to compare? When yes, give force-accept option + for row in reader: + sql.safequery("INSERT INTO `applications` (id, username, name, timestamp, email, pubkey, status) " + "VALUES (?,?,?,?,?,?,?)", + tuple([row["id"], row["username"], row["name"], row["timestamp"], + row["email"], row["pubkey"], row["status"]])) # @TODO: without IDs + if row["status"] == "1": + sysctl.register(row["username"]) + sysctl.lock_user_pw(row["username"]) + sysctl.add_to_usergroup(row["username"]) + sysctl.make_ssh_usable(row["username"], row["pubkey"]) + print(row['id'], row['username'], row['email'], row['name'], row['pubkey'], row['timestamp'], + row['status'] + "====> Registered.") + elif row["status"] == "0": + print(row['id'], row['username'], row['email'], row['name'], row['pubkey'], row['timestamp'], + row['status'] + "not approved, therefore not registered.") + else: + print(f"Uhm, ok. Type is {type(row['status'])}, and value is {row['status']}") + pass # @TODO: Import with sqlitedb and system. Will be fun Kappa + except OSError as E: + print(f"UUFFF, something went WRONG with the file {fname}: {E}") + if __name__ == "__main__": try: L = ListUsers.ListUsers() fetch = L.getFetch() - ret = io.StringIO() - writer = csv.writer(ret, quoting=csv.QUOTE_NONNUMERIC) # @TODO: Should be a specific dialect instead? - writer.writerow(['id', 'username', 'email', 'name', 'pubkey' 'timestamp', 'status']) - for user in fetch: - writer.writerow([user['id'], user['username'], user['email'], user['name'], user['pubkey'], - user['timestamp'], user['status']]) - - if CFG.args.file == "stdout": - print(ret.getvalue()) + B = Backup() + if CFG.args.Import: + if not CFG.args.file: + print("You MUST set a CSV-file with the -f/--file flag that already exist") + exit(1) + if not B.ImportFromFile(CFG.args.file): + print("Backup didn't work because the file doesnt exist") else: - with open(CFG.args.file, "w") as f: - print(ret.getvalue(), file=f) + B.BackupToFile(fetch) exit(0) except KeyboardInterrupt as e: pass diff --git a/private/lib/CFG.py b/private/lib/CFG.py index 13e2ec5..5e2123b 100644 --- a/private/lib/CFG.py +++ b/private/lib/CFG.py @@ -20,6 +20,11 @@ argparser.add_argument('-a', '--approved', default=False, action="store_true", help="Only approved Users.", required=False) argparser.add_argument('-f', '--file', default="stdout", type=str, help='write to file instead of stdout', required=False) +argparser.add_argument('--Import', default=False, action="store_true", + help="Import Users from file. Affects currently only Backup.py.\n" + "Setting this to true will result in -f being interpreted as the input file to import " + "users from. The file MUST be a comma separated CSV file being readable having it's " + "defined columns written in the first line.") args = argparser.parse_args() CONF_FILE = args.config