Tests for simple WebDAV operations
==================================

ShellExServer makes some changes to the default WebDAV behavior in
Zope/Plone. Mainly, it changes it so the following permissions require
at least 'Authenticated' role:

- WebDAV Access
- WebDAV Lock
- WebDAV Unlock

Create a Document object as index_html on the portal root:

  >>> from Testing.ZopeTestCase import user_name, user_password
  >>> self.setRoles(['Manager'])
  >>> _ = self.portal.invokeFactory('Document', 'index_html')

Verify current workflow state:

  >>> from Products.CMFCore.utils import getToolByName
  >>> wtool = getToolByName(self.portal, 'portal_workflow')
  >>> def state(obj=self.portal.index_html):
  ...   return wtool.getInfoFor(obj, 'review_state')
  >>> def do_action(action, obj=self.portal.index_html):
  ...   return wtool.doActionFor(obj, action)
  >>> print state()
  visible

Check that an Anonymous user can't do a PROPFIND:

  >>> print http(r"""
  ... PROPFIND /plone/index_html HTTP/1.1
  ... Content-Type: text/xml; charset="utf-8"
  ... Depth: 0
  ...
  ... <?xml version="1.0" encoding="utf-8"?><DAV:propfind xmlns:DAV="DAV:"><DAV:prop><displayname/><DAV:/></DAV:prop></DAV:propfind>""")
  HTTP/1.1 401 Unauthorized
  ...

Check that Anonymous can't lock:

  >>> print http(r"""
  ... LOCK /plone/index_html HTTP/1.1
  ... Content-Type: text/xml; charset="utf-8"
  ...
  ... <?xml version="1.0" encoding="utf-8"?>
  ... <DAV:lockinfo xmlns:DAV="DAV:">
  ... <DAV:lockscope><DAV:exclusive/></DAV:lockscope>
  ... <DAV:locktype><DAV:write/></DAV:locktype>
  ... </DAV:lockinfo>""")
  HTTP/1.1 401 Unauthorized
  ...


Workflow Permissions
--------------------

Now for each workflow state, we are going to verify that the user can
access or not and that he can lock or not.

Visible State
~~~~~~~~~~~~~

  >>> print state()
  visible

Check that an Authenticated user can do a PROPFIND:

  >>> print http(r"""
  ... PROPFIND /plone/index_html HTTP/1.1
  ... Content-Type: text/xml; charset="utf-8"
  ... Authorization: Basic %s:%s
  ... Depth: 0
  ...
  ... <?xml version="1.0" encoding="utf-8"?>
  ...    <DAV:propfind xmlns:DAV="DAV:"
  ...      xmlns:zope="http://zope.org/propsets/default">
  ...      <DAV:prop><zope:title/></DAV:prop>
  ...    </DAV:propfind>""" % (user_name, user_password))
  HTTP/1.1 207 Multi-Status
  ...

Check that an Authenticated user can LOCK:

  >>> self.portal.index_html.wl_clearLocks()
  >>> print http(r"""
  ... LOCK /plone/index_html HTTP/1.1
  ... Content-Type: text/xml; charset="utf-8"
  ... Depth: 0
  ... Authorization: Basic %s:%s
  ...
  ... <?xml version="1.0" encoding="utf-8"?>
  ... <DAV:lockinfo xmlns:DAV="DAV:">
  ... <DAV:lockscope><DAV:exclusive/></DAV:lockscope>
  ... <DAV:locktype><DAV:write/></DAV:locktype>
  ... </DAV:lockinfo>""" % (user_name, user_password))
  HTTP/1.1 200 OK
  ...
  Lock-Token: ...

Pending State
~~~~~~~~~~~~~

  >>> print state()
  visible

  >>> do_action('submit')

  >>> print state()
  pending

Check that an Authenticated user can do a PROPFIND:

  >>> from Testing.ZopeTestCase import user_name, user_password
  >>> print http(r"""
  ... PROPFIND /plone/index_html HTTP/1.1
  ... Content-Type: text/xml; charset="utf-8"
  ... Authorization: Basic %s:%s
  ... Depth: 0
  ...
  ... <?xml version="1.0" encoding="utf-8"?>
  ...    <DAV:propfind xmlns:DAV="DAV:">
  ...      <DAV:prop><displayname/></DAV:prop>
  ...    </DAV:propfind>""" % (user_name, user_password))
  HTTP/1.1 207 Multi-Status
  ...

Check that an Authenticated user can LOCK:

  >>> self.portal.index_html.wl_clearLocks()
  >>> print http(r"""
  ... LOCK /plone/index_html HTTP/1.1
  ... Content-Type: text/xml; charset="utf-8"
  ... Depth: 0
  ... Authorization: Basic %s:%s
  ...
  ... <?xml version="1.0" encoding="utf-8"?>
  ... <DAV:lockinfo xmlns:DAV="DAV:">
  ... <DAV:lockscope><DAV:exclusive/></DAV:lockscope>
  ... <DAV:locktype><DAV:write/></DAV:locktype>
  ... </DAV:lockinfo>""" % (user_name, user_password))
  HTTP/1.1 200 OK
  ...
  Lock-Token: ...

