Languages

Previous versions

1.2
1.1

Source code for openPLM.apps.webdav.views

"""
openPLM.webdav application
Copyright 2012 LinObject

Modified version of webdav/views.py from:
    django-webdav is a small WebDAV implementation for Django.
    Copyright 2012 Peter Gebauer

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""
import logging
import base64

from django.conf import settings
from django.http import HttpResponse, HttpResponseForbidden, HttpResponseNotFound
from django.contrib.auth import authenticate, login
from django.views.decorators.csrf import csrf_exempt

from openPLM.apps.webdav.webdav_handler import WebDavHandler
from openPLM.apps.webdav.webdav_handler import WebDavHandlerException
from openPLM.apps.webdav.backends.openplm import OpenPLMBackend
from openPLM.apps.webdav.acl import WebDavPrivilegeException

from openPLM.plmapp.views.base import secure_required
from openPLM.plmapp.exceptions import ControllerError

logger = logging.getLogger("webdav")

@csrf_exempt
[docs]def not_found(request, *args, **kwargs): return HttpResponseNotFound("Not found")
[docs]def basic_auth(request): """ Authenticates the user with a basic http authentication and returns the user. Returns None if the user can not be authenticated. """ if 'HTTP_AUTHORIZATION' in request.META: auth = request.META['HTTP_AUTHORIZATION'].split() if len(auth) == 2: # only basic auth is supported if auth[0].lower() == "basic": uname, passwd = base64.b64decode(auth[1]).split(':') user = authenticate(username=uname, password=passwd) if user is not None and user.is_active: login(request, user) request.user = user return user return None
@csrf_exempt @secure_required
[docs]def openplm_webdav(request, local_path): """ View that handles all webdav requests. """ if request.user.is_anonymous(): user = basic_auth(request) else: user = request.user if user: if user.profile.restricted: return HttpResponseForbidden("403 Forbidden", None, 403, "text/plain") backend = OpenPLMBackend(user) handler = WebDavHandler(local_path, backend) try: return handler.handle_method(request) except WebDavHandlerException, wdhe: logger.error("handlers failed to handle request; %s"%wdhe) return HttpResponse("400 Bad Request", None, 400, "text/plain") except (WebDavPrivilegeException, ControllerError), wpe: logger.info("user '%s' failed privileges; %s" %(request.user.username, wpe)) return HttpResponse("403 Forbidden", None, 403, "text/plain") except NotImplementedError, nie: logger.warning("no implementation; %s"%nie) return HttpResponse("501 Not Implemented", None, 501, "text/plain") # failed authentication results in 401 response = HttpResponse() response.status_code = 401 response['WWW-Authenticate'] = 'Basic realm="openPLM-dav"' return response
if "django_digest" in settings.INSTALLED_APPS: # pip install "hg+https://bitbucket.org/scjody/django-digest" python_digest from django_digest import HttpDigestAuthenticator import python_digest from hashlib import md5 def calc_ha2_rspauth(uri): return md5(":" + uri).hexdigest() def calc_hash(**parameters): hash_text = "%(ha1)s:%(nonce)s:%(nc)s:%(cnonce)s:auth:%(ha2)s" % parameters return md5(hash_text).hexdigest() def calc_rspauth(parameters): ha2_rspauth = calc_ha2_rspauth(parameters["uri"]) return calc_hash(ha2=ha2_rspauth, **parameters) def _httpdigest(f): @csrf_exempt def wrapper(request, *args, **kwargs): authenticator = HttpDigestAuthenticator() if not authenticator.authenticate(request): return authenticator.build_challenge_response() response = f(request, *args, **kwargs) if hasattr(response, 'status_code') and response.status_code in [401, 403]: return authenticator.build_challenge_response() if 200 <= response.status_code < 300: digest = python_digest.parse_digest_credentials( request.META['HTTP_AUTHORIZATION']) nc = "%08d" % digest.nc partial_digest = authenticator._account_storage.get_partial_digest(digest.username) parameters = { "username": request.user.username, "ha1": partial_digest, "nonce": digest.nonce, "cnonce": digest.cnonce, "method":digest.algorithm, "uri": digest.uri, "nc": nc, } rspauth = calc_rspauth(parameters) info = 'rspauth="%s",cnonce="%s",nc=%s,qop=%s' % (rspauth, digest.cnonce, nc, digest.qop) response["Authentication-Info"] = info return response return wrapper openplm_webdav = _httpdigest(openplm_webdav)