diff options
author | Daniel Calviño Sánchez <danxuliu@gmail.com> | 2023-02-05 05:16:55 +0100 |
---|---|---|
committer | Daniel Calviño Sánchez <danxuliu@gmail.com> | 2023-02-14 10:37:18 +0100 |
commit | c3e7b1491217fcd8a2c9745739daa57e69e7b3b5 (patch) | |
tree | ba93ce06334f517727ad95a89ab7e157d2f2e577 /recording | |
parent | ca2195396b2064206f85609763fbe0fd35156187 (diff) |
Add module to send requests to the Nextcloud server
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Diffstat (limited to 'recording')
-rw-r--r-- | recording/pyproject.toml | 1 | ||||
-rw-r--r-- | recording/src/nextcloud/talk/recording/BackendNotifier.py | 116 |
2 files changed, 117 insertions, 0 deletions
diff --git a/recording/pyproject.toml b/recording/pyproject.toml index dc8f1f0fa..9ff86c232 100644 --- a/recording/pyproject.toml +++ b/recording/pyproject.toml @@ -7,6 +7,7 @@ classifiers = [ ] dependencies = [ "selenium>=4.6.0", + "urllib3", "websocket-client", ] dynamic = ["version"] diff --git a/recording/src/nextcloud/talk/recording/BackendNotifier.py b/recording/src/nextcloud/talk/recording/BackendNotifier.py new file mode 100644 index 000000000..8177c8253 --- /dev/null +++ b/recording/src/nextcloud/talk/recording/BackendNotifier.py @@ -0,0 +1,116 @@ +# +# @copyright Copyright (c) 2023, Daniel Calviño Sánchez (danxuliu@gmail.com) +# +# @license GNU AGPL version 3 or any later version +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +""" +Module to send requests to the Nextcloud server. +""" + +import hashlib +import hmac +import logging +import os +import ssl +from secrets import token_urlsafe +from urllib.request import Request, urlopen +from urllib3 import encode_multipart_formdata + +from .Config import config + +logger = logging.getLogger(__name__) + +def getRandomAndChecksum(backend, data): + """ + Returns a random string and the checksum of the given data with that random. + + :param backend: the backend to send the data to. + :param data: the data, as bytes. + """ + secret = config.getBackendSecret(backend).encode() + random = token_urlsafe(64) + hmacValue = hmac.new(secret, random.encode() + data, hashlib.sha256) + + return random, hmacValue.hexdigest() + +def doRequest(backend, request, retries=3): + """ + Send the request to the backend. + + SSL verification will be skipped if configured. + + :param backend: the backend to send the request to. + :param request: the request to send. + :param retries: the number of times to retry in case of failure. + """ + context = None + + if config.getBackendSkipVerify(backend): + context = ssl.create_default_context() + context.check_hostname = False + context.verify_mode = ssl.CERT_NONE + + try: + urlopen(request, context=context) + except Exception as exception: + if retries > 1: + logger.exception(f"Failed to send message to backend, {retries} retries left!") + doRequest(backend, request, retries - 1) + else: + logger.exception(f"Failed to send message to backend, giving up!") + raise + +def uploadRecording(backend, token, fileName, owner): + """ + Upload the recording specified by fileName. + + The name of the uploaded file is the basename of the original file. + + :param backend: the backend to upload the file to. + :param token: the token of the conversation that was recorded. + :param fileName: the recording file name. + :param owner: the owner of the uploaded file. + """ + + logger.info(f"Upload recording {fileName} to {backend} in {token} as {owner}") + + url = backend + '/ocs/v2.php/apps/spreed/api/v1/recording/' + token + '/store' + + fileContents = None + with open(fileName, 'rb') as file: + fileContents = file.read() + + # Plain values become arguments, while tuples become files; the body used to + # calculate the checksum is empty. + data = { + 'owner': owner, + 'file': (os.path.basename(fileName), fileContents), + } + data, contentType = encode_multipart_formdata(data) + + random, checksum = getRandomAndChecksum(backend, token.encode()) + + headers = { + 'Content-Type': contentType, + 'OCS-ApiRequest': 'true', + 'Talk-Recording-Random': random, + 'Talk-Recording-Checksum': checksum, + } + + uploadRequest = Request(url, data, headers) + + doRequest(backend, uploadRequest) |