From de7b5114f1f835cf6ea41b2cb2d2c38e89c28df2 Mon Sep 17 00:00:00 2001 From: Jeny Sadadia Date: Wed, 21 Jun 2023 11:48:23 +0530 Subject: [PATCH 1/3] api.main: add `/users/profile` endpoint Implement an endpoint to get public profile details of all available users. It also accepts request query parameters to get matching user. e.g. `http://API_URL/users?username=test` This will exclude password field from the response for security reasons. Signed-off-by: Jeny Sadadia --- api/main.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/api/main.py b/api/main.py index b7597fb8..d996e57f 100644 --- a/api/main.py +++ b/api/main.py @@ -173,6 +173,26 @@ async def post_user( return obj +@app.get('/users/profile', response_model=PageModel, + response_model_include={"items": {"__all__": {"profile": { + "username", "groups"}}}, + "total": {"__all__"}, + "limit": {"__all__"}, + "offset": {"__all__"}, + }) +async def get_users_profile(request: Request): + """Get profile of all the users if no request parameters have passed. + Get the matching user profile otherwise.""" + query_params = dict(request.query_params) + # Drop pagination parameters from query as they're already in arguments + for pg_key in ['limit', 'offset']: + query_params.pop(pg_key, None) + paginated_resp = await db.find_by_attributes(User, query_params) + paginated_resp.items = serialize_paginated_data( + User, paginated_resp.items) + return paginated_resp + + @app.post('/group', response_model=UserGroup, response_model_by_alias=False) async def post_user_group( group: UserGroup, From d8d76ae4998e5c47fae97abeb8f65851c6a43403 Mon Sep 17 00:00:00 2001 From: Jeny Sadadia Date: Fri, 7 Jul 2023 22:35:38 +0530 Subject: [PATCH 2/3] api.main: implement `/users` endpoint Implement an endpoint to get all available user models. The user model will contain private information along with public user profiles. Thus, the endpoint will be accessible by admin users only. Signed-off-by: Jeny Sadadia --- api/main.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/api/main.py b/api/main.py index d996e57f..e5a50ecb 100644 --- a/api/main.py +++ b/api/main.py @@ -193,6 +193,24 @@ async def get_users_profile(request: Request): return paginated_resp +@app.get('/users', response_model=PageModel, + response_model_exclude={"items": {"__all__": {"profile": { + "hashed_password"}}}}) +async def get_users( + request: Request, + current_user: User = Security(get_user, scopes=["admin"])): + """Get all the users if no request parameters have passed. + Get the matching users otherwise.""" + query_params = dict(request.query_params) + # Drop pagination parameters from query as they're already in arguments + for pg_key in ['limit', 'offset']: + query_params.pop(pg_key, None) + paginated_resp = await db.find_by_attributes(User, query_params) + paginated_resp.items = serialize_paginated_data( + User, paginated_resp.items) + return paginated_resp + + @app.post('/group', response_model=UserGroup, response_model_by_alias=False) async def post_user_group( group: UserGroup, From 44e6d08db2548b1b364a3ea6fa1e87f26e062ca6 Mon Sep 17 00:00:00 2001 From: Jeny Sadadia Date: Tue, 11 Jul 2023 14:58:52 +0530 Subject: [PATCH 3/3] api.main: add `/user/` endpoint Implement an endpoint to get user model matching provided user ID. The endpoint will be accessible by admin users only and will not include password in the response. Signed-off-by: Jeny Sadadia --- api/main.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/api/main.py b/api/main.py index e5a50ecb..a097cac4 100644 --- a/api/main.py +++ b/api/main.py @@ -211,6 +211,16 @@ async def get_users( return paginated_resp +@app.get('/user/{user_id}', response_model=User, + response_model_by_alias=False, + response_model_exclude={"profile": {"hashed_password"}}) +async def get_user_by_id( + user_id: str, + current_user: User = Security(get_user, scopes=["admin"])): + """Get user matching provided user id""" + return await db.find_by_id(User, user_id) + + @app.post('/group', response_model=UserGroup, response_model_by_alias=False) async def post_user_group( group: UserGroup,