Watcha op572 delete nc group when folder is unshared (#99)

* feat: deletes groups on unsharing Nextcloud folder

* fix: await set_room_mapping_with_nextcloud_directory and deleted_room_mapping_with_nextcloud_directory functions

* feat: deletion of useless import

* Update synapse/handlers/room.py

Co-authored-by: c-cal <57274151+c-cal@users.noreply.github.com>

* Update synapse/handlers/room.py

Co-authored-by: c-cal <57274151+c-cal@users.noreply.github.com>

* feat: improve functions naming

* feat: remove keycloak serveur and realm value from Synapse config

* feat: get keycloak serveur and realm values from issuer

* Merge branch 'dev' into watcha-op572-delete-NC-group-when-folder-is-unshared

* Update synapse/handlers/room.py

Co-authored-by: c-cal <57274151+c-cal@users.noreply.github.com>

* Update synapse/handlers/room.py

Co-authored-by: c-cal <57274151+c-cal@users.noreply.github.com>

* fix: get keycloak attributes from Synapse config

Co-authored-by: c-cal <57274151+c-cal@users.noreply.github.com>
pull/103/head
KevICO 4 years ago committed by GitHub
parent 02c4d46a33
commit f9268c08ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 203
      synapse/handlers/room.py
  2. 20
      synapse/rest/client/v1/room.py
  3. 2
      synapse/rest/client/v1/watcha.py

@ -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 = []

@ -278,16 +278,26 @@ class RoomStateEventRestServlet(TransactionRestServlet):
400, "VectorSetting is only used for Nextcloud integration."
)
nextcloud_URL = content["nextcloudShare"]
nextcloud_url = content["nextcloudShare"]
requester_id = requester.user.to_string()
if not nextcloud_URL:
if not nextcloud_url:
await self.handlers.watcha_room_handler.delete_room_mapping_with_nextcloud_directory(
room_id, requester_id
room_id
)
else:
await self.handlers.watcha_room_handler.add_room_mapping_with_nextcloud_directory(
room_id, requester_id, nextcloud_URL
url_query = urlparse.parse_qs(urlparse.urlparse(nextcloud_url).query)
if "dir" not in url_query:
raise SynapseError(
400,
"The url doesn't point to a valid nextcloud directory path.",
)
nextcloud_directory_path = url_query["dir"][0]
await self.handlers.watcha_room_handler.update_nextcloud_mapping(
room_id, requester_id, nextcloud_directory_path
)
# +watcha
(

@ -125,7 +125,7 @@ class WatchaSendNextcloudActivityToWatchaRoomServlet(RestServlet):
continue
try:
rooms = await self.handler.watcha_room_handler.get_room_list_to_send_NC_notification(
rooms = await self.handler.watcha_room_handler.get_room_list_to_send_nextcloud_notification(
notification["directory"],
notification["limit_of_notification_propagation"],
)

Loading…
Cancel
Save