From c66827452d02110460b130c69173cb1f00d0d457 Mon Sep 17 00:00:00 2001 From: Seth Ladygo Date: Mon, 24 Feb 2020 15:18:23 -0800 Subject: [PATCH] webdav: change auth package to django-http-auth --- procat2/resource.py | 197 ++------------------------------------------ procat2/settings.py | 1 - procat2/urls.py | 4 +- requirements.txt | 4 +- 4 files changed, 8 insertions(+), 198 deletions(-) diff --git a/procat2/resource.py b/procat2/resource.py index c850386..61be048 100644 --- a/procat2/resource.py +++ b/procat2/resource.py @@ -2,37 +2,18 @@ import datetime import os import shutil from sys import getfilesystemencoding - import logging from django.utils.decorators import method_decorator -from django.views.decorators.csrf import csrf_exempt -from django.core.exceptions import PermissionDenied, ValidationError -from djangodav.utils import WEBDAV_NSMAP, D, url_join, get_property_tag_list, rfc1123_date, rfc5987_content_disposition -from django.utils.timezone import now - -from djangodav.responses import HttpResponsePreconditionFailed, HttpResponseCreated, HttpResponseNoContent, \ - HttpResponseConflict, HttpResponseMediatypeNotSupported, HttpResponseBadGateway, HttpResponseMultiStatus, \ - HttpResponseLocked, ResponseException - -#from djangodav.fs.resources import DummyFSDAVResource from djangodav.acls import FullAcl -from djangodav.base.resources import BaseDavResource -from djangodav.base.resources import MetaEtagMixIn +from djangodav.base.resources import BaseDavResource, MetaEtagMixIn from djangodav.locks import DummyLock from djangodav.utils import url_join from djangodav.views import DavView -# import lxml xml parser -from lxml import etree -# use defusedxmls parse function -from defusedxml.lxml import parse - -from rest_framework.authentication import SessionAuthentication, BasicAuthentication -from rest_framework.permissions import IsAuthenticated -from rest_framework.response import Response -from rest_framework.views import APIView +from django.utils.decorators import method_decorator +from django_http_auth.decorators import http_basic_auth from .models import Catalog @@ -41,169 +22,17 @@ log = logging.getLogger(__name__) fs_encoding = getfilesystemencoding() -class ExampleView(APIView): - authentication_classes = [SessionAuthentication, BasicAuthentication] - permission_classes = [IsAuthenticated] +@method_decorator(http_basic_auth, name='dispatch') +class AuthDavView(DavView): - def get(self, request, format=None): - content = { - 'user': str(request.user), # `django.contrib.auth.User` instance. - 'auth': str(request.auth), # None - } - return Response(content) - - -class AuthDavView(DavView, APIView): - authentication_classes = [BasicAuthentication] - #authentication_classes = [SessionAuthentication, BasicAuthentication] - permission_classes = [IsAuthenticated] - auth_user = None - path = "" - def __init__(self): log.info(f"AuthDavView init") super(DavView, self).__init__(resource_class=MarkupDavResource, lock_class=DummyLock, acl_class=FullAcl) - # def get(self, request, format=None): - def get(self, request, head=False, *args, **kwargs): - # content = { - # 'user': str(request.user), # `django.contrib.auth.User` instance. - # 'auth': str(request.auth), # None - # } - # return Response(content) - self.auth_user = request.user - log.info(f'AuthDavView GET auth user: {request.user}') - path = "" - return super(DavView, self).get(request, path, head=False, *args, **kwargs) - - def dispatch(self, request, path, *args, **kwargs): - log.info(f'AuthDavView dispatch 0') - if path: - self.path = path - self.base_url = request.META['PATH_INFO'][:-len(self.path)] - else: - self.path = '/' - self.base_url = request.META['PATH_INFO'] - - # log.info(f'AuthDavView dispatch 1') - # super(APIView, self).dispatch(request, *args, **kwargs) - # log.info(f'AuthDavView dispatch 2') - # super(DavView, self).dispatch(request, *args, **kwargs) - # log.info(f'AuthDavView dispatch 3') - - # FROM APIView - self.args = args - self.kwargs = kwargs - request = self.initialize_request(request, *args, **kwargs) - self.request = request - self.headers = self.default_response_headers # deprecate? - - try: - self.initial(request, *args, **kwargs) - - # TODO HERE? - - meta = request.META.get - self.xbody = kwargs['xbody'] = None - if (request.method.lower() != 'put' - and "/xml" in meta('CONTENT_TYPE', '') - and meta('CONTENT_LENGTH', 0) != '' - and int(meta('CONTENT_LENGTH', 0)) > 0): - - # parse XML using defusedxmls parse function - self.xbody = kwargs['xbody'] = etree.XPathDocumentEvaluator( - parse(request, etree.XMLParser(ns_clean=True, resolve_entities=True)), - namespaces=WEBDAV_NSMAP - ) - - if request.method.upper() in self._allowed_methods(): - handler = getattr(self, request.method.lower(), self.http_method_not_allowed) - else: - handler = self.http_method_not_allowed - #try: - log.info(f"AuthDavView DISPATCH {handler} for {path}") - resp = handler(request, self.path, *args, **kwargs) - except ResponseException as e: - print(e) - resp = e.response - except PermissionDenied as pe: - print(pe) - resp = HttpResponseForbidden() - except ValidationError as ve: - print(ve) - resp = HttpResponseBadRequest() - except Exception as exc: - resp = self.handle_exception(exc) - self.response = self.finalize_response(request, resp, *args, **kwargs) - return self.response - - if not 'Allow' in resp: - methods = self._allowed_methods() - if methods: - resp['Allow'] = ", ".join(methods) - if not 'Date' in resp: - resp['Date'] = rfc1123_date(now()) - if self.server_header: - resp['Server'] = self.server_header - return resp - - - # TODO END HERE - - # Get the appropriate handler method - # if request.method.lower() in self.http_method_names: - # handler = getattr(self, request.method.lower(), - # self.http_method_not_allowed) - # else: - # handler = self.http_method_not_allowed - - # response = handler(request, *args, **kwargs) - - # except Exception as exc: - # response = self.handle_exception(exc) - - # self.response = self.finalize_response(request, response, *args, **kwargs) - # return self.response - - - def options(self, request, path, *args, **kwargs): - """ - Handler method for HTTP 'OPTIONS' request. - """ - log.info('AuthDavView OPTIONS') - # FROM APIView - # if self.metadata_class is None: - # return self.http_method_not_allowed(request, *args, **kwargs) - # data = self.metadata_class().determine_metadata(request, self) - # return Response(data, status=status.HTTP_200_OK) - - # FROM DavView - if not self.has_access(self.resource, 'read'): - return self.no_access() - response = self.build_xml_response() - response['DAV'] = '1,2' - response['Content-Length'] = '0' - if self.path in ('/', '*'): - return response - response['Allow'] = ", ".join(self._allowed_methods()) - if self.resource.exists and self.resource.is_object: - response['Accept-Ranges'] = 'bytes' - return response - - # @method_decorator(csrf_exempt) - # def dispatch(self, request, path, *args, **kwargs): - # self.auth_user = request.user - # log.info(f'auth user: {request.user}') - # return super().dispatch(request, path, *args, **kwargs) - class MarkupDavResource(MetaEtagMixIn, BaseDavResource): root = '/opt/imagebank/mkbeta/webdav' # TODO replace with settings var - def __init__(self, path): - log.info(f"MarkupDavResource INIT {path}") - super().__init__(path) - def __str__(self): return f"" @@ -271,7 +100,6 @@ class MarkupDavResource(MetaEtagMixIn, BaseDavResource): def is_collection(self): """Return True if this resource is a directory (collection in WebDAV parlance).""" path = '/'.join(self.path) - # log.info(f"is_collection {self.path}") if path == '': return True @@ -311,21 +139,6 @@ class MarkupDavResource(MetaEtagMixIn, BaseDavResource): else: return os.path.exists(self.get_abs_path()) - # def get_children(self): - # """Return an iterator of all direct children of this resource.""" - # # make sure the current object is a directory - # path = self.get_abs_path() - # log.info(f"get_children {path}") - # if os.path.isdir(path): - # for child in os.listdir(path): - # try: - # is_unicode = isinstance(child, str) - # except NameError: # Python 3 fix - # is_unicode = isinstance(child, str) - # if not is_unicode: - # child = child.decode(fs_encoding) - # yield self.clone(url_join(*(self.path + [child]))) - # def write(self, content, temp_file=None, range_start=None): # raise NotImplementedError diff --git a/procat2/settings.py b/procat2/settings.py index fb0ee68..aab03e7 100644 --- a/procat2/settings.py +++ b/procat2/settings.py @@ -119,7 +119,6 @@ INSTALLED_APPS = [ 'lazysignup', 'webpack_loader', 'djangodav', - 'rest_framework', 'procat2', 'dashboard', 'products', diff --git a/procat2/urls.py b/procat2/urls.py index c546eb7..4945479 100644 --- a/procat2/urls.py +++ b/procat2/urls.py @@ -26,7 +26,7 @@ from products.views import search_products, all_models from .forms import UserCreationForm from .views import login_guest, lazy_convert_done -from .resource import AuthDavView, ExampleView +from .resource import AuthDavView urlpatterns = [ @@ -55,9 +55,7 @@ urlpatterns = [ path('markup/', include('markup.urls')), - #path('dav', DavView.as_view(resource_class=MarkupDavResource, lock_class=DummyLock, acl_class=FullAcl)), path('dav', AuthDavView.as_view()), - path('example', ExampleView.as_view()), ] if settings.DJDT: diff --git a/requirements.txt b/requirements.txt index 4d17982..079282b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,12 +10,12 @@ django-appconf==1.0.3 django-celery-results==1.1.2 django-debug-toolbar==2.1 django-extensions==2.2.5 +git+https://github.com/arcli/django-http-auth.git#egg=django-http-auth django-lazysignup==2.0.0 django-settings-export==1.2.1 django-user-accounts==2.1.0 django-webpack-loader==0.6.0 -git+https://github.com/abend/djangodav.git#egg=DjangoDav -djangorestframework==3.11.0 +git+https://github.com/arcli/djangodav.git#egg=DjangoDav Dumper==1.2.0 et-xmlfile==1.0.1 humanize==0.5.1