import base64 import json import os from cryptography.fernet import Fernet from pathlib import Path from django.conf import settings from django.contrib.auth.models import User from django.db import models from troggle.core.models.troggle import DataIssue, Expedition, Person, PersonExpedition """This imports the registered troggle users, who are nearly-all, but not quite, Persons. exceptions are "expo" and "expoadmin" which are created by the databaseReset.py import program. This imports unencrypted email addresses but never exports them. Passwords are only ever stored as hashes using the standard Django functions. """ todo = """ - [copy these from paper notes] """ USERS_FILE = "users_e.json" ENCRYPTED_DIR = "encrypted" def load_users(): """These are the previously registered users of the troggle system. """ PARSER_USERS = "_users" DataIssue.objects.filter(parser=PARSER_USERS).delete() key = settings.LONGTERM_SECRET_KEY # Django generated k = base64.urlsafe_b64encode(key.encode("utf8")[:32]) # make Fernet compatible f = Fernet(k) jsonfile = settings.EXPOWEB / ENCRYPTED_DIR / USERS_FILE jsonurl = "/" + str(Path(ENCRYPTED_DIR) / USERS_FILE) if not (jsonfile.is_file()): message = f" ! Users json file does not exist: '{jsonfile}'" DataIssue.objects.create(parser=PARSER_USERS, message=message) print(message) return None with open(jsonfile, 'r', encoding='utf-8') as json_f: message = "" try: registered_users_dict = json.load(json_f) except FileNotFoundError: message = f"File {jsonfile} not found!" except json.JSONDecodeError: message = f"Invalid JSON format! - JSONDecodeError for {jsonfile}" except Exception as e: message = f"! Troggle USERs. Failed to load {jsonfile} JSON file. Exception <{e}>" if message: print(message) DataIssue.objects.update_or_create(parser=PARSER_USERS, message=message, url=jsonurl) return None users_list = registered_users_dict["registered_users"] print(f" - {len(users_list)} users read from JSON") for userdata in users_list: if userdata["username"]: if userdata["username"] in [ "expo", "expoadmin" ]: continue if "encrypted" not in userdata: userdata["encrypted"] = True try: u = userdata["username"] email = userdata["email"] if userdata["encrypted"]: email = f.decrypt(email).decode() print(f" - user: '{u} <{email}>' ") if existing_user := User.objects.filter(username=userdata["username"]): # WALRUS # print(f" - deleting existing user '{existing_user[0]}' before importing") existing_user[0].delete() user = User.objects.create_user(userdata["username"], email, "secret") user.set_password = "secret" # special attribute stores hash not password user.is_staff = False user.is_superuser = False user.save() except Exception as e: print(f"Exception <{e}>\n{len(User.objects.all())} users now in db:\n{User.objects.all()}") formatted_json = json.dumps(userdata, indent=4) print(formatted_json) raise return None else: print(f" - user: BAD username for {userdata} ") ru = [] for u in User.objects.all(): if u.username == "expo": continue if u.username == "expoadmin": continue e_email = f.encrypt(u.email.encode("utf8")).decode() ru.append({"username":u.username, "email": e_email, "password": u.password, "encrypted": True}) # print(u.username, e_email) original = f.decrypt(e_email).decode() print(u.username, original) jsondict = { "registered_users": ru } encryptedfile = settings.EXPOWEB / ENCRYPTED_DIR / "encrypt.json" if settings.DEVSERVER: with open(encryptedfile, 'w', encoding='utf-8') as json_f: json.dump(jsondict, json_f, indent=1) return True