webdav: change auth package to django-http-auth

This commit is contained in:
2020-02-24 15:18:23 -08:00
parent 370f149acf
commit c66827452d
4 changed files with 8 additions and 198 deletions

View File

@ -2,37 +2,18 @@ import datetime
import os import os
import shutil import shutil
from sys import getfilesystemencoding from sys import getfilesystemencoding
import logging import logging
from django.utils.decorators import method_decorator 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.acls import FullAcl
from djangodav.base.resources import BaseDavResource from djangodav.base.resources import BaseDavResource, MetaEtagMixIn
from djangodav.base.resources import MetaEtagMixIn
from djangodav.locks import DummyLock from djangodav.locks import DummyLock
from djangodav.utils import url_join from djangodav.utils import url_join
from djangodav.views import DavView from djangodav.views import DavView
# import lxml xml parser from django.utils.decorators import method_decorator
from lxml import etree from django_http_auth.decorators import http_basic_auth
# 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 .models import Catalog from .models import Catalog
@ -41,169 +22,17 @@ log = logging.getLogger(__name__)
fs_encoding = getfilesystemencoding() fs_encoding = getfilesystemencoding()
class ExampleView(APIView): @method_decorator(http_basic_auth, name='dispatch')
authentication_classes = [SessionAuthentication, BasicAuthentication] class AuthDavView(DavView):
permission_classes = [IsAuthenticated]
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): def __init__(self):
log.info(f"AuthDavView init") log.info(f"AuthDavView init")
super(DavView, self).__init__(resource_class=MarkupDavResource, lock_class=DummyLock, acl_class=FullAcl) 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): class MarkupDavResource(MetaEtagMixIn, BaseDavResource):
root = '/opt/imagebank/mkbeta/webdav' # TODO replace with settings var 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): def __str__(self):
return f"<MarkupDavResource {self.path}>" return f"<MarkupDavResource {self.path}>"
@ -271,7 +100,6 @@ class MarkupDavResource(MetaEtagMixIn, BaseDavResource):
def is_collection(self): def is_collection(self):
"""Return True if this resource is a directory (collection in WebDAV parlance).""" """Return True if this resource is a directory (collection in WebDAV parlance)."""
path = '/'.join(self.path) path = '/'.join(self.path)
# log.info(f"is_collection {self.path}")
if path == '': if path == '':
return True return True
@ -311,21 +139,6 @@ class MarkupDavResource(MetaEtagMixIn, BaseDavResource):
else: else:
return os.path.exists(self.get_abs_path()) 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): # def write(self, content, temp_file=None, range_start=None):
# raise NotImplementedError # raise NotImplementedError

View File

@ -119,7 +119,6 @@ INSTALLED_APPS = [
'lazysignup', 'lazysignup',
'webpack_loader', 'webpack_loader',
'djangodav', 'djangodav',
'rest_framework',
'procat2', 'procat2',
'dashboard', 'dashboard',
'products', 'products',

View File

@ -26,7 +26,7 @@ from products.views import search_products, all_models
from .forms import UserCreationForm from .forms import UserCreationForm
from .views import login_guest, lazy_convert_done from .views import login_guest, lazy_convert_done
from .resource import AuthDavView, ExampleView from .resource import AuthDavView
urlpatterns = [ urlpatterns = [
@ -55,9 +55,7 @@ urlpatterns = [
path('markup/', include('markup.urls')), path('markup/', include('markup.urls')),
#path('dav<path:path>', DavView.as_view(resource_class=MarkupDavResource, lock_class=DummyLock, acl_class=FullAcl)),
path('dav<path:path>', AuthDavView.as_view()), path('dav<path:path>', AuthDavView.as_view()),
path('example', ExampleView.as_view()),
] ]
if settings.DJDT: if settings.DJDT:

View File

@ -10,12 +10,12 @@ django-appconf==1.0.3
django-celery-results==1.1.2 django-celery-results==1.1.2
django-debug-toolbar==2.1 django-debug-toolbar==2.1
django-extensions==2.2.5 django-extensions==2.2.5
git+https://github.com/arcli/django-http-auth.git#egg=django-http-auth
django-lazysignup==2.0.0 django-lazysignup==2.0.0
django-settings-export==1.2.1 django-settings-export==1.2.1
django-user-accounts==2.1.0 django-user-accounts==2.1.0
django-webpack-loader==0.6.0 django-webpack-loader==0.6.0
git+https://github.com/abend/djangodav.git#egg=DjangoDav git+https://github.com/arcli/djangodav.git#egg=DjangoDav
djangorestframework==3.11.0
Dumper==1.2.0 Dumper==1.2.0
et-xmlfile==1.0.1 et-xmlfile==1.0.1
humanize==0.5.1 humanize==0.5.1