General overhaul, better messages, ordered imports etc

feature-admin-split
Darksider3 5 years ago
parent 32c6ea7e07
commit 8008fa36b9

@ -1,9 +1,10 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import ListUsers import configparser
import csv import csv
import io import io
import configparser
import ListUsers
import lib.uis.default as default_cmd # Follows -u, -a, -f flags import lib.uis.default as default_cmd # Follows -u, -a, -f flags
@ -115,17 +116,14 @@ if __name__ == "__main__":
args = default_cmd.argparser.parse_args() args = default_cmd.argparser.parse_args()
config = configparser.ConfigParser() config = configparser.ConfigParser()
config.read(args.config) config.read(args.config)
try: L = ListUsers.ListUsers(config['DEFAULT']['applications_db'],
L = ListUsers.ListUsers(config['DEFAULT']['applications_db'], unapproved=args.unapproved, approved=args.approved)
unapproved=args.unapproved, approved=args.approved) fetch = L.get_fetch()
fetch = L.get_fetch() if fetch:
if fetch: B = Backup(args.file)
B = Backup(args.file) B.setFieldnames(fetch[0].keys()) # sqlite3.row delivers its keys for us! SO NICE!
B.setFieldnames(fetch[0].keys()) # sqlite3.row delivers its keys for us! SO NICE! B.backup_to_file(fetch)
B.backup_to_file(fetch) else:
else: print("nothing to backup!")
print("nothing to backup!") exit(1)
exit(1) exit(0)
exit(0)
except KeyboardInterrupt as e:
pass

@ -1,8 +1,9 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import configparser
import csv import csv
import os import os
import configparser
import lib.UserExceptions import lib.UserExceptions
import lib.uis.config_ui # dont go to default, just following -c flag import lib.uis.config_ui # dont go to default, just following -c flag
@ -74,15 +75,13 @@ if __name__ == "__main__":
args = ArgParser.parse_args() args = ArgParser.parse_args()
config = configparser.ConfigParser() config = configparser.ConfigParser()
config.read(args.config) config.read(args.config)
try:
if not args.Import: if not args.Import:
print("Error, need the import flag") print("Error, need the import flag")
if not args.file:
print("Error, need the import file")
if not args.file: if not args.file:
print("Error, need the import file") print("You MUST set a CSV-file with the -f/--file flag that already exist")
if not args.file: exit(1)
print("You MUST set a CSV-file with the -f/--file flag that already exist") import_from_file(args.file, config['DEFAULT']['applications_db'])
exit(1) exit(0)
import_from_file(args.file, config['DEFAULT']['applications_db'])
exit(0)
except KeyboardInterrupt as e:
pass

