Beispiel #1
0
    def getIndirectUrlLockList(self, url, principal=None):
        """Return a list of valid lockDicts, that protect <path> directly or indirectly.
        
        If a principal is given, only locks owned by this principal are returned.
        Side effect: expired locks for this path and all parents are purged.
        """   
        url = normalizeLockRoot(url)
        lockList = []
        u = url 
        while u:
            ll = self.storage.getLockList(u, includeRoot=True, 
                                          includeChildren=False, 
                                          tokenOnly=False)
            for l in ll:
                if u != url and l["depth"] != "infinity":
                    continue  # We only consider parents with Depth: infinity
                # TODO: handle shared locks in some way?
#                if l["scope"] == "shared" and lockscope == "shared" and principal != l["principal"]:
#                    continue  # Only compatible with shared locks by other users 
                if principal is None or principal == l["principal"]:
                    lockList.append(l)
            u = util.getUriParent(u)
        return lockList
Beispiel #2
0
    def getIndirectUrlLockList(self, url, principal=None):
        """Return a list of valid lockDicts, that protect <path> directly or indirectly.
        
        If a principal is given, only locks owned by this principal are returned.
        Side effect: expired locks for this path and all parents are purged.
        """
        url = normalizeLockRoot(url)
        lockList = []
        u = url
        while u:
            ll = self.storage.getLockList(u,
                                          includeRoot=True,
                                          includeChildren=False,
                                          tokenOnly=False)
            for l in ll:
                if u != url and l["depth"] != "infinity":
                    continue  # We only consider parents with Depth: infinity
                # TODO: handle shared locks in some way?
#                if l["scope"] == "shared" and lockscope == "shared" and principal != l["principal"]:
#                    continue  # Only compatible with shared locks by other users
                if principal is None or principal == l["principal"]:
                    lockList.append(l)
            u = util.getUriParent(u)
        return lockList
Beispiel #3
0
    def _listDirectory(self, davres, environ, start_response):
        """
        @see: http://www.webdav.org/specs/rfc4918.html#rfc.section.9.4
        """
        assert davres.isCollection
        
        dirConfig = environ["wsgidav.config"].get("dir_browser", {})
        displaypath = urllib.unquote(davres.getHref())
        isReadOnly = environ["wsgidav.provider"].isReadOnly()

        trailer = dirConfig.get("response_trailer")
        if trailer:
            trailer = trailer.replace("${version}", 
                "<a href='https://github.com/mar10/wsgidav/'>WsgiDAV/%s</a>" % __version__)
            trailer = trailer.replace("${time}", util.getRfc1123Time())
        else:
            trailer = ("Seafile WebDAV Server, based on <a href='https://github.com/mar10/wsgidav/'>WsgiDAV/%s</a> - %s" 
                       % (__version__, util.getRfc1123Time()))

        
        html = []
        html.append("<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>");
        html.append("<html>")
        html.append("<head>")
        html.append("<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>")
        html.append("<meta name='generator' content='WsgiDAV %s'>" % __version__)
        html.append("<title>WsgiDAV - Index of %s </title>" % displaypath)
        
        html.append("<script type='text/javascript'>%s</script>" % PAGE_SCRIPT)
        html.append("<style type='text/css'>%s</style>" % PAGE_CSS)

        # Special CSS to enable MS Internet Explorer behaviour
        if dirConfig.get("ms_mount"):
            html.append("<style type='text/css'> A {behavior: url(#default#AnchorClick);} </style>")
        
        if dirConfig.get("ms_sharepoint_plugin"):
            html.append("<object id='winFirefoxPlugin' type='application/x-sharepoint' width='0' height='0' style=''visibility: hidden;'></object>")

        html.append("</head>")
        html.append("<body onload='onLoad()'>")

        # Title
        html.append("<h1>Index of %s</h1>" % displaypath)
        # Add DAV-Mount link and Web-Folder link
        links = []
        if dirConfig.get("davmount"):
            links.append("<a title='Open this folder in a WebDAV client.' href='%s?davmount'>Mount</a>" % util.makeCompleteUrl(environ))
        if dirConfig.get("ms_mount"):
            links.append("<a title='Open as Web Folder (requires Microsoft Internet Explorer)' href='' FOLDER='%s'>Open as Web Folder</a>" % util.makeCompleteUrl(environ))
