allows admins to create new users
This commit is contained in:
46
admin.py
46
admin.py
@@ -137,3 +137,49 @@ def register_admin_routes(app):
|
||||
except Exception as e:
|
||||
print(f"[ERR] Failed to update user: {e}")
|
||||
abort(500, "Failed to update user")
|
||||
|
||||
@app.route("/admin/users/new")
|
||||
@admin_required
|
||||
def admin_user_new():
|
||||
"""Display form to create a new user"""
|
||||
return render_template("admin_user_create.html")
|
||||
|
||||
@app.route("/admin/users/create", methods=["POST"])
|
||||
@admin_required
|
||||
def create_user():
|
||||
"""Create a new user"""
|
||||
try:
|
||||
# Get form data
|
||||
user_email = request.form.get("user_email")
|
||||
if not user_email:
|
||||
abort(400, "User email is required")
|
||||
|
||||
# Validate email format
|
||||
if "@" not in user_email:
|
||||
abort(400, "Invalid email format")
|
||||
|
||||
# Create user in Firebase Authentication
|
||||
user_record = fb_auth.create_user(
|
||||
email=user_email,
|
||||
email_verified=False,
|
||||
disabled=not request.form.get("enabled", False)
|
||||
)
|
||||
|
||||
# Create user profile in Firestore
|
||||
user_ref = db.collection("users").document(user_record.uid)
|
||||
user_ref.set({
|
||||
"user_email": user_email,
|
||||
"case_email": request.form.get("case_email", ""),
|
||||
"enabled": bool(request.form.get("enabled", False)),
|
||||
"is_admin": bool(request.form.get("is_admin", False))
|
||||
})
|
||||
|
||||
# Redirect to admin users page
|
||||
return redirect(url_for("admin_users"))
|
||||
|
||||
except fb_auth.EmailAlreadyExistsError:
|
||||
print(f"[ERR] User with email {user_email} already exists")
|
||||
abort(400, "A user with this email already exists")
|
||||
except Exception as e:
|
||||
print(f"[ERR] Failed to create user: {e}")
|
||||
abort(500, "Failed to create user")
|
||||
55
templates/admin_user_create.html
Normal file
55
templates/admin_user_create.html
Normal file
@@ -0,0 +1,55 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block content %}
|
||||
<div class="h-full flex flex-col max-w-2xl mx-auto">
|
||||
<h1 class="text-xl font-semibold mb-6">Create New User</h1>
|
||||
|
||||
<form method="POST" action="/admin/users/create" class="space-y-6">
|
||||
<div>
|
||||
<label for="user_email" class="block text-sm font-medium text-slate-700">User Email</label>
|
||||
<input type="email" id="user_email" name="user_email"
|
||||
value=""
|
||||
required
|
||||
class="mt-1 block w-full px-3 py-2 border border-slate-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500">
|
||||
<p class="mt-1 text-sm text-slate-500">The email address that will be used for authentication.</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="enabled" class="block text-sm font-medium text-slate-700">Enabled</label>
|
||||
<div class="mt-1 flex items-center">
|
||||
<input type="checkbox" id="enabled" name="enabled"
|
||||
checked
|
||||
class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-slate-300 rounded">
|
||||
<label for="enabled" class="ml-2 block text-sm text-slate-700">Check to enable this user</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="is_admin" class="block text-sm font-medium text-slate-700">Admin</label>
|
||||
<div class="mt-1 flex items-center">
|
||||
<input type="checkbox" id="is_admin" name="is_admin"
|
||||
class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-slate-300 rounded">
|
||||
<label for="is_admin" class="ml-2 block text-sm text-slate-700">Check to make this user an admin</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="case_email" class="block text-sm font-medium text-slate-700">Case Email</label>
|
||||
<input type="email" id="case_email" name="case_email"
|
||||
value=""
|
||||
class="mt-1 block w-full px-3 py-2 border border-slate-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500">
|
||||
<p class="mt-1 text-sm text-slate-500">The email address used for project access.</p>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end space-x-3 pt-4">
|
||||
<button type="button" onclick="window.location.href='/admin/users'"
|
||||
class="px-4 py-2 text-sm font-medium text-slate-700 bg-gray-100 hover:bg-gray-200 rounded-md transition-colors">
|
||||
Cancel
|
||||
</button>
|
||||
<button type="submit"
|
||||
class="px-4 py-2 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-md transition-colors">
|
||||
Create User
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -19,6 +19,11 @@
|
||||
{% set _ = session.pop('reset_user_email', None) %}
|
||||
{% endif %}
|
||||
<h1 class="text-xl font-semibold mb-4">Admin: User Management</h1>
|
||||
<div class="mb-6">
|
||||
<a href="/admin/users/new" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
|
||||
Create New User
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="overflow-scroll">
|
||||
<table class="w-full whitespace-nowrap shadow-md border border-slate-200">
|
||||
|
||||
Reference in New Issue
Block a user