@ -1,11 +1,11 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from lib.sqlitedb import SQLiteDB
import lib.uis.default as default_cmd # Follows -u, -a, -f flags
from typing import List # Typing support!
import sqlite3 # sqlite3.Row-Object
import configparser import configparser
import sqlite3 # sqlite3.Row-Object
from typing import List # Typing support!
import lib.uis.default as default_cmd # Follows -u, -a, -f flags
from lib.sqlitedb import SQLiteDB
class ListUsers: class ListUsers:
@ -46,7 +46,7 @@ class ListUsers:
query = "SELECT `username` FROM `applications` WHERE `status` = '1' ORDER BY timestamp ASC" query = "SELECT `username` FROM `applications` WHERE `status` = '1' ORDER BY timestamp ASC"
self.usersFetch = self.db.query(query) self.usersFetch = self.db.query(query)
for users in self.usersFetch: for users in self.usersFetch:
list_str += users["username"]+"\n" list_str += users["username"] + "\n"
return list_str return list_str
def prettyPrint(self) -> None: def prettyPrint(self) -> None:
@ -94,30 +94,27 @@ if __name__ == "__main__":
config = configparser.ConfigParser() config = configparser.ConfigParser()
config.read(args.config) config.read(args.config)
try: ret = ""
ret = "" if args.user is not None:
if args.user is not None: L = ListUsers(config['DEFAULT']['applications_db'], unapproved=args.unapproved, approved=args.approved,
L = ListUsers(config['DEFAULT']['applications_db'], unapproved=args.unapproved, approved=args.approved, single_user=args.user)
single_user=args.user) else:
else: L = ListUsers(config['DEFAULT']['applications_db'], unapproved=args.unapproved, approved=args.approved)
L = ListUsers(config['DEFAULT']['applications_db'], unapproved=args.unapproved, approved=args.approved) if args.args_asc:
if args.args_asc: ret = L.output_as_list()
ret = L.output_as_list() else:
else: fetch = L.get_fetch()
fetch = L.get_fetch() ret += "ID %-1s| Username %-5s| Mail %-20s| Name %-17s| Registered %-8s | State |\n" % (
ret += "ID %-1s| Username %-5s| Mail %-20s| Name %-17s| Registered %-8s | State |\n" % ( " ", " ", " ", " ", " "
" ", " ", " ", " ", " " )
ret += 102 * "-" + "\n"
for user in fetch:
ret += "%-4i| %-14s| %-25s| %-22s| %-8s | %-5i |\n" % (
user["id"], user["username"], user["email"], user["name"], user["timestamp"], user["status"]
) )
ret += 102 * "-" + "\n" if args.file != "stdout":
for user in fetch: with open(args.file, 'w') as f:
ret += "%-4i| %-14s| %-25s| %-22s| %-8s | %-5i |\n" % ( print(ret, file=f)
user["id"], user["username"], user["email"], user["name"], user["timestamp"], user["status"] else:
) print(ret)
if args.file != "stdout": exit(0)
with open(args.file, 'w') as f:
print(ret, file=f)
else:
print(ret)
exit(0)
except KeyboardInterrupt:
pass