#                html.append("<a href='' FOLDER='%ssetup.py'>Open setup.py as WebDAV</a>" % util.makeCompleteUrl(environ))
        if links:
            html.append("<p>%s</p>" % " &#8211; ".join(links))

        html.append("<hr>")
        # Listing
        html.append("<table onclick='return onClickTable(event)'>")

        html.append("<thead>")
        html.append("<tr><th>Name</th> <th>Type</th> <th class='right'>Size</th> <th class='right'>Last modified</th> </tr>")
        html.append("</thead>")
            
        html.append("<tbody>")
        if davres.path in ("", "/"):
            html.append("<tr><td>Top level share</td> <td></td> <td></td> <td></td> </tr>")
        else:
            parentUrl = util.getUriParent(davres.getHref())
            html.append("<tr><td><a href='" + parentUrl + "'>Parent Directory</a></td> <td></td> <td></td> <td></td> </tr>")

        # Ask collection for member info list
        dirInfoList = davres.getDirectoryInfo()

        if dirInfoList is None:
            # No pre-build info: traverse members
            dirInfoList = []
            childList = davres.getDescendants(depth="1", addSelf=False)
            for res in childList:
                di = res.getDisplayInfo()
                href = res.getHref()
                infoDict = {"href": href,
                            "class": "",
                            "displayName": escapeName(res.getDisplayName()),
                            "lastModified": res.getLastModified(),
                            "isCollection": res.isCollection,
                            "contentLength": res.getContentLength(),
                            "displayType": di.get("type"),
                            "displayTypeComment": di.get("typeComment"),
                            }

                if not isReadOnly and not res.isCollection:
                    ext = os.path.splitext(href)[1].lstrip(".").lower()
                    officeType = msOfficeExtToTypeMap.get(ext)
                    if officeType:
                        # print "OT", officeType
                        # print "OT", dirConfig
                        if dirConfig.get("ms_sharepoint_plugin"):
                            infoDict["class"] = "msoffice"
                        elif dirConfig.get("ms_sharepoint_urls"):
                            infoDict["href"] = "ms-%s:ofe|u|%s" % (officeType, href)

                dirInfoList.append(infoDict)
        # 
        for infoDict in dirInfoList:
            lastModified = infoDict.get("lastModified")
            if lastModified is None:
                infoDict["strModified"] = ""
            else:
                infoDict["strModified"] = util.getRfc1123Time(lastModified)
            
            infoDict["strSize"] = "-"
            if not infoDict.get("isCollection"):
                contentLength = infoDict.get("contentLength")
                if contentLength is not None:
                    infoDict["strSize"] = util.byteNumberString(contentLength)

            html.append("""\
            <tr><td><a href="%(href)s" class="%(class)s">%(displayName)s</a></td>
            <td>%(displayType)s</td>
            <td class='right'>%(strSize)s</td>
            <td class='right'>%(strModified)s</td></tr>""" % infoDict)
            
        html.append("</tbody>")
        html.append("</table>")

        html.append("<hr>") 

        if "http_authenticator.username" in environ:
            if environ.get("http_authenticator.username"):
                html.append("<p>Authenticated user: '******', realm: '%s'.</p>" 
                              % (environ.get("http_authenticator.username"),
                                 environ.get("http_authenticator.realm")))
#            else:
#                html.append("<p>Anonymous</p>")

        if trailer:
            html.append("<p class='trailer'>%s</p>" % trailer)

        html.append("</body></html>")

        body = "\n".join(html) 

        start_response("200 OK", [("Content-Type", "text/html"), 
                                  ("Content-Length", str(len(body))),
                                  ("Date", util.getRfc1123Time()),
                                  ])
        return [ body ] 
    def _listDirectory(self, davres, environ, start_response):
        """
        @see: http://www.webdav.org/specs/rfc4918.html#rfc.section.9.4
        """
        assert davres.isCollection

        dirConfig = environ["wsgidav.config"].get("dir_browser", {})
        displaypath = urllib.unquote(davres.getHref())

        trailer = dirConfig.get("response_trailer")
        if trailer:
            trailer = trailer.replace(
                "${version}",
                "<a href='http://wsgidav.googlecode.com/'>WsgiDAV/%s</a>" %
                __version__)
            trailer = trailer.replace("${time}", util.getRfc1123Time())
        else:
            trailer = (
                "<a href='http://wsgidav.googlecode.com/'>WsgiDAV/%s</a> - %s"
                % (__version__, util.getRfc1123Time()))

        html = []
        html.append(
            "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>"
        )
        html.append("<html>")
        html.append("<head>")
        html.append(
            "<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>"
        )
        html.append("<meta name='generator' content='WsgiDAV %s'>" %
                    __version__)
        html.append("<title>WsgiDAV - Index of %s </title>" % displaypath)

        html.append("""\
<style type="text/css">
    img { border: 0; padding: 0 2px; vertical-align: text-bottom; }
    th, td { padding: 2px 20px 2px 2px; }
    th { text-align: left; }
    th.right { text-align: right; }
    td  { font-family: monospace; vertical-align: bottom; white-space: pre; }
    td.right { text-align: right; }
    table { border: 0; }
    a.symlink { font-style: italic; }
    p.trailer { font-size: smaller; }
</style>""")
        # Special CSS to enable MS Internet Explorer behaviour
        if dirConfig.get("msmount"):
            html.append("""\
<style type="text/css">
    A {behavior: url(#default#AnchorClick);}
</style>""")

        html.append("</head><body>")

        # Title
        html.append("<h1>Index of %s</h1>" % displaypath)
        # Add DAV-Mount link and Web-Folder link
        links = []
        if dirConfig.get("davmount"):
            links.append(
                "<a title='Open this folder in a WebDAV client.' href='%s?davmount'>Mount</a>"
                % util.makeCompleteUrl(environ))
        if dirConfig.get("msmount"):
            links.append(
                "<a title='Open as Web Folder (requires Microsoft Internet Explorer)' href='' FOLDER='%s'>Open as Web Folder</a>"
                % util.makeCompleteUrl(environ))