Published State
~~~~~~~~~~~~~~~

  >>> print state()
  pending

  >>> do_action('publish')

  >>> print state()
  published

Check that an Authenticated user can do a PROPFIND:

  >>> from Testing.ZopeTestCase import user_name, user_password
  >>> print http(r"""
  ... PROPFIND /plone/index_html HTTP/1.1
  ... Content-Type: text/xml; charset="utf-8"
  ... Authorization: Basic %s:%s
  ... Depth: 0
  ...
  ... <?xml version="1.0" encoding="utf-8"?>
  ...    <DAV:propfind xmlns:DAV="DAV:">
  ...      <DAV:prop><displayname/></DAV:prop>
  ...    </DAV:propfind>""" % (user_name, user_password))
  HTTP/1.1 207 Multi-Status
  ...

Check that an Authenticated user can LOCK:

  >>> self.portal.index_html.wl_clearLocks()
  >>> print http(r"""
  ... LOCK /plone/index_html HTTP/1.1
  ... Content-Type: text/xml; charset="utf-8"
  ... Depth: 0
  ... Authorization: Basic %s:%s
  ...
  ... <?xml version="1.0" encoding="utf-8"?>
  ... <DAV:lockinfo xmlns:DAV="DAV:">
  ... <DAV:lockscope><DAV:exclusive/></DAV:lockscope>
  ... <DAV:locktype><DAV:write/></DAV:locktype>
  ... </DAV:lockinfo>""" % (user_name, user_password))
  HTTP/1.1 200 OK
  ...
  Lock-Token: ...

Private State
~~~~~~~~~~~~~

  >>> print state()
  published

  >>> do_action('retract')

  >>> print state()
  visible

  >>> do_action('hide')

  >>> print state()
  private

Check that an Owner user can do a PROPFIND:

  >>> self.setRoles(['Owner'])
  >>> print http(r"""
  ... PROPFIND /plone/index_html HTTP/1.1
  ... Content-Type: text/xml; charset="utf-8"
  ... Authorization: Basic %s:%s
  ... Depth: 0
  ...
  ... <?xml version="1.0" encoding="utf-8"?>
  ...    <DAV:propfind xmlns:DAV="DAV:">
  ...      <DAV:prop><displayname/></DAV:prop>
  ...    </DAV:propfind>""" % (user_name, user_password))
  HTTP/1.1 207 Multi-Status
  ...

Check that an Owner user can LOCK:

  >>> self.portal.index_html.wl_clearLocks()
  >>> print http(r"""
  ... LOCK /plone/index_html HTTP/1.1
  ... Content-Type: text/xml; charset="utf-8"
  ... Depth: 0
  ... Authorization: Basic %s:%s
  ...
  ... <?xml version="1.0" encoding="utf-8"?>
  ... <DAV:lockinfo xmlns:DAV="DAV:">
  ... <DAV:lockscope><DAV:exclusive/></DAV:lockscope>
  ... <DAV:locktype><DAV:write/></DAV:locktype>
  ... </DAV:lockinfo>""" % (user_name, user_password))
  HTTP/1.1 200 OK
  ...
  Lock-Token: ...

Check that an Authenticated user can't do a PROPFIND:

  >>> self.setRoles(['Authenticated'])
  >>> print http(r"""
  ... PROPFIND /plone/index_html HTTP/1.1
  ... Content-Type: text/xml; charset="utf-8"
  ... Authorization: Basic %s:%s
  ... Depth: 0
  ...
  ... <?xml version="1.0" encoding="utf-8"?>
  ...    <DAV:propfind xmlns:DAV="DAV:">
  ...      <DAV:prop><displayname/></DAV:prop>
  ...    </DAV:propfind>""" % (user_name, user_password))
  HTTP/1.1 401 Unauthorized
  ...

Check that an Authenticated user can't LOCK:

  >>> self.portal.index_html.wl_clearLocks()
  >>> print http(r"""
  ... LOCK /plone/index_html HTTP/1.1
  ... Content-Type: text/xml; charset="utf-8"
  ... Depth: 0
  ... Authorization: Basic %s:%s
  ...
  ... <?xml version="1.0" encoding="utf-8"?>
  ... <DAV:lockinfo xmlns:DAV="DAV:">
  ... <DAV:lockscope><DAV:exclusive/></DAV:lockscope>
  ... <DAV:locktype><DAV:write/></DAV:locktype>
  ... </DAV:lockinfo>""" % (user_name, user_password))
  HTTP/1.1 401 Unauthorized
  ...