@ -1,12 +1,13 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import configparser import configparser
import lib.uis.config_ui # only follow -c flag import sqlite3
import lib.Validator
import lib.sqlitedb
import lib.System import lib.System
import lib.UserExceptions import lib.UserExceptions
import sqlite3 import lib.Validator
import lib.sqlitedb
import lib.uis.config_ui # only follow -c flag
if __name__ == "__main__": if __name__ == "__main__":
lib.uis.config_ui.argparser.description += " - Edit Tilde Users" lib.uis.config_ui.argparser.description += " - Edit Tilde Users"
@ -35,115 +36,112 @@ if __name__ == "__main__":
args = ArgParser.parse_args() args = ArgParser.parse_args()
config = configparser.ConfigParser() config = configparser.ConfigParser()
config.read(args.config) config.read(args.config)
try: db = config['DEFAULT']['applications_db']
db = config['DEFAULT']['applications_db'] if not args.sshpubkey and not args.name and not args.username and not args.email and args.status is None \
if not args.sshpubkey and not args.name and not args.username and not args.email and args.status is None \ and not args.remove:
and not args.remove: print(f"Well, SOMETHING must be done with {args.user} ;-)")
print(f"Well, SOMETHING must be done with {args.user} ;-)") exit(1)
# --> --user
if not lib.Validator.checkUserInDB(args.user, db):
print(f"User {args.user} does not exist in the database.")
exit(1)
DB = lib.sqlitedb.SQLiteDB(db)
sys_ctl = lib.System.System(args.user)
if not DB:
print("Could not establish connection to database")
exit(1)
CurrentUser = DB.safequery("SELECT * FROM `applications` WHERE `username`=?", tuple([args.user]))[0]
# --> --remove
if args.remove:
print(f"Removing {args.user} from the system and the database...")
try:
DB.removeApplicantFromDBperUsername(args.user)
print(f"Purged from the DB")
if CurrentUser["status"] == 1:
sys_ctl.remove_user()
print(f"Purged from the system")
else:
print(f"'{args.user}' was not approved before, therefore not deleting from system itself.")
except lib.UserExceptions.General as e:
print(f"{e}")
exit(1)
print(f"Successfully removed '{args.user}'.")
exit(0)
# --> --sshpubkey
if args.sshpubkey:
if not lib.Validator.checkSSHKey(args.sshpubkey):
print(f"Pubkey '{args.sshpubkey}' isn't valid.")
exit(1) exit(1)
# --> --user try:
if not lib.Validator.checkUserInDB(args.user, db): DB.safequery("UPDATE `applications` SET `pubkey`=? WHERE `username`=?",
print(f"User {args.user} does not exist in the database.") tuple([args.sshpubkey, args.user]))
CurrentUser = DB.safequery("SELECT * FROM `applications` WHERE `username` = ? ", tuple([args.user]))[0]
if int(CurrentUser["status"]) == 1:
sys_ctl.make_ssh_usable(args.sshpubkey)
except sqlite3.Error as e:
print(f"Something unexpected happened! {e}")
exit(1) exit(1)
DB = lib.sqlitedb.SQLiteDB(db) except lib.UserExceptions.ModifyFilesystem as e:
sys_ctl = lib.System.System(args.user) print(f"One action failed during writing the ssh key back to the authorization file. {e}")
if not DB: print(f"'{args.user}'s SSH-Key updated successfully.")
print("Could not establish connection to database")
# --> --name
if args.name:
if not lib.Validator.checkName(args.name):
print(f"'{args.name}' is not a valid Name.")
exit(1) exit(1)
CurrentUser = DB.safequery("SELECT * FROM `applications` WHERE `username`=?", tuple([args.user]))[0] try:
DB.safequery("UPDATE `applications` SET `name` =? WHERE `username` =?", tuple([args.name, args.user]))
except sqlite3.Error as e:
print(f"Could not write '{args.name}' to database: {e}")
print(f"'{args.user}'s Name changed to '{args.name}'.")
# --> --remove # --> --email
if args.remove: if args.email:
print(f"Removing {args.user} from the system and the database...") if not lib.Validator.checkEmail(args.email):
try: print(f"'{args.email}' is not a valid Mail address!")
DB.removeApplicantFromDBperUsername(args.user) exit(1)
print(f"Purged from the DB") try:
if CurrentUser["status"] == 1: DB.safequery("UPDATE `applications` SET `email` =? WHERE `username` =?", tuple([args.email]))
sys_ctl.remove_user() except sqlite3.Error as e:
print(f"Purged from the system") print(f"Could not write '{args.email}' to the database. {e}")
else: print(f"'{args.user}' Mail changed to '{args.email}'.")
print(f"'{args.user}' was not approved before, therefore not deleting from system itself.")
except lib.UserExceptions.General as e: # --> --status
print(f"{e}") if args.status is not None:
exit(1) if args.status != 0 and args.status != 1:
print(f"Successfully removed '{args.user}'.") print("Only 0 and 1 are valid status, where 1 is activated and 0 is unapproved.")
exit(0) exit(0)
# --> --sshpubkey # just takes first result out of the dict
if args.sshpubkey: if args.status == int(CurrentUser["status"]):
if not lib.Validator.checkSSHKey(args.sshpubkey): print(f"New and old status are the same.")
print(f"Pubkey '{args.sshpubkey}' isn't valid.")
exit(1) if args.status == 0 and int(CurrentUser["status"]) == 1:
try: try:
DB.safequery("UPDATE `applications` SET `pubkey`=? WHERE `username`=?", DB.safequery("UPDATE `applications` SET `status` =? WHERE `id`=?",
tuple([args.sshpubkey, args.user])) tuple([args.status, CurrentUser["id"]]))
CurrentUser = DB.safequery("SELECT * FROM `applications` WHERE `username` = ? ", tuple([args.user]))[0] sys_ctl.remove_user()
if int(CurrentUser["status"]) == 1:
sys_ctl.make_ssh_usable(args.sshpubkey)
except sqlite3.Error as e: except sqlite3.Error as e:
print(f"Something unexpected happened! {e}") print(f"Could not update database entry for '{args.user}', did not touch the system")
exit(1) exit(1)
except lib.UserExceptions.ModifyFilesystem as e: except lib.UserExceptions.UnknownReturnCode as e:
print(f"One action failed during writing the ssh key back to the authorization file. {e}") print(f"Could not remove '{args.user}' from the system, unknown return code: {e}. DB is modified.")
print(f"'{args.user}'s SSH-Key updated successfully.")
# --> --name
if args.name:
if not lib.Validator.checkName(args.name):
print(f"'{args.name}' is not a valid Name.")
exit(1) exit(1)
try: print(f"Successfully changed '{args.user}'s status to 0 and cleared from the system.")
DB.safequery("UPDATE `applications` SET `name` =? WHERE `username` =?", tuple([args.name, args.user]))
except sqlite3.Error as e:
print(f"Could not write '{args.name}' to database: {e}")
print(f"'{args.user}'s Name changed to '{args.name}'.")
# --> --email if args.status == 1 and int(CurrentUser["status"]) == 0:
if args.email:
if not lib.Validator.checkEmail(args.email):
print(f"'{args.email}' is not a valid Mail address!")
exit(1)
try: try:
DB.safequery("UPDATE `applications` SET `email` =? WHERE `username` =?", tuple([args.email])) DB.safequery("UPDATE `applications` SET `status`=? WHERE `username`=?",
tuple([args.status, args.user]))
sys_ctl.aio_approve(CurrentUser["pubkey"])
except sqlite3.Error as e: except sqlite3.Error as e:
print(f"Could not write '{args.email}' to the database. {e}") print(f"Could not update Users status in database")
print(f"'{args.user}' Mail changed to '{args.email}'.") exit(1)
except lib.UserExceptions.General as ChangeUser:
# --> --status print(f"Some chain in the cattle just slipped away, my lord! {ChangeUser}")
if args.status is not None: exit(1)
if args.status != 0 and args.status != 1: print(f"Successfully changed '{args.user}'s status to 1 and created on the system.")
print("Only 0 and 1 are valid status, where 1 is activated and 0 is unapproved.") exit(0)
exit(0)
# just takes first result out of the dict
if args.status == int(CurrentUser["status"]):
print(f"New and old status are the same.")
if args.status == 0 and int(CurrentUser["status"]) == 1:
try:
DB.safequery("UPDATE `applications` SET `status` =? WHERE `id`=?",
tuple([args.status, CurrentUser["id"]]))
sys_ctl.remove_user()
except sqlite3.Error as e:
print(f"Could not update database entry for '{args.user}', did not touch the system")
exit(1)
except lib.UserExceptions.UnknownReturnCode as e:
print(f"Could not remove '{args.user}' from the system, unknown return code: {e}. DB is modified.")
exit(1)
print(f"Successfully changed '{args.user}'s status to 0 and cleared from the system.")
if args.status == 1 and int(CurrentUser["status"]) == 0:
try:
DB.safequery("UPDATE `applications` SET `status`=? WHERE `username`=?",
tuple([args.status, args.user]))
sys_ctl.aio_approve(CurrentUser["pubkey"])
except sqlite3.Error as e:
print(f"Could not update Users status in database")
exit(1)
except lib.UserExceptions.General as ChangeUser:
print(f"Some chain in the cattle just slipped away, my lord! {ChangeUser}")
exit(1)
print(f"Successfully changed '{args.user}'s status to 1 and created on the system.")
exit(0)
except KeyboardInterrupt as e:
pass