#                html.append("<a href='' FOLDER='%ssetup.py'>Open setup.py as WebDAV</a>" % util.makeCompleteUrl(environ))
        if links:
            html.append("<p>%s</p>" % " &#8211; ".join(links))

        html.append("<hr>")
        # Listing
        html.append("<table>")

        html.append("<thead>")
        html.append(
            "<tr><th>Name</th> <th>Type</th> <th class='right'>Size</th> <th class='right'>Last modified</th> </tr>"
        )
        html.append("</thead>")

        html.append("<tbody>")
        if davres.path in ("", "/"):
            html.append(
                "<tr><td>Top level share</td> <td></td> <td></td> <td></td> </tr>"
            )
        else:
            parentUrl = util.getUriParent(davres.getHref())
            html.append(
                "<tr><td><a href='" + parentUrl +
                "'>Parent Directory</a></td> <td></td> <td></td> <td></td> </tr>"
            )

        # Ask collection for member info list
        dirInfoList = davres.getDirectoryInfo()

        if dirInfoList is None:
            # No pre-build info: traverse members
            dirInfoList = []
            childList = davres.getDescendants(depth="1", addSelf=False)
            for res in childList:
                di = res.getDisplayInfo()
                infoDict = {
                    "href": res.getHref(),
                    "displayName": res.getDisplayName(),
                    "lastModified": res.getLastModified(),
                    "isCollection": res.isCollection,
                    "contentLength": res.getContentLength(),
                    "displayType": di.get("type"),
                    "displayTypeComment": di.get("typeComment"),
                }
                dirInfoList.append(infoDict)
        #
        for infoDict in dirInfoList:
            lastModified = infoDict.get("lastModified")
            if lastModified is None:
                infoDict["strModified"] = ""
            else:
                infoDict["strModified"] = util.getRfc1123Time(lastModified)

            infoDict["strSize"] = "-"
            if not infoDict.get("isCollection"):
                contentLength = infoDict.get("contentLength")
                if contentLength is not None:
                    infoDict["strSize"] = util.byteNumberString(contentLength)

            html.append("""\
            <tr><td><a href="%(href)s">%(displayName)s</a></td>
            <td>%(displayType)s</td>
            <td class='right'>%(strSize)s</td>
            <td class='right'>%(strModified)s</td></tr>""" % infoDict)

        html.append("</tbody>")
        html.append("</table>")

        html.append("<hr>")

        if "http_authenticator.username" in environ:
            if environ.get("http_authenticator.username"):
                html.append("<p>Authenticated user: '******', realm: '%s'.</p>" %
                            (environ.get("http_authenticator.username"),
                             environ.get("http_authenticator.realm")))
#            else:
#                html.append("<p>Anonymous</p>")

        if trailer:
            html.append("<p class='trailer'>%s</p>" % trailer)
#            html.append("<p class='trailer'><a href='http://wsgidav.googlecode.com/'>WsgiDAV/%s</a> - %s</p>"
#                          % (__version__, util.getRfc1123Time()))

        html.append("</body></html>")

        body = "\n".join(html)

        start_response("200 OK", [
            ("Content-Type", "text/html"),
            ("Content-Length", str(len(body))),
            ("Date", util.getRfc1123Time()),
        ])
        return [body]
