From 86859a0794c0ab3846e7102d5676b94dd3d6706a Mon Sep 17 00:00:00 2001 From: Stefan Hynek <stefan.hynek@uni-goettingen.de> Date: Thu, 21 Oct 2021 09:59:27 +0200 Subject: [PATCH] feat: implement basic textgrid DomainController and DAVProvider allow authentication with username only; deliver a RootCollection built from textgrid projects --- src/repdav/textgrid_dav_provider.py | 90 ++++++++++++++++++++++++ src/repdav/textgrid_domain_controller.py | 36 ++++++++++ 2 files changed, 126 insertions(+) create mode 100644 src/repdav/textgrid_dav_provider.py create mode 100644 src/repdav/textgrid_domain_controller.py diff --git a/src/repdav/textgrid_dav_provider.py b/src/repdav/textgrid_dav_provider.py new file mode 100644 index 0000000..893f2b3 --- /dev/null +++ b/src/repdav/textgrid_dav_provider.py @@ -0,0 +1,90 @@ +import logging + +from wsgidav.dav_provider import DAVCollection, DAVNonCollection, DAVProvider +from wsgidav.util import join_uri + +from .tgapi import TextgridAuth + +_logger = logging.getLogger(__name__) + + +class TextgridRootCollection(DAVCollection): + """top level collection that incorporates so called "projects" + + this is implemented as READ-ONLY as project may not be created with webDAV + """ + + def __init__(self, environ): + DAVCollection.__init__(self, "/", environ) + self._sid = environ["wsgidav.auth.user_name"] + _logger.debug("MY SID: %s", self._sid) + self._tg_auth = TextgridAuth() + self._projects = tuple(self._tg_auth.assigned_projects(self._sid)) + _logger.debug("MY PROJECTS: %s", self._projects) + + def get_member_names(self): + _logger.debug("Called get_member_names(self).") + return self._projects + + def get_member(self, name): + _logger.debug("Called get_member(self, name).") + if name in self._projects: + return TextgridCollection(join_uri(self.path, name), self.environ) + return None + + +class TextgridCollection(DAVCollection): + def __init__(self, path, environ): + DAVCollection.__init__(self, path, environ) + + def create_empty_resource(self, name): + pass + + def create_collection(self, name): + pass + + def get_member_names(self): + pass + + def delete(self): + pass + + def copy_move_single(self, dest_path, is_move): + pass + + +class TextgridResource(DAVNonCollection): + def __init__(self, path, environ): + DAVNonCollection.__init__(self, path, environ) + + def get_content_length(self): + pass + + def get_content_type(self): + pass + + def get_content(self): + pass + + def begin_write(self, content_type=None): + pass + + +# ============================================================================ +# TextgridResourceProvider +# ============================================================================ +class TextgridResourceProvider(DAVProvider): + """ + DAV provider that serves Textgrid resources + """ + + def __init__(self): + super(TextgridResourceProvider, self).__init__() + + def get_resource_inst(self, path, environ): + _logger.debug("PATH: %s", path) + _logger.debug("ENVIRON: %s", environ) + self._count_get_resource_inst += 1 + root = TextgridRootCollection(environ) + # an instance of _DAVResource (i.e. either DAVCollection or DAVNonCollection) + return root.resolve("", path) diff --git a/src/repdav/textgrid_domain_controller.py b/src/repdav/textgrid_domain_controller.py new file mode 100644 index 0000000..382a669 --- /dev/null +++ b/src/repdav/textgrid_domain_controller.py @@ -0,0 +1,36 @@ +import logging +from wsgidav.dc.base_dc import BaseDomainController +# see https://github.com/mar10/wsgidav/blob/master/wsgidav/dc/base_dc.py +# for the implementation of the BaseDomainController + +_logger = logging.getLogger(__name__) + + +# see https://github.com/mar10/wsgidav/blob/master/wsgidav/dc/simple_dc.py +# for the implementation of the SimpleDomainController +class TextgridDC(BaseDomainController): + def __init__(self, wsgidav_app, config): + super(TextgridDC, self).__init__(wsgidav_app, config) + return + + def __str__(self): + return "{}()".format(self.__class__.__name__) + + def get_domain_realm(self, path_info, environ): + """Resolve a relative url to the appropriate realm name.""" + realm = self._calc_realm_from_path_provider(path_info, environ) + _logger.debug("REALM: %s", realm) + return realm + + def require_authentication(self, realm, environ): + """Authentication with a valid session ID as the username is required.""" + return True + + def basic_auth_user(self, realm, user_name, password, environ): + """Authentication will always be granted in the first place because sid + validation is an "expensive" request. + """ + return True + + def supports_http_digest_auth(self): + return False -- GitLab