@ -1,6 +1,7 @@
import os import os
import subprocess
import pwd import pwd
import subprocess
import lib.UserExceptions import lib.UserExceptions
@ -136,7 +137,7 @@ class System:
os.chown(ssh_dir + "authorized_keys", pwd.getpwnam(self.user)[2], pwd.getpwnam(self.user)[3]) os.chown(ssh_dir + "authorized_keys", pwd.getpwnam(self.user)[2], pwd.getpwnam(self.user)[3])
except OSError as e: # by os.chown except OSError as e: # by os.chown
raise lib.UserExceptions.ModifyFilesystem( raise lib.UserExceptions.ModifyFilesystem(
f"Could not chown {ssh_dir} and/or authorized_keys to {self.user} and their group, Exception: {e}",) f"Could not chown {ssh_dir} and/or authorized_keys to {self.user} and their group, Exception: {e}", )
except KeyError as e: # by PWD except KeyError as e: # by PWD
raise lib.UserExceptions.General(f"PWD can't find {self.user}: {e}") raise lib.UserExceptions.General(f"PWD can't find {self.user}: {e}")
return True return True
@ -201,7 +202,7 @@ class System:
rt = subprocess.call(cc) rt = subprocess.call(cc)
if rt != 0: if rt != 0:
raise lib.UserExceptions.UnknownReturnCode( raise lib.UserExceptions.UnknownReturnCode(
f"Could not add user '{self.user}' to group '{group}' with command '{cc}', returned '{rt}'",) f"Could not add user '{self.user}' to group '{group}' with command '{cc}', returned '{rt}'", )
return True return True
@staticmethod @staticmethod
@ -242,7 +243,7 @@ class System:
if ret.returncode != 0 and ret.returncode != 6: # userdel returns 6 when no mail dir was found but success if ret.returncode != 0 and ret.returncode != 6: # userdel returns 6 when no mail dir was found but success
raise lib.UserExceptions.UnknownReturnCode( raise lib.UserExceptions.UnknownReturnCode(
f"Could not delete user with command {cc}. Return code: {ret.returncode}," f"Could not delete user with command {cc}. Return code: {ret.returncode},"
f" stdout/stderr: {stdio+err_io}") f" stdout/stderr: {stdio + err_io}")
return True return True