Beispiel #5
0
    def _listDirectory(self, davres, environ, start_response):
        """
        @see: http://www.webdav.org/specs/rfc4918.html#rfc.section.9.4
        """
        assert davres.isCollection
        
        dirConfig = environ["wsgidav.config"].get("dir_browser", {})
        displaypath = urllib.unquote(davres.getHref())

        trailer = dirConfig.get("response_trailer")
        if trailer:
            trailer = trailer.replace("${version}", 
                "<a href='http://wsgidav.googlecode.com/'>WsgiDAV/%s</a>" % __version__)
            trailer = trailer.replace("${time}", util.getRfc1123Time())
        else:
            trailer = ("<a href='http://wsgidav.googlecode.com/'>WsgiDAV/%s</a> - %s" 
                       % (__version__, util.getRfc1123Time()))

        
        html = []
        html.append("<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>");
        html.append("<html>")
        html.append("<head>")
        html.append("<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>")
        html.append("<meta name='generator' content='WsgiDAV %s'>" % __version__)
        html.append("<title>WsgiDAV - Index of %s </title>" % displaypath)
        
        html.append("""\
<style type="text/css">
    img { border: 0; padding: 0 2px; vertical-align: text-bottom; }
    th, td { padding: 2px 20px 2px 2px; }
    th { text-align: left; }
    th.right { text-align: right; }
    td  { font-family: monospace; vertical-align: bottom; white-space: pre; }
    td.right { text-align: right; }
    table { border: 0; }
    a.symlink { font-style: italic; }
    p.trailer { font-size: smaller; }
</style>""")        
        # Special CSS to enable MS Internet Explorer behaviour
        if dirConfig.get("msmount"):
            html.append("""\
<style type="text/css">
    A {behavior: url(#default#AnchorClick);}
</style>""")
        
        html.append("</head><body>")

        # Title
        html.append("<h1>Index of %s</h1>" % displaypath)
        # Add DAV-Mount link and Web-Folder link
        links = []
        if dirConfig.get("davmount"):
            links.append("<a title='Open this folder in a WebDAV client.' href='%s?davmount'>Mount</a>" % util.makeCompleteUrl(environ))
        if dirConfig.get("msmount"):
            links.append("<a title='Open as Web Folder (requires Microsoft Internet Explorer)' href='' FOLDER='%s'>Open as Web Folder</a>" % util.makeCompleteUrl(environ))
#                html.append("<a href='' FOLDER='%ssetup.py'>Open setup.py as WebDAV</a>" % util.makeCompleteUrl(environ))
        if links:
            html.append("<p>%s</p>" % " &#8211; ".join(links))

        html.append("<hr>")
        # Listing
        html.append("<table>")

        html.append("<thead>")
        html.append("<tr><th>Name</th> <th>Type</th> <th class='right'>Size</th> <th class='right'>Last modified</th> </tr>")
        html.append("</thead>")
            
        html.append("<tbody>")
        if davres.path in ("", "/"):
            html.append("<tr><td>Top level share</td> <td></td> <td></td> <td></td> </tr>")
        else:
            parentUrl = util.getUriParent(davres.getHref())
            html.append("<tr><td><a href='" + parentUrl + "'>Parent Directory</a></td> <td></td> <td></td> <td></td> </tr>")

        # Ask collection for member info list
        dirInfoList = davres.getDirectoryInfo()

        if dirInfoList is None:
            # No pre-build info: traverse members
            dirInfoList = []
            childList = davres.getDescendants(depth="1", addSelf=False)
            for res in childList:
                di = res.getDisplayInfo()
                infoDict = {"href": res.getHref(),
                            "displayName": res.getDisplayName(),
                            "lastModified": res.getLastModified(),
                            "isCollection": res.isCollection,
                            "contentLength": res.getContentLength(),
                            "displayType": di.get("type"),
                            "displayTypeComment": di.get("typeComment"),
                            }
                dirInfoList.append(infoDict)
        # 
        for infoDict in dirInfoList:
            lastModified = infoDict.get("lastModified")
            if lastModified is None:
                infoDict["strModified"] = ""
            else:
                infoDict["strModified"] = util.getRfc1123Time(lastModified)
            
            infoDict["strSize"] = "-"
            if not infoDict.get("isCollection"):
                contentLength = infoDict.get("contentLength")
                if contentLength is not None:
                    infoDict["strSize"] = util.byteNumberString(contentLength)

            html.append("""\
            <tr><td><a href="%(href)s">%(displayName)s</a></td>
            <td>%(displayType)s</td>
            <td class='right'>%(strSize)s</td>
            <td class='right'>%(strModified)s</td></tr>""" % infoDict)
            
        html.append("</tbody>")
        html.append("</table>")

        html.append("<hr>") 

        if "http_authenticator.username" in environ:
            if environ.get("http_authenticator.username"):
                html.append("<p>Authenticated user: '******', realm: '%s'.</p>" 
                              % (environ.get("http_authenticator.username"),
                                 environ.get("http_authenticator.realm")))
#            else:
#                html.append("<p>Anonymous</p>")

        if trailer:
            html.append("<p class='trailer'>%s</p>" % trailer)
#            html.append("<p class='trailer'><a href='http://wsgidav.googlecode.com/'>WsgiDAV/%s</a> - %s</p>" 
#                          % (__version__, util.getRfc1123Time()))

        html.append("</body></html>")

        body = "\n".join(html) 

        start_response("200 OK", [("Content-Type", "text/html"), 
                                  ("Content-Length", str(len(body))),
                                  ("Date", util.getRfc1123Time()),
                                  ])
        return [ body ] 
