Skip to content

Commit a4b5092

Browse files
committed
Update export script
- Do not export inactive users, they have never logged in. - Set OW4 userid on export - Support exporting without password for updating a previous export - Fix off-by one in number of scripts
1 parent 2ba3f8e commit a4b5092

File tree

1 file changed

+31
-17
lines changed

1 file changed

+31
-17
lines changed

scripts/management/commands/auth0_export.py

+31-17
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
from django.core.management.base import BaseCommand
88

9-
from apps.authentication.models import OnlineUser
9+
from apps.authentication.models import Email, OnlineUser
1010

1111
ws = re.compile(r"\s+")
1212

@@ -36,10 +36,12 @@ def extract_phone_number(u: OnlineUser) -> Optional[str]:
3636

3737
def create_auth0_user(u: OnlineUser):
3838
if not u.has_usable_password:
39-
print(f"Skipping {u}, no usable password")
39+
print(f"Skipping {u.pk}, no usable password")
4040
return None
4141
if u.email is None or len(u.email) == 0:
42-
print(f"Skipping {u}, no email")
42+
emails = Email.objects.filter(user=u)
43+
# print(u.email_user)
44+
print(f"Skipping {u.pk}, no email or? {emails}")
4345
return None
4446
# if u.auth0_subject is not None:
4547
# print(f"Skipping {u}, already migrated")
@@ -48,7 +50,7 @@ def create_auth0_user(u: OnlineUser):
4850
try:
4951
algorithm, iterations, salt, hash = u.password.split("$", 3)
5052
except ValueError as e:
51-
print(f"{e=}\n{u=}\n{u.password=}")
53+
print(f"{e}\n{u.pk=}\n{u.password=}")
5254
return None
5355

5456
# thank you https://community.auth0.com/t/wrong-password-for-imported-users-from-django/61105
@@ -58,24 +60,34 @@ def create_auth0_user(u: OnlineUser):
5860
# we probably only use pbkdf2_sha256, in auth0 they use -
5961
algorithm = algorithm.replace("_", "-")
6062

61-
id = str(uuid4())
62-
u.auth0_subject = f"auth0|{id}"
63+
user_previously_exported = True
64+
if not u.auth0_subject:
65+
user_previously_exported = False
66+
id = str(uuid4())
67+
u.auth0_subject = f"auth0|{id}"
6368

6469
auth0_user = {
65-
"user_id": id,
70+
"user_id": u.auth0_subject.split("|")[1],
6671
"email": u.email,
6772
"email_verified": u.is_active,
6873
"given_name": u.first_name,
6974
"family_name": u.last_name,
70-
"name": f"{u.first_name} {u.last_name}",
71-
"custom_password_hash": {
75+
"user_metadata": {},
76+
"app_metadata": {
77+
"ow4_userid": u.pk,
78+
},
79+
}
80+
81+
if not user_previously_exported:
82+
# we do not want to export passwords of existing users in auth0
83+
# auth0 then just errors out, and users might not remember their passwords
84+
auth0_user["custom_password_hash"] = {
7285
"algorithm": "pbkdf2",
7386
"hash": {
7487
"encoding": "utf-8",
7588
"value": f"$pbkdf2-sha256$i={iterations},l=32${salt}${hash}",
7689
},
77-
},
78-
}
90+
}
7991

8092
if len(u.first_name) == 0:
8193
del auth0_user["given_name"]
@@ -84,21 +96,23 @@ def create_auth0_user(u: OnlineUser):
8496
del auth0_user["family_name"]
8597

8698
if num := extract_phone_number(u):
87-
auth0_user["mfa_factors"] = [{"phone": {"value": num}}]
99+
auth0_user["user_metadata"]["phone"] = num
100+
101+
if len(auth0_user["user_metadata"]) == 0:
102+
del auth0_user["user_metadata"]
88103

89104
return (u, auth0_user)
90105

91106

92107
class Command(BaseCommand):
93108
def handle(self, *args, **options):
94-
users = [
95-
create_auth0_user(u) for u in OnlineUser.objects.iterator(chunk_size=100)
96-
]
109+
qs = OnlineUser.objects.filter(is_active=True)
110+
users = [create_auth0_user(u) for u in qs.iterator(chunk_size=100)]
97111
users = [u for u in users if u is not None]
98112
N = 700
99-
for i in range(int(OnlineUser.objects.count() / 700)):
113+
for i in range(int(qs.count() / N) + 1):
100114
chunk = users[i * N : i * N + N]
101115
OnlineUser.objects.bulk_update([u for (u, _) in chunk], ["auth0_subject"])
102116
file = json.dumps([a0u for (_, a0u) in chunk])
103-
with open(f"auth0_users_staging_{i}.json", "w") as f:
117+
with open(f"auth0_users_prod_{i}.json", "w") as f:
104118
f.write(file)

0 commit comments

Comments
 (0)