Skip to content

Commit 694a583

Browse files
committed
Added: admin user toggle route (#155)
1 parent 061fc59 commit 694a583

File tree

2 files changed

+72
-8
lines changed

2 files changed

+72
-8
lines changed

libreforms_fastapi/app/__init__.py

+71-7
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
check_configuration_assumptions,
7272
generate_password_hash,
7373
check_password_hash,
74+
percentage_alphanumeric_generate_password,
7475
)
7576

7677
# Import the tools used to generate signatures
@@ -1545,7 +1546,7 @@ async def api_auth_create(
15451546
new_user.public_key = ds_manager.public_key_bytes
15461547

15471548
# Add the user to the default group
1548-
group = session.query(Group).filter_by(name='default').first()
1549+
group = session.query(Group).filter_by(id=1).first()
15491550
new_user.groups.append(group)
15501551

15511552
session.add(new_user)
@@ -1870,9 +1871,7 @@ async def api_auth_help(
18701871
##########################
18711872

18721873
# Get all users
1873-
# > paired with manage users admin UI route
1874-
1875-
1874+
# > paired with manage users admin UI route
18761875
@app.get(
18771876
"/api/admin/get_users",
18781877
dependencies=[Depends(api_key_auth)],
@@ -1922,11 +1921,76 @@ async def api_admin_get_users(
19221921
# Add new user
19231922
# > paired with add newadmin UI route
19241923

1925-
# Modify user *** including disable user
1924+
# User setting toggles
1925+
@app.patch(
1926+
"/api/admin/toggle/{field}/{id}",
1927+
dependencies=[Depends(api_key_auth)],
1928+
response_class=JSONResponse,
1929+
)
1930+
async def api_admin_modify_user(
1931+
field:str,
1932+
id:str,
1933+
request: Request,
1934+
background_tasks: BackgroundTasks,
1935+
session: SessionLocal = Depends(get_db),
1936+
key: str = Depends(X_API_KEY)
1937+
):
1938+
"""
1939+
Toggles a user field by ID. In the case of passwords, it resets them. Requires site admin permissions.
1940+
Logs the action for audit purposes.
1941+
"""
1942+
1943+
if field not in ["active", "site_admin", "password", "api_key"]:
1944+
raise HTTPException(status_code=404)
1945+
1946+
# Get the requesting user details
1947+
user = session.query(User).filter_by(api_key=key).first()
1948+
1949+
if not user or not user.site_admin:
1950+
raise HTTPException(status_code=404)
1951+
1952+
1953+
user_to_change = session.query(User).get(id)
1954+
if not user_to_change:
1955+
raise HTTPException(status_code=404, detail="Could not find user. Are you sure they exist?")
1956+
1957+
# Here we set the relevant value to change
1958+
if field in ["active", "site_admin"]:
1959+
if user.id == user_to_change.id:
1960+
raise HTTPException(status_code=418, detail=f"You really shouldn't try to toggle the {field} status of the current user...")
1961+
new_value = not getattr(user_to_change, field)
1962+
setattr(user_to_change, field, new_value)
1963+
elif field == "password":
1964+
new_value = percentage_alphanumeric_generate_password(config.PASSWORD_REGEX, 16, .65)
1965+
user_to_change.password = generate_password_hash(new_value)
1966+
elif field == "api_key":
1967+
# Rotate the user's API key
1968+
new_value = signatures.rotate_key(user_to_change.api_key)
1969+
user_to_change.api_key = new_value
1970+
1971+
session.add(user_to_change)
1972+
session.commit()
1973+
1974+
# Write this query to the TransactionLog
1975+
if config.COLLECT_USAGE_STATISTICS:
1976+
background_tasks.add_task(
1977+
write_api_call_to_transaction_log,
1978+
api_key=key,
1979+
endpoint=request.url.path,
1980+
remote_addr=request.client.host,
1981+
query_params={},
1982+
)
1983+
1984+
return JSONResponse(
1985+
status_code=200,
1986+
content={"status": "success", "message": f"{field} set to {new_value} for user id {id}"},
1987+
)
1988+
1989+
19261990

1927-
# Get Transaction Statistics
1928-
# Paired with the Transaction Statistics admin UI route
19291991

1992+
# Get Transaction Log
1993+
# Paired with the Transaction Data admin UI route
19301994

19311995
# Update application config
19321996

libreforms_fastapi/utils/scripts.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import re
1+
import re, random, string
22
from passlib.context import CryptContext
33

44
# Create a password context

0 commit comments

Comments
 (0)