Beispiel #6
0
    def _listDirectory(self, davres, environ, start_response):
        """
        @see: http://www.webdav.org/specs/rfc4918.html#rfc.section.9.4
        """
        assert davres.isCollection
        
        dirConfig = environ["wsgidav.config"].get("dir_browser", {})
        displaypath = urllib.unquote(davres.getHref())
        isReadOnly = environ["wsgidav.provider"].isReadOnly()

        trailer = dirConfig.get("response_trailer")
        if trailer:
            trailer = trailer.replace("${version}", 
                "<a href='https://github.com/mar10/wsgidav/'>WsgiDAV/%s</a>" % __version__)
            trailer = trailer.replace("${time}", util.getRfc1123Time())
        else:
            trailer = ("<a href='https://github.com/mar10/wsgidav/'>WsgiDAV/%s</a> - %s" 
                       % (__version__, util.getRfc1123Time()))

        
        html = []
        html.append("<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>");
        html.append("<html>")
        html.append("<head>")
        html.append("<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>")
        html.append("<meta name='generator' content='WsgiDAV %s'>" % __version__)
        html.append("<title>WsgiDAV - Index of %s </title>" % displaypath)
        
        html.append("<script type='text/javascript'>%s</script>" % PAGE_SCRIPT)
        html.append("<style type='text/css'>%s</style>" % PAGE_CSS)

        # Special CSS to enable MS Internet Explorer behaviour
        if dirConfig.get("ms_mount"):
            html.append("<style type='text/css'> A {behavior: url(#default#AnchorClick);} </style>")
        
        if dirConfig.get("ms_sharepoint_plugin"):
            html.append("<object id='winFirefoxPlugin' type='application/x-sharepoint' width='0' height='0' style=''visibility: hidden;'></object>")

        html.append("</head>")
        html.append("<body onload='onLoad()'>")

        # Title
        html.append("<h1>Index of %s</h1>" % displaypath)
        # Add DAV-Mount link and Web-Folder link
        links = []
        if dirConfig.get("davmount"):
            links.append("<a title='Open this folder in a WebDAV client.' href='%s?davmount'>Mount</a>" % util.makeCompleteUrl(environ))
        if dirConfig.get("ms_mount"):
            links.append("<a title='Open as Web Folder (requires Microsoft Internet Explorer)' href='' FOLDER='%s'>Open as Web Folder</a>" % util.makeCompleteUrl(environ))
#                html.append("<a href='' FOLDER='%ssetup.py'>Open setup.py as WebDAV</a>" % util.makeCompleteUrl(environ))
        if links:
            html.append("<p>%s</p>" % " &#8211; ".join(links))

        html.append("<hr>")
        # Listing
        html.append("<table onclick='return onClickTable(event)'>")

        html.append("<thead>")
        html.append("<tr><th>Name</th> <th>Type</th> <th class='right'>Size</th> <th class='right'>Last modified</th> </tr>")
        html.append("</thead>")
            
        html.append("<tbody>")
        if davres.path in ("", "/"):
            html.append("<tr><td>Top level share</td> <td></td> <td></td> <td></td> </tr>")
        else:
            parentUrl = util.getUriParent(davres.getHref())
            html.append("<tr><td><a href='" + parentUrl + "'>Parent Directory</a></td> <td></td> <td></td> <td></td> </tr>")

        # Ask collection for member info list
        dirInfoList = davres.getDirectoryInfo()

        if dirInfoList is None:
            # No pre-build info: traverse members
            dirInfoList = []
            childList = davres.getDescendants(depth="1", addSelf=False)
            for res in childList:
                di = res.getDisplayInfo()
                href = res.getHref()
                infoDict = {"href": href,
                            "class": "",
                            "displayName": res.getDisplayName(),
                            "lastModified": res.getLastModified(),
                            "isCollection": res.isCollection,
                            "contentLength": res.getContentLength(),
                            "displayType": di.get("type"),
                            "displayTypeComment": di.get("typeComment"),
                            }

                if not isReadOnly and not res.isCollection:
                    ext = os.path.splitext(href)[1].lstrip(".").lower()
                    officeType = msOfficeExtToTypeMap.get(ext)
                    if officeType:
                        print "OT", officeType
                        print "OT", dirConfig
                        if dirConfig.get("ms_sharepoint_plugin"):
                            infoDict["class"] = "msoffice"
                        elif dirConfig.get("ms_sharepoint_urls"):
                            infoDict["href"] = "ms-%s:ofe|u|%s" % (officeType, href)

                dirInfoList.append(infoDict)
        # 
        for infoDict in dirInfoList:
            lastModified = infoDict.get("lastModified")
            if lastModified is None:
                infoDict["strModified"] = ""
            else:
                infoDict["strModified"] = util.getRfc1123Time(lastModified)
            
            infoDict["strSize"] = "-"
            if not infoDict.get("isCollection"):
                contentLength = infoDict.get("contentLength")
                if contentLength is not None:
                    infoDict["strSize"] = util.byteNumberString(contentLength)

            html.append("""\
            <tr><td><a href="%(href)s" class="%(class)s">%(displayName)s</a></td>
            <td>%(displayType)s</td>
            <td class='right'>%(strSize)s</td>
            <td class='right'>%(strModified)s</td></tr>""" % infoDict)
            
        html.append("</tbody>")
        html.append("</table>")

        html.append("<hr>") 

        if "http_authenticator.username" in environ:
            if environ.get("http_authenticator.username"):
                html.append("<p>Authenticated user: '******', realm: '%s'.</p>" 
                              % (environ.get("http_authenticator.username"),
                                 environ.get("http_authenticator.realm")))
