diff --git a/server/db/defaults.py b/server/db/defaults.py index 1f752da4c..da597fc8a 100644 --- a/server/db/defaults.py +++ b/server/db/defaults.py @@ -51,14 +51,24 @@ def calculate_expiry_period(invitation, today=datetime.today()): def cleanse_short_name(data, attr="short_name"): + """ + Cleanses a short_name attribute in a JSON object (typically a description of a CO). + :param data: The JSON object (CO) + :param attr: The attribute name + :return: True if the attribute was modified, False otherwise + """ if attr not in data: raise BadRequest(f"Missing {attr} in JSON") short_name = data[attr] while short_name[0].isnumeric(): short_name = short_name[1:] - data[attr] = re.sub(r"[^a-zA-Z_0-9]+", "", short_name).lower()[:16] - return data[attr] == short_name + short_name = re.sub(r"[^a-zA-Z_0-9]+", "", short_name).lower()[:16] + + is_modified = not (data[attr] == short_name) + data[attr] = short_name + + return not is_modified uri_re = re.compile("^(https?|ssh|ftp)://(.+)$") diff --git a/server/test/api/test_collaboration.py b/server/test/api/test_collaboration.py index e8da72649..bf3154573 100644 --- a/server/test/api/test_collaboration.py +++ b/server/test/api/test_collaboration.py @@ -692,7 +692,7 @@ def test_api_call_existing_short_name(self): data=json.dumps({ "name": "new_collaboration", "administrators": ["the@ex.org"], - "short_name": f"1{ai_computing_short_name}", + "short_name": f"{ai_computing_short_name}", "description": "new_collaboration", "accepted_user_policy": "https://aup.org", "disable_join_requests": True, @@ -748,6 +748,40 @@ def test_api_call_with_invalid_short_name(self): response_json = response.json self.assertTrue("Invalid CO short_name" in response_json["message"]) + def test_api_call_with_invalid_short_name_2(self): + response = self.client.post("/api/collaborations/v1", + headers={"Authorization": f"Bearer {uuc_secret}"}, + data=json.dumps({ + "name": "new_collaboration", + "description": "new_collaboration", + "administrators": ["the@ex.org", "that@ex.org"], + "short_name": "lang56789012345678901234567890", + "disable_join_requests": True, + "disclose_member_information": True, + "disclose_email_information": True + }), + content_type="application/json") + self.assertEqual(400, response.status_code) + response_json = response.json + self.assertTrue("Invalid CO short_name" in response_json["message"]) + + def test_api_call_with_invalid_short_name_3(self): + response = self.client.post("/api/collaborations/v1", + headers={"Authorization": f"Bearer {uuc_secret}"}, + data=json.dumps({ + "name": "new_collaboration", + "description": "new_collaboration", + "administrators": ["the@ex.org", "that@ex.org"], + "short_name": "12begincijfer", + "disable_join_requests": True, + "disclose_member_information": True, + "disclose_email_information": True + }), + content_type="application/json") + self.assertEqual(400, response.status_code) + response_json = response.json + self.assertTrue("Invalid CO short_name" in response_json["message"]) + def test_collaborations_may_request_collaboration_true(self): self.login("urn:mary") res = self.get("/api/collaborations/may_request_collaboration", with_basic_auth=False)