@ -2,15 +2,21 @@ class General(Exception):
pass pass
class UnknownUser(General): class User(General):
pass pass
class UnknownReturnCode(General): class UnknownUser(User):
pass def __init__(self, name):
Exception.__init__(self, f"Tried to perform action on unknown user '{name}'")
class UserExistsAlready(User):
def __init__(self, name):
Exception.__init__(self, f"User '{name}' is already registered")
class UserExistsAlready(UnknownReturnCode): class UnknownReturnCode(General):
pass pass
@ -26,10 +32,6 @@ class SQLiteDatabaseDoesntExistYet(General):
pass pass
class User(Exception):
pass
class UsernameLength(User): class UsernameLength(User):
pass pass

@ -1,7 +1,8 @@
import re import csv
import pwd import pwd
import re
import lib.sqlitedb import lib.sqlitedb
import csv
def checkUsernameCharacters(username: str) -> bool: def checkUsernameCharacters(username: str) -> bool:
@ -54,9 +55,8 @@ def checkUserExists(username: str) -> bool:
try: try:
pwd.getpwnam(username) pwd.getpwnam(username)
except KeyError: except KeyError:
return True # User already exists
else:
return False return False
return True # User already exists
def checkUserInDB(username: str, db: str) -> bool: def checkUserInDB(username: str, db: str) -> bool:
@ -203,7 +203,7 @@ def checkImportFile(path: str, db: str):
if not lib.Validator.checkEmail(row["email"]): if not lib.Validator.checkEmail(row["email"]):
errstr += f"Line {ln}: E-Mail address of user '{row['username']}' '{row['email']}' is not valid.\n" errstr += f"Line {ln}: E-Mail address of user '{row['username']}' '{row['email']}' is not valid.\n"
valid = False valid = False
if not lib.Validator.checkUserExists(row["username"]) or checkUserInDB(row["username"], db): if lib.Validator.checkUserExists(row["username"]) or checkUserInDB(row["username"], db):
errstr += f"Line {ln}: User '{row['username']}' already exists.\n" errstr += f"Line {ln}: User '{row['username']}' already exists.\n"
valid = False valid = False
if not lib.Validator.checkDatetimeFormat(row["timestamp"]): if not lib.Validator.checkDatetimeFormat(row["timestamp"]):

Loading…
Cancel
Save