mirror of
https://expo.survex.com/repositories/troggle/.git
synced 2025-12-16 10:47:12 +00:00
129 lines
4.9 KiB
Python
129 lines
4.9 KiB
Python
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 register_user(u, email, password=None, pwhash=None):
|
|
try:
|
|
if existing_user := User.objects.filter(username=u): # WALRUS
|
|
print(f" - deleting existing user '{existing_user[0]}' before importing")
|
|
existing_user[0].delete()
|
|
user = User.objects.create_user(u, email)
|
|
if pwhash:
|
|
user.password = pwhash
|
|
elif password:
|
|
user.set_password(password) # function creates hash and stores hash
|
|
print(f" # hashing provided clear-text password {password} to make pwhash for user {u}")
|
|
else:
|
|
user.set_password('secret') # function creates hash and stores hash
|
|
print(f" # hashing 'secret' password to make pwhash for user {u}")
|
|
user.is_staff = False
|
|
user.is_superuser = False
|
|
user.save()
|
|
print(f" - receated and reset user '{user}'")
|
|
except Exception as e:
|
|
print(f"Exception <{e}>\n{len(User.objects.all())} users now in db:\n{User.objects.all()}")
|
|
raise
|
|
|
|
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}>' ")
|
|
except Exception as e:
|
|
print(f"Exception <{e}>\n")
|
|
formatted_json = json.dumps(userdata, indent=4)
|
|
print(formatted_json)
|
|
raise
|
|
return None
|
|
if "pwhash" in userdata:
|
|
pwhash = userdata["pwhash"]
|
|
register_user(u, email, pwhash=pwhash)
|
|
else:
|
|
register_user(u, email)
|
|
else:
|
|
print(f" - user: BAD username for {userdata} ")
|
|
|
|
ru = []
|
|
print(f"\n + Exporting users, encrypted emails, and password hashes")
|
|
for u in User.objects.all():
|
|
if u.username in ["expo", "expoadmin"]:
|
|
continue
|
|
e_email = f.encrypt(u.email.encode("utf8")).decode()
|
|
ru.append({"username":u.username, "email": e_email, "pwhash": u.password, "encrypted": True})
|
|
# print(u.username, e_email)
|
|
original = f.decrypt(e_email).decode()
|
|
print(f" - {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
|
|
|