Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CalDAV: Issue with write permissions and multiple shares #3677

Closed
georgehrke opened this issue Mar 2, 2017 · 5 comments
Closed

CalDAV: Issue with write permissions and multiple shares #3677

georgehrke opened this issue Mar 2, 2017 · 5 comments
Assignees

Comments

@georgehrke
Copy link
Member

taken from nextcloud/calendar#316

Steps

  1. Create a calendar as admin
  2. Create a user test1 that is part of group1 and group2
  3. Share calendar with group1
  4. Share calendar with group2
  5. Tick the "can edit" box for group1

Expected

test1 should be able to create events and see the calendar in the normal list.

Actually

test1 sees the calendar in the subscription list and therefor can not add events.

Workarounds

Swap step 4 and 5 makes it work. But you can then again break it, when you remove the "can edit" from all shares and add it to the first group again....

Dav response

<?xml version="1.0"?>
<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/" xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns">
 <d:response>
  <d:href>/remote.php/dav/calendars/test1/</d:href>
  <d:propstat>
   <d:prop>
    <d:resourcetype>
     <d:collection/>
    </d:resourcetype>
    <d:acl>
     <d:ace>
      <d:principal>
       <d:href>/remote.php/dav/principals/users/test1/</d:href>
      </d:principal>
      <d:grant>
       <d:privilege>
        <d:read/>
       </d:privilege>
      </d:grant>
      <d:protected/>
     </d:ace>
     <d:ace>
      <d:principal>
       <d:href>/remote.php/dav/principals/users/test1/</d:href>
      </d:principal>
      <d:grant>
       <d:privilege>
        <d:write/>
       </d:privilege>
      </d:grant>
      <d:protected/>
     </d:ace>
     <d:ace>
      <d:principal>
       <d:href>/remote.php/dav/principals/users/test1/calendar-proxy-write/</d:href>
      </d:principal>
      <d:grant>
       <d:privilege>
        <d:read/>
       </d:privilege>
      </d:grant>
      <d:protected/>
     </d:ace>
     <d:ace>
      <d:principal>
       <d:href>/remote.php/dav/principals/users/test1/calendar-proxy-write/</d:href>
      </d:principal>
      <d:grant>
       <d:privilege>
        <d:write/>
       </d:privilege>
      </d:grant>
      <d:protected/>
     </d:ace>
     <d:ace>
      <d:principal>
       <d:href>/remote.php/dav/principals/users/test1/calendar-proxy-read/</d:href>
      </d:principal>
      <d:grant>
       <d:privilege>
        <d:read/>
       </d:privilege>
      </d:grant>
      <d:protected/>
     </d:ace>
    </d:acl>
    <d:owner>
     <d:href>/remote.php/dav/principals/users/test1/</d:href>
    </d:owner>
   </d:prop>
   <d:status>HTTP/1.1 200 OK</d:status>
  </d:propstat>
  <d:propstat>
   <d:prop>
    <d:displayname/>
    <cal:calendar-description/>
    <cal:calendar-timezone/>
    <x1:calendar-order xmlns:x1="http://apple.com/ns/ical/"/>
    <x1:calendar-color xmlns:x1="http://apple.com/ns/ical/"/>
    <cal:supported-calendar-component-set/>
    <cs:publish-url/>
    <cs:allowed-sharing-modes/>
    <oc:calendar-enabled/>
    <oc:invite/>
    <cs:source/>
   </d:prop>
   <d:status>HTTP/1.1 404 Not Found</d:status>
  </d:propstat>
 </d:response>
 <d:response>
  <d:href>/remote.php/dav/calendars/test1/personal/</d:href>
  <d:propstat>
   <d:prop>
    <d:displayname>Persönlich</d:displayname>
    <d:resourcetype>
     <d:collection/>
     <cal:calendar/>
    </d:resourcetype>
    <x1:calendar-order xmlns:x1="http://apple.com/ns/ical/">0</x1:calendar-order>
    <cal:supported-calendar-component-set>
     <cal:comp name="VEVENT"/>
     <cal:comp name="VTODO"/>
    </cal:supported-calendar-component-set>
    <cs:allowed-sharing-modes>
     <cs:can-be-shared/>
     <cs:can-be-published/>
    </cs:allowed-sharing-modes>
    <d:acl>
     <d:ace>
      <d:principal>
       <d:href>/remote.php/dav/principals/users/test1/</d:href>
      </d:principal>
      <d:grant>
       <d:privilege>
        <d:read/>
       </d:privilege>
      </d:grant>
      <d:protected/>
     </d:ace>
     <d:ace>
      <d:principal>
       <d:href>/remote.php/dav/principals/users/test1/</d:href>
      </d:principal>
      <d:grant>
       <d:privilege>
        <d:write/>
       </d:privilege>
      </d:grant>
      <d:protected/>
     </d:ace>
    </d:acl>
    <d:owner>
     <d:href>/remote.php/dav/principals/users/test1/</d:href>
    </d:owner>
    <oc:invite/>
   </d:prop>
   <d:status>HTTP/1.1 200 OK</d:status>
  </d:propstat>
  <d:propstat>
   <d:prop>
    <cal:calendar-description/>
    <cal:calendar-timezone/>
    <x1:calendar-color xmlns:x1="http://apple.com/ns/ical/"/>
    <cs:publish-url/>
    <oc:calendar-enabled/>
    <cs:source/>
   </d:prop>
   <d:status>HTTP/1.1 404 Not Found</d:status>
  </d:propstat>
 </d:response>
 <d:response>
  <d:href>/remote.php/dav/calendars/test1/test_shared_by_admin/</d:href>
  <d:propstat>
   <d:prop>
    <d:displayname>Test (Admin Istrato)</d:displayname>
    <d:resourcetype>
     <d:collection/>
     <cal:calendar/>
    </d:resourcetype>
    <x1:calendar-order xmlns:x1="http://apple.com/ns/ical/">0</x1:calendar-order>
    <x1:calendar-color xmlns:x1="http://apple.com/ns/ical/">#78e774</x1:calendar-color>
    <cal:supported-calendar-component-set>
     <cal:comp name="VEVENT"/>
     <cal:comp name="VTODO"/>
    </cal:supported-calendar-component-set>
    <cs:allowed-sharing-modes>
     <cs:can-be-shared/>
     <cs:can-be-published/>
    </cs:allowed-sharing-modes>
    <d:acl>
     <d:ace>
      <d:principal>
       <d:href>/remote.php/dav/principals/users/admin/</d:href>
      </d:principal>
      <d:grant>
       <d:privilege>
        <d:read/>
       </d:privilege>
      </d:grant>
      <d:protected/>
     </d:ace>
     <d:ace>
      <d:principal>
       <d:href>/remote.php/dav/principals/users/admin/</d:href>
      </d:principal>
      <d:grant>
       <d:privilege>
        <d:write/>
       </d:privilege>
      </d:grant>
      <d:protected/>
     </d:ace>
     <d:ace>
      <d:principal>
       <d:href>/remote.php/dav/principals/users/test1/</d:href>
      </d:principal>
      <d:grant>
       <d:privilege>
        <d:read/>
       </d:privilege>
      </d:grant>
      <d:protected/>
     </d:ace>
     <d:ace>
      <d:principal>
       <d:href>/remote.php/dav/principals/groups/group2/</d:href>
      </d:principal>
      <d:grant>
       <d:privilege>
        <d:read/>
       </d:privilege>
      </d:grant>
      <d:protected/>
     </d:ace>
     <d:ace>
      <d:principal>
       <d:href>/remote.php/dav/principals/groups/group2/</d:href>
      </d:principal>
      <d:grant>
       <d:privilege>
        <d:write-properties/>
       </d:privilege>
      </d:grant>
      <d:protected/>
     </d:ace>
     <d:ace>
      <d:principal>
       <d:href>/remote.php/dav/principals/groups/group1/</d:href>
      </d:principal>
      <d:grant>
       <d:privilege>
        <d:read/>
       </d:privilege>
      </d:grant>
      <d:protected/>
     </d:ace>
     <d:ace>
      <d:principal>
       <d:href>/remote.php/dav/principals/groups/group1/</d:href>
      </d:principal>
      <d:grant>
       <d:privilege>
        <d:write/>
       </d:privilege>
      </d:grant>
      <d:protected/>
     </d:ace>
    </d:acl>
    <d:owner>
     <d:href>/remote.php/dav/principals/users/admin/</d:href>
    </d:owner>
    <oc:invite>
     <oc:user>
      <d:href>principal:principals/groups/group2</d:href>
      <oc:invite-accepted/>
      <oc:access>
       <oc:read/>
      </oc:access>
     </oc:user>
     <oc:user>
      <d:href>principal:principals/groups/group1</d:href>
      <oc:invite-accepted/>
      <oc:access>
       <oc:read-write/>
      </oc:access>
     </oc:user>
    </oc:invite>
   </d:prop>
   <d:status>HTTP/1.1 200 OK</d:status>
  </d:propstat>
  <d:propstat>
   <d:prop>
    <cal:calendar-description/>
    <cal:calendar-timezone/>
    <cs:publish-url/>
    <oc:calendar-enabled/>
    <cs:source/>
   </d:prop>
   <d:status>HTTP/1.1 404 Not Found</d:status>
  </d:propstat>
 </d:response>
 <d:response>
  <d:href>/remote.php/dav/calendars/test1/inbox/</d:href>
  <d:propstat>
   <d:prop>
    <d:resourcetype>
     <d:collection/>
     <cal:schedule-inbox/>
    </d:resourcetype>
    <d:acl>
     <d:ace>
      <d:principal>
       <d:authenticated/>
      </d:principal>
      <d:grant>
       <d:privilege>
        <d:read/>
       </d:privilege>
      </d:grant>
      <d:protected/>
     </d:ace>
     <d:ace>
      <d:principal>
       <d:href>/remote.php/dav/principals/users/test1/</d:href>
      </d:principal>
      <d:grant>
       <d:privilege>
        <d:write-properties/>
       </d:privilege>
      </d:grant>
      <d:protected/>
     </d:ace>
     <d:ace>
      <d:principal>
       <d:href>/remote.php/dav/principals/users/test1/</d:href>
      </d:principal>
      <d:grant>
       <d:privilege>
        <d:unbind/>
       </d:privilege>
      </d:grant>
      <d:protected/>
     </d:ace>
     <d:ace>
      <d:principal>
       <d:href>/remote.php/dav/principals/users/test1/calendar-proxy-write/</d:href>
      </d:principal>
      <d:grant>
       <d:privilege>
        <d:unbind/>
       </d:privilege>
      </d:grant>
      <d:protected/>
     </d:ace>
     <d:ace>
      <d:principal>
       <d:authenticated/>
      </d:principal>
      <d:grant>
       <d:privilege>
        <cal:schedule-deliver/>
       </d:privilege>
      </d:grant>
      <d:protected/>
     </d:ace>
    </d:acl>
    <d:owner>
     <d:href>/remote.php/dav/principals/users/test1/</d:href>
    </d:owner>
   </d:prop>
   <d:status>HTTP/1.1 200 OK</d:status>
  </d:propstat>
  <d:propstat>
   <d:prop>
    <d:displayname/>
    <cal:calendar-description/>
    <cal:calendar-timezone/>
    <x1:calendar-order xmlns:x1="http://apple.com/ns/ical/"/>
    <x1:calendar-color xmlns:x1="http://apple.com/ns/ical/"/>
    <cal:supported-calendar-component-set/>
    <cs:publish-url/>
    <cs:allowed-sharing-modes/>
    <oc:calendar-enabled/>
    <oc:invite/>
    <cs:source/>
   </d:prop>
   <d:status>HTTP/1.1 404 Not Found</d:status>
  </d:propstat>
 </d:response>
 <d:response>
  <d:href>/remote.php/dav/calendars/test1/outbox/</d:href>
  <d:propstat>
   <d:prop>
    <d:resourcetype>
     <d:collection/>
     <cal:schedule-outbox/>
    </d:resourcetype>
    <d:acl>
     <d:ace>
      <d:principal>
       <d:href>/remote.php/dav/principals/users/test1/</d:href>
      </d:principal>
      <d:grant>
       <d:privilege>
        <cal:schedule-send/>
       </d:privilege>
      </d:grant>
      <d:protected/>
     </d:ace>
     <d:ace>
      <d:principal>
       <d:href>/remote.php/dav/principals/users/test1/</d:href>
      </d:principal>
      <d:grant>
       <d:privilege>
        <d:read/>
       </d:privilege>
      </d:grant>
      <d:protected/>
     </d:ace>
     <d:ace>
      <d:principal>
       <d:href>/remote.php/dav/principals/users/test1/calendar-proxy-write/</d:href>
      </d:principal>
      <d:grant>
       <d:privilege>
        <cal:schedule-send/>
       </d:privilege>
      </d:grant>
      <d:protected/>
     </d:ace>
     <d:ace>
      <d:principal>
       <d:href>/remote.php/dav/principals/users/test1/calendar-proxy-read/</d:href>
      </d:principal>
      <d:grant>
       <d:privilege>
        <d:read/>
       </d:privilege>
      </d:grant>
      <d:protected/>
     </d:ace>
     <d:ace>
      <d:principal>
       <d:href>/remote.php/dav/principals/users/test1/calendar-proxy-write/</d:href>
      </d:principal>
      <d:grant>
       <d:privilege>
        <d:read/>
       </d:privilege>
      </d:grant>
      <d:protected/>
     </d:ace>
    </d:acl>
    <d:owner>
     <d:href>/remote.php/dav/principals/users/test1/</d:href>
    </d:owner>
   </d:prop>
   <d:status>HTTP/1.1 200 OK</d:status>
  </d:propstat>
  <d:propstat>
   <d:prop>
    <d:displayname/>
    <cal:calendar-description/>
    <cal:calendar-timezone/>
    <x1:calendar-order xmlns:x1="http://apple.com/ns/ical/"/>
    <x1:calendar-color xmlns:x1="http://apple.com/ns/ical/"/>
    <cal:supported-calendar-component-set/>
    <cs:publish-url/>
    <cs:allowed-sharing-modes/>
    <oc:calendar-enabled/>
    <oc:invite/>
    <cs:source/>
   </d:prop>
   <d:status>HTTP/1.1 404 Not Found</d:status>
  </d:propstat>
 </d:response>
