@@ -279,7 +279,13 @@ def api_get(self, url, params=None, data=None, headers=None):
279279 self .update_token (r )
280280 return r
281281
282- def api_post (self , url , params , json , retry = False ):
282+ def api_post (
283+ self ,
284+ url ,
285+ params ,
286+ json ,
287+ retry = False ,
288+ ):
283289 """
284290 Perform a POST request. Refresh XSRF token if necessary.
285291 POSTs are typically used to create objects.
@@ -1464,31 +1470,21 @@ def search_users_not_in_group(self, group_uuid, query=None, embeds=None):
14641470 ]
14651471 return users
14661472
1467- def update_user_metadata (self , user_uuid , metadata_updates ):
1473+ def update_user_metadata (self , user_uuid , path , value , embeds = None ):
14681474 """
14691475 Update user metadata
14701476 @param user_uuid: UUID of the user
14711477 @param metadata_updates: List of metadata updates in the PATCH format
14721478 @return: Updated User object or None if the operation fails
14731479 """
14741480 url = f"{ self .API_ENDPOINT } /eperson/epersons/{ user_uuid } "
1475- headers = {"Content-Type" : "application/json" }
1476- r = self .api_patch (url , headers = headers , data = json .dumps (metadata_updates ))
1477- r_json = parse_json (response = r )
1478- return User (r_json ) if r_json else None
1479-
1480- def replace_user_property (self , user_uuid , path , value ):
1481- """
1482- Replace a specific property of a user
1483- @param user_uuid: UUID of the user
1484- @param path: Path of the property to update (e.g., "/canLogin", "/email")
1485- @param value: New value for the property
1486- @return: Updated User object or None if the operation fails
1487- """
1488- url = f"{ self .API_ENDPOINT } /eperson/epersons/{ user_uuid } "
1489- headers = {"Content-Type" : "application/json" }
1490- data = [{"op" : "replace" , "path" : path , "value" : value }]
1491- r = self .api_patch (url , headers = headers , data = json .dumps (data ))
1481+ r = self .api_patch (
1482+ url = url ,
1483+ operation = "replace" ,
1484+ path = path ,
1485+ value = value ,
1486+ params = parse_params (embeds = embeds ),
1487+ )
14921488 r_json = parse_json (response = r )
14931489 return User (r_json ) if r_json else None
14941490
@@ -1503,19 +1499,21 @@ def change_user_password(self, user_uuid, current_password, new_password):
15031499 # TODO: ensure this is only triggered when the user management is done in DSpace directly.
15041500 # If the user management is done in an external system (e.g. LDAP), this method should not be used.
15051501 url = f"{ self .API_ENDPOINT } /eperson/epersons/{ user_uuid } "
1506- headers = {"Content-Type" : "application/json" }
1507- data = [
1508- {
1509- "op" : "add" ,
1510- "path" : "/password" ,
1511- "value" : {
1512- "new_password" : new_password ,
1513- "current_password" : current_password ,
1514- },
1515- }
1516- ]
1517- r = self .api_patch (url , headers = headers , data = json .dumps (data ))
1518- return r .status_code == 200
1502+ r = self .api_patch (
1503+ url ,
1504+ operation = "add" ,
1505+ path = "/password" ,
1506+ value = {
1507+ "new_password" : new_password ,
1508+ "current_password" : current_password ,
1509+ },
1510+ )
1511+ if r .status_code == 200 :
1512+ logging .info ("Updated Password for user %s" , user_uuid )
1513+ return True
1514+ else :
1515+ logging .error ("An error occurred updating the password." )
1516+ return False
15191517
15201518 # PAGINATION
15211519 def get_users (self , page = 0 , size = 20 , sort = None , embeds = None ):
@@ -1640,9 +1638,9 @@ def update_group_name(self, uuid, new_name):
16401638 @return: Updated Group object or None if the update fails
16411639 """
16421640 url = f"{ self .API_ENDPOINT } /eperson/groups/{ uuid } "
1643- headers = { "Content-Type" : "application/json" }
1644- data = [{ "op" : "replace" , " path" : " /name" , " value" : new_name }]
1645- response = self . api_patch ( url , headers = headers , data = json . dumps ( data ) )
1641+ response = self . api_patch (
1642+ url , operation = "replace" , path = " /name" , value = new_name
1643+ )
16461644 response_json = parse_json (response = response )
16471645 return Group (response_json ) if response_json else None
16481646
@@ -1674,9 +1672,8 @@ def add_subgroup(self, parent_uuid, child_uuid):
16741672 @return: Boolean indicating success or failure
16751673 """
16761674 url = f"{ self .API_ENDPOINT } /eperson/groups/{ parent_uuid } /subgroups"
1677- headers = {"Content-Type" : "text/uri-list" }
16781675 data = f"{ self .API_ENDPOINT } /eperson/groups/{ child_uuid } "
1679- response = self .api_post (url , headers = headers , data = data )
1676+ response = self .api_post_uri (url , uri_list = data , params = None )
16801677 if response .status_code == 204 :
16811678 return True
16821679 elif response .status_code == 401 :
@@ -1710,7 +1707,7 @@ def remove_subgroup(self, parent_uuid, child_uuid):
17101707 @return: Boolean indicating success or failure
17111708 """
17121709 url = f"{ self .API_ENDPOINT } /eperson/groups/{ parent_uuid } /subgroups/{ child_uuid } "
1713- response = self .api_delete (url )
1710+ response = self .api_delete (url , params = None )
17141711 if response .status_code == 204 :
17151712 return True
17161713 if response .status_code == 401 :
@@ -1782,9 +1779,24 @@ def add_eperson_to_group(self, group_uuid, eperson_uuid):
17821779 @return: Boolean indicating success or failure
17831780 """
17841781 url = f"{ self .API_ENDPOINT } /eperson/groups/{ group_uuid } /epersons"
1785- headers = {"Content-Type" : "text/uri-list" }
1782+ # check if the eperson exists and is valid
1783+ eperson = self .get_user_by_uuid (eperson_uuid )
1784+ if eperson is None :
1785+ logging .error ("The specified EPerson does not exist" )
1786+ return False
1787+ if not isinstance (eperson , User ):
1788+ logging .error ("Invalid EPerson object" )
1789+ return False
1790+ # check if the group exists and is valid
1791+ group = self .get_group_by_uuid (group_uuid )
1792+ if group is None :
1793+ logging .error ("The specified group does not exist" )
1794+ return False
1795+ if not isinstance (group , Group ):
1796+ logging .error ("Invalid Group object" )
1797+ return False
17861798 data = f"{ self .API_ENDPOINT } /eperson/epersons/{ eperson_uuid } "
1787- response = self .api_post (url , headers = headers , data = data )
1799+ response = self .api_post_uri (url , uri_list = data , params = None )
17881800 if response .status_code == 204 :
17891801 return True
17901802 elif response .status_code == 401 :
@@ -1813,7 +1825,7 @@ def remove_eperson_from_group(self, group_uuid, eperson_uuid):
18131825 @return: Boolean indicating success or failure
18141826 """
18151827 url = f"{ self .API_ENDPOINT } /eperson/groups/{ group_uuid } /epersons/{ eperson_uuid } "
1816- response = self .api_delete (url )
1828+ response = self .api_delete (url , params = None )
18171829 if response .status_code == 204 :
18181830 return True
18191831 elif response .status_code == 401 :
0 commit comments