|
|
|
@ -66,7 +66,6 @@ from pathlib import Path |
|
|
|
|
from requests import get, post, delete, auth, HTTPError |
|
|
|
|
from requests.auth import HTTPBasicAuth |
|
|
|
|
from synapse.types import get_localpart_from_id |
|
|
|
|
from urllib.parse import parse_qs, urlparse |
|
|
|
|
# +watcha |
|
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__) |
|
|
|
@ -1436,104 +1435,33 @@ class WatchaRoomHandler(BaseHandler): |
|
|
|
|
|
|
|
|
|
self.keycloak_access_token = "" |
|
|
|
|
|
|
|
|
|
async def delete_room_mapping_with_nextcloud_directory(self, room_id, requester_id): |
|
|
|
|
async def delete_room_mapping_with_nextcloud_directory(self, room_id): |
|
|
|
|
""" Delete a mapping between a room and an Nextcloud folder. |
|
|
|
|
|
|
|
|
|
Args : |
|
|
|
|
room_id: the id of the room. |
|
|
|
|
requester_id: the user_id of the requester. |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
directory_path = await self.store.get_nextcloud_directory_path_from_roomID( |
|
|
|
|
room_id |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
self.keycloak_access_token = await self.get_keycloak_access_token() |
|
|
|
|
except HTTPError: |
|
|
|
|
raise SynapseError( |
|
|
|
|
400, |
|
|
|
|
"Unable to retrieve the Keycloak access token of realm {}".format( |
|
|
|
|
self.keycloak_realm |
|
|
|
|
), |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
nextcloud_username = await self.get_nextcloud_username( |
|
|
|
|
get_localpart_from_id(requester_id) |
|
|
|
|
) |
|
|
|
|
except HTTPError: |
|
|
|
|
raise SynapseError( |
|
|
|
|
400, |
|
|
|
|
"Unable to retrieve the corresponding Nextcloud username of user {}.".format( |
|
|
|
|
requester_id |
|
|
|
|
), |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
all_shares = await self.get_sharing_of_nextcloud_directory( |
|
|
|
|
nextcloud_username, directory_path |
|
|
|
|
) |
|
|
|
|
except HTTPError as e: |
|
|
|
|
if e.response.status_code == 404: |
|
|
|
|
raise SynapseError( |
|
|
|
|
400, |
|
|
|
|
"The user {} doesn't have the access right to the folder {}.".format( |
|
|
|
|
requester_id, directory_path |
|
|
|
|
), |
|
|
|
|
Codes.NEXTCLOUD_FOLDER_ACCESS_FORBIDDEN, |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
raise SynapseError( |
|
|
|
|
400, "Unable to get shares on the folder {}.".format(directory_path), |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
group_share_id = "" |
|
|
|
|
for share in all_shares: |
|
|
|
|
if share["share_with"] == room_id: |
|
|
|
|
group_share_id = share["id"] |
|
|
|
|
break |
|
|
|
|
|
|
|
|
|
if not group_share_id: |
|
|
|
|
raise SynapseError( |
|
|
|
|
400, |
|
|
|
|
"Unable to retrieve share id between Watcha room {} and Nextcloud directory {}".format( |
|
|
|
|
room_id, directory_path |
|
|
|
|
), |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
await self.delete_existing_nextcloud_share( |
|
|
|
|
nextcloud_username, group_share_id |
|
|
|
|
) |
|
|
|
|
await self.delete_nextcloud_group(room_id) |
|
|
|
|
except HTTPError: |
|
|
|
|
raise SynapseError( |
|
|
|
|
400, |
|
|
|
|
"Unable to delete the share on the nextcloud folder {} for the nextcloud group {}.".format( |
|
|
|
|
room_id, directory_path |
|
|
|
|
), |
|
|
|
|
400, "Unable to delete the Nextcloud group {}.".format(room_id), |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
await self.store.deleted_room_mapping_with_nextcloud_directory(room_id) |
|
|
|
|
|
|
|
|
|
async def add_room_mapping_with_nextcloud_directory( |
|
|
|
|
self, room_id, requester_id, nextcloud_URL |
|
|
|
|
async def update_nextcloud_mapping( |
|
|
|
|
self, room_id, requester_id, nextcloud_directory_path |
|
|
|
|
): |
|
|
|
|
""" Add a mapping between a room and an Nextcloud folder. |
|
|
|
|
""" Update the mapping between a room and a Nextcloud folder. |
|
|
|
|
|
|
|
|
|
Args : |
|
|
|
|
room_id: the id of the room which must be linked with the Nextcloud folder. |
|
|
|
|
requester_id: the user_id of the requester. |
|
|
|
|
nextcloud_URL: an URL pointing on the Nextcloud folder to link with the room. |
|
|
|
|
nextcloud_directory_path: the directory path of the Nextcloud folder to link with the room. |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
nextcloud_URL_query = parse_qs(urlparse(nextcloud_URL).query) |
|
|
|
|
|
|
|
|
|
if "dir" not in nextcloud_URL_query: |
|
|
|
|
raise SynapseError(400, "The url doesn't point to a valid directory path.") |
|
|
|
|
|
|
|
|
|
nextcloud_directory_path = nextcloud_URL_query["dir"][0] |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
self.keycloak_access_token = await self.get_keycloak_access_token() |
|
|
|
|
except HTTPError: |
|
|
|
@ -1556,35 +1484,11 @@ class WatchaRoomHandler(BaseHandler): |
|
|
|
|
), |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
await self.get_sharing_of_nextcloud_directory( |
|
|
|
|
nextcloud_username, nextcloud_directory_path |
|
|
|
|
) |
|
|
|
|
except HTTPError as e: |
|
|
|
|
if e.response.status_code == 404: |
|
|
|
|
raise SynapseError( |
|
|
|
|
400, |
|
|
|
|
"The user {} doesn't have the access right to the folder {}.".format( |
|
|
|
|
requester_id, nextcloud_directory_path |
|
|
|
|
), |
|
|
|
|
Codes.NEXTCLOUD_FOLDER_ACCESS_FORBIDDEN, |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
raise SynapseError( |
|
|
|
|
400, |
|
|
|
|
"Unable to get shares on the folder {}.".format( |
|
|
|
|
nextcloud_directory_path |
|
|
|
|
), |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
group_exists = await self.nextcloud_room_group_exists(room_id) |
|
|
|
|
except HTTPError: |
|
|
|
|
raise SynapseError( |
|
|
|
|
400, |
|
|
|
|
"Unable to retrieve to know if the nextcloud group {} exists or not.".format( |
|
|
|
|
room_id |
|
|
|
|
), |
|
|
|
|
400, "Unable to know if the nextcloud group {} exists.".format(room_id), |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
if not group_exists: |
|
|
|
@ -1595,15 +1499,58 @@ class WatchaRoomHandler(BaseHandler): |
|
|
|
|
400, "Unable to create the Nextcloud group {}.".format(room_id) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
mapped_directory_path = await self.store.get_nextcloud_directory_path_from_roomID( |
|
|
|
|
room_id |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
if mapped_directory_path: |
|
|
|
|
try: |
|
|
|
|
await self.delete_existing_nextcloud_share( |
|
|
|
|
nextcloud_username, mapped_directory_path, room_id |
|
|
|
|
) |
|
|
|
|
except HTTPError as e: |
|
|
|
|
logger.error( |
|
|
|
|
"Unable to delete the share on the nextcloud folder {} for the nextcloud group {} : ".format( |
|
|
|
|
room_id, directory_path, e |
|
|
|
|
) |
|
|
|
|
) |
|
|
|
|
if e.response.status_code == 404: |
|
|
|
|
raise SynapseError( |
|
|
|
|
404, |
|
|
|
|
"The user {} doesn't have the access right to the folder {}.".format( |
|
|
|
|
requester_id, directory_path |
|
|
|
|
), |
|
|
|
|
Codes.NEXTCLOUD_FOLDER_ACCESS_FORBIDDEN, |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
raise SynapseError( |
|
|
|
|
400, |
|
|
|
|
"Unable to get shares on the folder {}.".format(directory_path), |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
await self.create_new_nextcloud_share( |
|
|
|
|
nextcloud_username, nextcloud_directory_path, room_id |
|
|
|
|
) |
|
|
|
|
except HTTPError: |
|
|
|
|
except HTTPError as e: |
|
|
|
|
logger.error( |
|
|
|
|
"Unable to create a share for the nextcloud group {} on the nextcloud folder {} : {}".format( |
|
|
|
|
room_id, nextcloud_directory_path, e |
|
|
|
|
), |
|
|
|
|
) |
|
|
|
|
if e.response.status_code == 404: |
|
|
|
|
raise SynapseError( |
|
|
|
|
404, |
|
|
|
|
"The user {} doesn't have the access right to the folder {}.".format( |
|
|
|
|
requester_id, nextcloud_directory_path |
|
|
|
|
), |
|
|
|
|
Codes.NEXTCLOUD_FOLDER_ACCESS_FORBIDDEN, |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
raise SynapseError( |
|
|
|
|
400, |
|
|
|
|
"Unable to create a share for the nextcloud group {} on the nextcloud folder {}.".format( |
|
|
|
|
room_id, nextcloud_directory_path |
|
|
|
|
"Unable to get shares on the folder {}.".format( |
|
|
|
|
nextcloud_directory_path |
|
|
|
|
), |
|
|
|
|
) |
|
|
|
|
|
|
|
|
@ -1739,6 +1686,22 @@ class WatchaRoomHandler(BaseHandler): |
|
|
|
|
) |
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
async def delete_nextcloud_group(self, room_id): |
|
|
|
|
""" Delete an Nextcloud group named as room_id. |
|
|
|
|
|
|
|
|
|
Args: |
|
|
|
|
room_id: the room_id of the room which Nextcloud directory is linked. |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
request = delete( |
|
|
|
|
"{}/ocs/v1.php/cloud/groups/{}".format(self.nextcloud_server, room_id), |
|
|
|
|
headers={"OCS-APIRequest": "true"}, |
|
|
|
|
auth=HTTPBasicAuth( |
|
|
|
|
self.service_account_name, self.service_account_password |
|
|
|
|
), |
|
|
|
|
) |
|
|
|
|
request.raise_for_status() |
|
|
|
|
|
|
|
|
|
async def add_user_to_nextcloud_groups(self, username, group_name): |
|
|
|
|
""" Add user to the Nextcloud group named as room_id. |
|
|
|
|
|
|
|
|
@ -1771,6 +1734,8 @@ class WatchaRoomHandler(BaseHandler): |
|
|
|
|
group_name: the Nextcloud group id. |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
await self.get_sharing_of_nextcloud_directory(requester, directory_path) |
|
|
|
|
|
|
|
|
|
request = post( |
|
|
|
|
"{}/ocs/v2.php/apps/files_sharing/api/v1/shares".format( |
|
|
|
|
self.nextcloud_server |
|
|
|
@ -1787,13 +1752,33 @@ class WatchaRoomHandler(BaseHandler): |
|
|
|
|
) |
|
|
|
|
request.raise_for_status() |
|
|
|
|
|
|
|
|
|
async def delete_existing_nextcloud_share(self, requester, share_id): |
|
|
|
|
async def delete_existing_nextcloud_share( |
|
|
|
|
self, requester, mapped_directory_path, group_name |
|
|
|
|
): |
|
|
|
|
""" Delete an existing share (corresponding to the share id) on the folder. |
|
|
|
|
|
|
|
|
|
Args: |
|
|
|
|
requester: the Nextcloud username of the requester who want to delete an existing share. |
|
|
|
|
share_id: the id of the share to delete. |
|
|
|
|
""" |
|
|
|
|
all_shares = await self.get_sharing_of_nextcloud_directory( |
|
|
|
|
requester, mapped_directory_path |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
share_id = "" |
|
|
|
|
for share in all_shares: |
|
|
|
|
if share["share_with"] == group_name: |
|
|
|
|
share_id = share["id"] |
|
|
|
|
break |
|
|
|
|
|
|
|
|
|
if not share_id: |
|
|
|
|
raise SynapseError( |
|
|
|
|
400, |
|
|
|
|
"Unable to retrieve share id between Nextcloud group {} and Nextcloud directory {}".format( |
|
|
|
|
group_name, mapped_directory_path |
|
|
|
|
), |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
request = delete( |
|
|
|
|
"{}/ocs/v2.php/apps/files_sharing/api/v1/shares/{}".format( |
|
|
|
|
self.nextcloud_server, share_id |
|
|
|
@ -1803,7 +1788,7 @@ class WatchaRoomHandler(BaseHandler): |
|
|
|
|
) |
|
|
|
|
request.raise_for_status() |
|
|
|
|
|
|
|
|
|
async def get_room_list_to_send_NC_notification( |
|
|
|
|
async def get_room_list_to_send_nextcloud_notification( |
|
|
|
|
self, directory, limit_of_notification_propagation |
|
|
|
|
): |
|
|
|
|
rooms = [] |
|
|
|
|