#            else:
#                html.append("<p>Anonymous</p>")

        if trailer:
            html.append("<p class='trailer'>%s</p>" % trailer)

        html.append("</body></html>")

        body = "\n".join(html) 

        start_response("200 OK", [("Content-Type", "text/html"), 
                                  ("Content-Length", str(len(body))),
                                  ("Date", util.getRfc1123Time()),
                                  ])
        return [ body ] 
Beispiel #7
0
    def checkWritePermission(self, url, depth, tokenList, principal):
        """Check, if <principal> can modify <url>, otherwise raise HTTP_LOCKED.
        
        If modifying <url> is prevented by a lock, DAVError(HTTP_LOCKED) is 
        raised. An embedded DAVErrorCondition contains the conflicting locks. 

        <url> may be modified by <principal>, if it is not currently locked
        directly or indirectly (i.e. by a locked parent).
        For depth-infinity operations, <url> also must not have locked children. 

        It is not enough to check whether a lock is owned by <principal>, but 
        also the token must be passed with the request. Because <principal> may 
        run two different applications.  

        See http://www.webdav.org/specs/rfc4918.html#lock-model
            http://www.webdav.org/specs/rfc4918.html#rfc.section.7.4

        TODO: verify assumptions:
        - Parent locks WILL NOT be conflicting, if they are depth-0.
        - Exclusive child locks WILL be conflicting, even if they are owned by <principal>.
        
        @param url: URL that shall be modified, created, moved, or deleted
        @param depth: "0"|"infinity"
        @param tokenList: list of lock tokens, that the principal submitted in If: header
        @param principal: name of the principal requesting a lock 

        @return: None or raise error
        """
        assert depth in ("0", "infinity")
        _logger.debug("checkWritePermission(%s, %s, %s, %s)" %
                      (url, depth, tokenList, principal))

        # Error precondition to collect conflicting URLs
        errcond = DAVErrorCondition(PRECONDITION_CODE_LockConflict)

        self._lock.acquireRead()
        try:
            # Check url and all parents for conflicting locks
            u = url
            while u:
                ll = self.getUrlLockList(u)
                _logger.debug("  checking %s" % u)
                for l in ll:
                    _logger.debug("     l=%s" % lockString(l))
                    if u != url and l["depth"] != "infinity":
                        # We only consider parents with Depth: inifinity
                        continue
                    elif principal == l["principal"] and l[
                            "token"] in tokenList:
                        # User owns this lock
                        continue
                    else:
                        # Token is owned by principal, but not passed with lock list
                        _logger.debug(" -> DENIED due to locked parent %s" %
                                      lockString(l))
                        errcond.add_href(l["root"])
                u = util.getUriParent(u)

            if depth == "infinity":
                # Check child URLs for conflicting locks
                childLocks = self.storage.getLockList(url,
                                                      includeRoot=False,
                                                      includeChildren=True,
                                                      tokenOnly=False)

                for l in childLocks:
                    assert util.isChildUri(url, l["root"])
                    #                    if util.isChildUri(url, l["root"]):
                    _logger.debug(" -> DENIED due to locked child %s" %
                                  lockString(l))
                    errcond.add_href(l["root"])
        finally:
            self._lock.release()

        # If there were conflicts, raise HTTP_LOCKED for <url>, and pass
        # conflicting resource with 'no-conflicting-lock' precondition
        if len(errcond.hrefs) > 0:
            raise DAVError(HTTP_LOCKED, errcondition=errcond)
        return
Beispiel #8
0
    def _checkLockPermission(self, url, locktype, lockscope, lockdepth,
                             tokenList, principal):
        """Check, if <principal> can lock <url>, otherwise raise an error.
        
        If locking <url> would create a conflict, DAVError(HTTP_LOCKED) is 
        raised. An embedded DAVErrorCondition contains the conflicting resource. 

        @see http://www.webdav.org/specs/rfc4918.html#lock-model

        - Parent locks WILL NOT be conflicting, if they are depth-0.
        - Exclusive depth-infinity parent locks WILL be conflicting, even if 
          they are owned by <principal>.
        - Child locks WILL NOT be conflicting, if we request a depth-0 lock.
        - Exclusive child locks WILL be conflicting, even if they are owned by 
          <principal>. (7.7)
        - It is not enough to check whether a lock is owned by <principal>, but 
          also the token must be passed with the request. (Because <principal> 
          may run two different applications on his client.)
        - <principal> cannot lock-exclusive, if he holds a parent shared-lock.
          (This would only make sense, if he was the only shared-lock holder.)
        - TODO: litmus tries to acquire a shared lock on one resource twice 
          (locks: 27 'double_sharedlock') and fails, when we return HTTP_LOCKED. 
          So we allow multi shared locks on a resource even for the same 
          principal.
        
        @param url: URL that shall be locked
        @param locktype: "write"
        @param lockscope: "shared"|"exclusive"
        @param lockdepth: "0"|"infinity"
        @param tokenList: list of lock tokens, that the user submitted in If: header
        @param principal: name of the principal requesting a lock 

        @return: None (or raise)
        """
        assert locktype == "write"
        assert lockscope in ("shared", "exclusive")
        assert lockdepth in ("0", "infinity")

        _logger.debug("checkLockPermission(%s, %s, %s, %s)" %
                      (url, lockscope, lockdepth, principal))

        # Error precondition to collect conflicting URLs
        errcond = DAVErrorCondition(PRECONDITION_CODE_LockConflict)

        self._lock.acquireRead()
        try:
            # Check url and all parents for conflicting locks
            u = url
            while u:
                ll = self.getUrlLockList(u)
                for l in ll:
                    _logger.debug("    check parent %s, %s" %
                                  (u, lockString(l)))
                    if u != url and l["depth"] != "infinity":
                        # We only consider parents with Depth: infinity
                        continue
                    elif l["scope"] == "shared" and lockscope == "shared":
                        # Only compatible with shared locks (even by same principal)
                        continue
                    # Lock conflict
                    _logger.debug(" -> DENIED due to locked parent %s" %
                                  lockString(l))
                    errcond.add_href(l["root"])
                u = util.getUriParent(u)

            if lockdepth == "infinity":
                # Check child URLs for conflicting locks
                childLocks = self.storage.getLockList(url,
                                                      includeRoot=False,
                                                      includeChildren=True,
                                                      tokenOnly=False)

                for l in childLocks:
                    assert util.isChildUri(url, l["root"])
                    #                    if util.isChildUri(url, l["root"]):
                    _logger.debug(" -> DENIED due to locked child %s" %
                                  lockString(l))
                    errcond.add_href(l["root"])
        finally:
            self._lock.release()

        # If there were conflicts, raise HTTP_LOCKED for <url>, and pass
        # conflicting resource with 'no-conflicting-lock' precondition
        if len(errcond.hrefs) > 0:
            raise DAVError(HTTP_LOCKED, errcondition=errcond)
        return
    def checkWritePermission(self, url, depth, tokenList, principal):
        """Check, if <principal> can modify <url>, otherwise raise HTTP_LOCKED.
        
        If modifying <url> is prevented by a lock, DAVError(HTTP_LOCKED) is 
        raised. An embedded DAVErrorCondition contains the conflicting locks. 

        <url> may be modified by <principal>, if it is not currently locked
        directly or indirectly (i.e. by a locked parent).
        For depth-infinity operations, <url> also must not have locked children. 

        It is not enough to check whether a lock is owned by <principal>, but 
        also the token must be passed with the request. Because <principal> may 
        run two different applications.  

        See http://www.webdav.org/specs/rfc4918.html#lock-model
            http://www.webdav.org/specs/rfc4918.html#rfc.section.7.4

        TODO: verify assumptions:
        - Parent locks WILL NOT be conflicting, if they are depth-0.
        - Exclusive child locks WILL be conflicting, even if they are owned by <principal>.
        
        @param url: URL that shall be modified, created, moved, or deleted
        @param depth: "0"|"infinity"
        @param tokenList: list of lock tokens, that the principal submitted in If: header
        @param principal: name of the principal requesting a lock 

        @return: None or raise error
        """
        assert depth in ("0", "infinity")
        _logger.debug("checkWritePermission(%s, %s, %s, %s)" % (url, depth, tokenList, principal))

        # Error precondition to collect conflicting URLs
        errcond = DAVErrorCondition(PRECONDITION_CODE_LockConflict)

        self._lock.acquireRead()
        try:
            # Check url and all parents for conflicting locks
            u = url 
            while u:
                ll = self.getUrlLockList(u)
                _logger.debug("  checking %s" % u)
                for l in ll:
                    _logger.debug("     l=%s" % lockString(l))
                    if u != url and l["depth"] != "infinity":
                        # We only consider parents with Depth: inifinity
                        continue  
                    elif principal == l["principal"] and l["token"] in tokenList:
                        # User owns this lock 
                        continue  
                    else:
                        # Token is owned by principal, but not passed with lock list
                        _logger.debug(" -> DENIED due to locked parent %s" % lockString(l))
                        errcond.add_href(l["root"])
                u = util.getUriParent(u)
    
            if depth == "infinity":
                # Check child URLs for conflicting locks
                childLocks = self.storage.getLockList(url, 
                                                      includeRoot=False, 
                                                      includeChildren=True, 
                                                      tokenOnly=False)

                for l in childLocks:
                    assert util.isChildUri(url, l["root"])