</d:multistatus>

The {DAV:}write} acl is set in https://github.com/nextcloud/server/blob/master/apps/dav/lib/CalDAV/Calendar.php#L123.

That relies on calendarInfo['{http://owncloud.org/ns}read-only']. (https://github.com/nextcloud/server/blob/master/apps/dav/lib/CalDAV/Calendar.php#L275).

The read-only property is set in getCalendarsForUser (https://github.com/nextcloud/server/blob/master/apps/dav/lib/CalDAV/CalDavBackend.php#L297),
but only for the first calendar queried from the database (https://github.com/nextcloud/server/blob/master/apps/dav/lib/CalDAV/CalDavBackend.php#L304)

When sharing with group1 and group2 and only then giving write-permission to group1, group1 comes after group2 in the dav_shares table. Therefore that row is ignored.

@georgehrke
Copy link
Member Author

@nickvergessen

@georgehrke
Copy link
Member Author

I see two solutions here:

  1. check if the existing calendar has fewer permissions in https://github.com/nextcloud/server/blob/master/apps/dav/lib/CalDAV/CalDavBackend.php#L304

  2. Permissions for sharing are:

1 - owner
2 - read-write
3 - read

Just add order by dav_shares.access to the sql query.

@georgehrke
Copy link
Member Author

I'd personally go with 2 for simplicity's sake.
@nickvergessen any opinion?

@nickvergessen
Copy link
Member

I'm already on it, I hate ordering, so will actually check it. But it's not complicated either.

@georgehrke
Copy link
Member Author

ok :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants