3333logging .basicConfig (level = logging .INFO )
3434logger = logging .getLogger (__name__ )
3535
36+ def get_user_attributes (args ):
37+ """Get user attributes from Cognito token.
3638
37- # Function to get the user email from the token
38- def get_user_email (args ):
39+ Args:
40+ args (dict): Request arguments containing the Authorization header.
41+
42+ Returns:
43+ dict: User attributes extracted from the token.
44+
45+ Raises:
46+ Exception: If token verification fails.
47+ """
3948 token = args ["Authorization" ]
4049 try :
4150 user_attributes = verify_cognito_token (token )
42- owner_email = user_attributes ["email" ]
43- if not owner_email :
44- logger .error ("No email found in user attributes" )
45- abort (401 , description = "Not authorized" )
46- return owner_email
51+ return user_attributes
4752 except Exception as error :
4853 logger .exception ("Error verifying token: %s" , error )
4954 abort (401 , description = "Not authorized" )
5055
56+ def get_user_information () -> dict :
57+ """A function to collect user information from a given Cognito Token.
58+
59+ Returns:
60+ dict: A dictionary containing the user's email and groups.
61+
62+ Raises:
63+ abort: If the email is not found in user attributes.
64+ """
65+ user_attributes = get_user_attributes (parser .parse_args ())
66+
67+ owner_email = user_attributes .get ("email" , "" )
68+ user_groups = user_attributes .get ("cognito:groups" , [])
69+
70+ if not owner_email :
71+ logger .error ("No email found in user attributes" )
72+ abort (401 , description = "Not authorized" )
73+
74+ return {"email" : owner_email , "groups" : user_groups }
75+
76+ def is_auth_user_in_admin_group (user_groups : list ) -> bool :
77+ """Check if the authenticated user is in the admin group.
78+
79+ Args:
80+ user_groups (list): List of groups the user belongs to.
81+
82+ Returns:
83+ bool: True if user is in admin group, False otherwise.
84+ """
85+ return "Admin" in user_groups
5186
5287# Route to return the user email from the token in authorization header
5388@ns .route ("/user" )
5489class User (Resource ):
5590 @ns .doc (responses = {200 : "Success" , 401 : "Authorization is required" })
5691 def get (self ):
57- owner_email = get_user_email (parser .parse_args ())
58- return {"email" : owner_email }, 200
92+ user_info = get_user_information ()
93+ owner_email = user_info ["email" ]
94+ user_groups = user_info ["groups" ]
95+ return {"email" : owner_email , "groups" : user_groups }, 200
5996
6097
6198# Route to return all projects with optional filters
@@ -339,7 +376,6 @@ class Projects(Resource):
339376 @ns .doc (responses = {200 : "Success" , 401 : "Authorization is required" })
340377 # @ns.marshal_list_with(project_model)
341378 def get (self ):
342- owner_email = get_user_email (parser .parse_args ())
343379 data = read_data ("new_project_data.json" )
344380 user_projects = [proj for proj in data ["projects" ]]
345381 return user_projects , 200
@@ -358,7 +394,8 @@ def get(self):
358394 },
359395 )
360396 def post (self ):
361- owner_email = get_user_email (parser .parse_args ())
397+ user_info = get_user_information ()
398+ owner_email = user_info ["email" ]
362399
363400 # Check that required fields are present in the JSON payload
364401 new_project = ns .payload
@@ -438,8 +475,6 @@ class ProjectDetail(Resource):
438475 # the name and the user email in the first user item in the user list
439476 @ns .marshal_with (project_model )
440477 def get (self , project_name ):
441- owner_email = get_user_email (parser .parse_args ())
442-
443478 # Sanitize project_name by replacing '%20' with spaces
444479 project_name = (
445480 project_name .replace ("%20" , " " ).replace ("\r \n " , "" ).replace ("\n " , "" )
@@ -474,7 +509,10 @@ def get(self, project_name):
474509 },
475510 )
476511 def put (self , project_name ):
477- owner_email = get_user_email (parser .parse_args ())
512+ user_info = get_user_information ()
513+ owner_email = user_info ["email" ]
514+ user_groups = user_info ["groups" ]
515+
478516 project_name = (
479517 project_name .replace ("%20" , " " ).replace ("\r \n " , "" ).replace ("\n " , "" )
480518 )
@@ -494,17 +532,18 @@ def put(self, project_name):
494532 if key not in environments or not isinstance (environments [key ], bool ):
495533 abort (400 , description = f"Invalid environments data: '{ key } ' must be a boolean" )
496534
497-
498535 # Ensure the email is set to owner_email
499536
500537 data = read_data ("new_project_data.json" )
501538
539+ logger .info (f"Authenticated user is in admin group: { is_auth_user_in_admin_group (user_groups )} " )
540+
502541 project = next (
503542 (
504543 proj
505544 for proj in data ["projects" ]
506545 if proj ["details" ][0 ]["name" ] == project_name
507- and any (user ["email" ] == owner_email for user in proj ["user" ])
546+ and ( any (user ["email" ] == owner_email for user in proj ["user" ]) or is_auth_user_in_admin_group ( user_groups ) )
508547 ),
509548 None ,
510549 )
0 commit comments