#                    if util.isChildUri(url, l["root"]): 
                    _logger.debug(" -> DENIED due to locked child %s" % lockString(l))
                    errcond.add_href(l["root"])
        finally:
            self._lock.release()               

        # If there were conflicts, raise HTTP_LOCKED for <url>, and pass
        # conflicting resource with 'no-conflicting-lock' precondition 
        if len(errcond.hrefs) > 0:              
            raise DAVError(HTTP_LOCKED, errcondition=errcond)
        return
    def _checkLockPermission(self, url, locktype, lockscope, lockdepth, 
                             tokenList, principal):
        """Check, if <principal> can lock <url>, otherwise raise an error.
        
        If locking <url> would create a conflict, DAVError(HTTP_LOCKED) is 
        raised. An embedded DAVErrorCondition contains the conflicting resource. 

        @see http://www.webdav.org/specs/rfc4918.html#lock-model

        - Parent locks WILL NOT be conflicting, if they are depth-0.
        - Exclusive depth-infinity parent locks WILL be conflicting, even if 
          they are owned by <principal>.
        - Child locks WILL NOT be conflicting, if we request a depth-0 lock.
        - Exclusive child locks WILL be conflicting, even if they are owned by 
          <principal>. (7.7)
        - It is not enough to check whether a lock is owned by <principal>, but 
          also the token must be passed with the request. (Because <principal> 
          may run two different applications on his client.)
        - <principal> cannot lock-exclusive, if he holds a parent shared-lock.
          (This would only make sense, if he was the only shared-lock holder.)
        - TODO: litmus tries to acquire a shared lock on one resource twice 
          (locks: 27 'double_sharedlock') and fails, when we return HTTP_LOCKED. 
          So we allow multi shared locks on a resource even for the same 
          principal.
        
        @param url: URL that shall be locked
        @param locktype: "write"
        @param lockscope: "shared"|"exclusive"
        @param lockdepth: "0"|"infinity"
        @param tokenList: list of lock tokens, that the user submitted in If: header
        @param principal: name of the principal requesting a lock 

        @return: None (or raise)
        """
        assert locktype == "write"
        assert lockscope in ("shared", "exclusive")
        assert lockdepth in ("0", "infinity")

        _logger.debug("checkLockPermission(%s, %s, %s, %s)" % (url, lockscope, lockdepth, principal))

        # Error precondition to collect conflicting URLs
        errcond = DAVErrorCondition(PRECONDITION_CODE_LockConflict)
        
        self._lock.acquireRead()
        try:
            # Check url and all parents for conflicting locks
            u = url 
            while u:
                ll = self.getUrlLockList(u)
                for l in ll:
                    _logger.debug("    check parent %s, %s" % (u, lockString(l)))
                    if u != url and l["depth"] != "infinity":
                        # We only consider parents with Depth: infinity
                        continue
                    elif l["scope"] == "shared" and lockscope == "shared":
                        # Only compatible with shared locks (even by same principal)
                        continue   
                    # Lock conflict
                    _logger.debug(" -> DENIED due to locked parent %s" % lockString(l))
                    errcond.add_href(l["root"])
                u = util.getUriParent(u)
    
            if lockdepth == "infinity":
                # Check child URLs for conflicting locks
                childLocks = self.storage.getLockList(url, 
                                                      includeRoot=False, 
                                                      includeChildren=True, 
                                                      tokenOnly=False)

                for l in childLocks:
                    assert util.isChildUri(url, l["root"])
#                    if util.isChildUri(url, l["root"]): 
                    _logger.debug(" -> DENIED due to locked child %s" % lockString(l))
                    errcond.add_href(l["root"])
        finally:
            self._lock.release()

        # If there were conflicts, raise HTTP_LOCKED for <url>, and pass
        # conflicting resource with 'no-conflicting-lock' precondition 
        if len(errcond.hrefs) > 0:              
            raise DAVError(HTTP_LOCKED, errcondition=errcond)
        return