Just wondering if there are any suggestions about this “You are not authorized 
to access this resource” issue wjem trying to delete this corrupt event.

Thanks in advance,

Ian

> On May 13, 2017, at 5:19 PM, Ian Baker <iba...@eem.ca> wrote:
> 
> André,
> 
> I can confirm that the problematic event doesn’t seem to crash the boss’s 
> Calendar.app.  It just doesn’t show up in his calendar, nor does the 
> associated event wit the same UID.  He is running 10.11.6, and I accessed his 
> calendar to confirm, and I’m running 10.12.5. Again, no crash.  To avoid the 
> erroneous notifications mentioned earlier, I used the macOS Guest account 
> with no mail accounts configured.
> 
> I was able to get the event's resource_id, and then establish its URL.  I 
> even validated that the URL was correct by getting it using Safari and 
> comparing the result with the expected event.  I authenticated in Safari with 
> both the boss’s userid/password as well as the Bonus round #1 
> AdminPrincipal's userid/password, so both authentications were working 
> correctly.
> 
> However, I am truly hesitant to report that when attempting the curl -X 
> delete, and authenticating either way, I get this:
> 
>       
> <html><head><title>Unauthorized</title></head><body><h1>Unauthorized</h1><p>You
>  are not authorized to access this resource.</p></body></html>
> 
> Not sure where to go from here.
> 
> TIA
> 
> Ian
> 
> 
>> On May 11, 2017, at 5:10 PM, Andre LaBranche <d...@apple.com 
>> <mailto:d...@apple.com>> wrote:
>> 
>> 
>>> On May 11, 2017, at 7:46 AM, Ian Baker <iba...@eem.ca 
>>> <mailto:iba...@eem.ca>> wrote:
>>> 
>>>> On May 10, 2017, at 8:27 PM, Andre LaBranche <d...@apple.com 
>>>> <mailto:d...@apple.com>> wrote:
>>>> 
>>>> Yeah, wow. There are actually two distinct VCALENDAR objects here - both 
>>>> with the same UID. I've never seen this happen.
>> 
>> I was embarrassingly mistaken in my characterization of this. The psql 
>> output clearly indicates there are two rows, and it is not abnormal to have 
>> multiple calendar_object rows for events with the same UID; the organizer 
>> and attendees all get their own copy.
>> 
>> Both of the events, when placed into discrete ics files, validate 
>> successfully.
>> 
>> Anyhow, even though the pycalendar validator is OK with both of these 
>> events, the one that has no organizer / attendee information but does have a 
>> RECURRENCE-ID crashes Calendar.app if I try to import it. That's bad, and I 
>> sent a bug to Calendar to remedy that.
>> 
>> It's unclear why this event is in the state that it's in, but it's not a 
>> good state. The easiest option for unblocking the web calendar is probably 
>> to just delete the problem event. Since it's just a (seemingly broken) 
>> cancel, there should be no harm in this. Never make changes to calendar data 
>> using direct database access; stick with HTTP to keep everything coherent. 
>> An HTTP "delete" request should work fine, the only tricky part is finding 
>> the URL to delete, since the event in question is likely returned in a batch 
>> request, in which case the individual URLs won't appear in the access.log.
>> 
>> The first step is to find the resource_id of the event, which is another 
>> column on calendar_object. We'll use the event UID and a substring search 
>> for RECURRENCE-ID as the predicates. In the example below, use your event's 
>> UID instead (which is 
>> 040000008200E00074C5B7101A82E008000000004020622BEB7AD201000000000000000010000000C05F922AF30E4145839AF52B293ABFFB)
>> 
>> caldav=# select resource_id, calendar_resource_id from calendar_object where 
>> icalendar_text LIKE '%RECURRENCE-ID%' and icalendar_uid = 
>> '8F98441F-3890-457E-B0E6-6875EE527951';
>>  resource_id | calendar_resource_id 
>> -------------+----------------------
>>           26 |                    2
>> (1 row)
>> 
>> (calendar_resource_id is a reference to the calendar that contains the 
>> event. There shouldn't be multiple results for this query in your case, but 
>> if there are, this value would probably vary).
>> 
>> With the resource_id in hand, you can compose a URL by traversing the 
>> CalendarServer resource hierarchy using something like the following, 
>> substituting your resource_id on the last line of the query, and changing 
>> 'example.com <http://example.com/>' to something correct.
>> 
>> SELECT '"https://example.com:8443/calendars/__uids__/' 
>> <https://example.com:8443/calendars/__uids__/'>
>>        || owner_uid 
>>        || '/' 
>>        || calendar_resource_name 
>>        || '/' 
>>        || resource_name
>>        || '"' as URL
>> FROM   calendar_bind 
>>        JOIN calendar_home 
>>          ON calendar_bind.calendar_home_resource_id = 
>> calendar_home.resource_id 
>>        JOIN calendar_object 
>>          ON calendar_bind.calendar_resource_id = 
>>             calendar_object.calendar_resource_id 
>> WHERE  calendar_object.resource_id = 26;
>> 
>> Example:
>> 
>> caldav=# SELECT '"https://example.com:8443/calendars/__uids__/' 
>> <https://example.com:8443/calendars/__uids__/'>
>> caldav-#        || owner_uid 
>> caldav-#        || '/' 
>> caldav-#        || calendar_resource_name 
>> caldav-#        || '/' 
>> caldav-#        || resource_name
>> caldav-#        || '"' as URL
>> caldav-# FROM   calendar_bind 
>> caldav-#        JOIN calendar_home 
>> caldav-#          ON calendar_bind.calendar_home_resource_id = 
>> calendar_home.resource_id 
>> caldav-#        JOIN calendar_object 
>> caldav-#          ON calendar_bind.calendar_resource_id = 
>> caldav-#             calendar_object.calendar_resource_id 
>> caldav-# WHERE  calendar_object.resource_id = 26;
>>                                                                     url      
>>                                                               
>> -------------------------------------------------------------------------------------------------------------------------------------------
>>  
>> "https://example.com:8443/calendars/__uids__/E1CB3592-E7BD-41C4-A27C-6E23FEFFD197/calendar/8F98441F-3890-457E-B0E6-6875EE527951.ics
>>  
>> <https://example.com:8443/calendars/__uids__/E1CB3592-E7BD-41C4-A27C-6E23FEFFD197/calendar/8F98441F-3890-457E-B0E6-6875EE527951.ics>"
>> (1 row)
>> 
>> Now with an URL, you can fire a DELETE using curl. Such a request usually 
>> needs to be authenticated with the credentials of the user whose GUID is 
>> shown after the __uids__ portion of the URL (in the DB, this is 
>> calendar_home.owner_uid). To confirm that username:
>> 
>> % dscl /Search search /Users GeneratedUID 
>> E1CB3592-E7BD-41C4-A27C-6E23FEFFD197
>> andre                GeneratedUID = (
>>     "E1CB3592-E7BD-41C4-A27C-6E23FEFFD197"
>> )
>> 
>> Now you can run curl, supplying the password when prompted:
>> 
>> curl -u <username> -X DELETE <url>
>> 
>> With this seemingly invalid event out of the way, the web calendar should 
>> now load (or at least, get stuck on something else).
>> 
>> 
>> Bonus round #1
>> 
>> ... but you might want to do this on behalf of your boss, without knowing 
>> his password. To do that, add yourself as an AdminPrincipal using the 
>> following CalendarServer config in the file:
>> "/Library/Server/Calendar and Contacts/Config/caldavd-user.plist"  (this 
>> file doesn't exist by default, and is read after caldavd-system.plist, 
>> overriding anything defined there)
>> 
>> <?xml version="1.0" encoding="UTF-8"?>
>> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" 
>> "http://www.apple.com/DTDs/PropertyList-1.0.dtd 
>> <http://www.apple.com/DTDs/PropertyList-1.0.dtd>">
>> <plist version="1.0">
>> <dict>
>> 
>>     <key>AdminPrincipals</key>
>>     <array>
>>         
>> <string>/principals/__uids__/AEB68DD7-D2B8-4D4D-A574-2A4533DF36A4/</string>
>>     </array>
>> 
>> </dict>
>> </plist>
>> 
>> Specify your own GUID instead of the one shown above, which you can find 
>> with a dscl query using your username, e.g.:
>> 
>> $ dscl /Search read /Users/andre GeneratedUID
>> GeneratedUID: E1CB3592-E7BD-41C4-A27C-6E23FEFFD197
>> 
>> Finally, restart CalendarServer to activate the new config:
>> 
>> sudo calendarserver_config --restart
>> 
>> After doing the delete, to disable the AdminPrincipal config, either rename 
>> the caldavd-user.plist file, or comment out the array elements like this:
>> 
>> <!-- 
>> <string>/principals/__uids__/AEB68DD7-D2B8-4D4D-A574-2A4533DF36A4/</string> 
>> -->
>> 
>> ... then bounce the service.
>> 
>> Bonus round #2
>> 
>> Also I confirmed that the validation steps included in my prior email work 
>> as written; the second 'cd' is not optional, and I was trying to do that as 
>> an alternative to 'installing' the module. But now that I remember that 
>> virtualenv <https://virtualenv.pypa.io/en/stable/> exists, here's a more 
>> standard approach:
>> 
>> # provision a new virtualenv, use it, install pycalendar from git using pip
>> virtualenv pycalendar-env
>> cd pycalendar-env
>> source bin/activate
>> pip install git+https://github.com/apple/ccs-pycalendar.git@master 
>> <git+https://github.com/apple/ccs-pycalendar.git@master>
>> 
>> # verify - this should print the path to the pycalendar module that was just 
>> installed
>> python -c 'import pycalendar ; print pycalendar.__path__'
>> 
>> # run the validator
>> % python -m pycalendar.validator ~/1.ics
>> No problems
>> 
>> Bonus round #3
>> 
>> The icalendar_text returned previously by psql isn't in proper iCalendar 
>> form. Even though there are psql options for raw output, I would have to 
>> look those up, while the following vim commands flow like water onto my 
>> keyboard:
>> 
>> :%s/+$//g
>> :%s/\\r//g
>> :%s/^ //g
>> :1,2d
>> :$-2,$d
>> :%s/[ ]*$//g
>> 
>> ... ok I looked it up, and it's easier than the above: just start psql like 
>> this: sudo psql -A -t -h /var/run/caldavd/PostgresSocket -U caldav caldav
>> 
>> e.g.
>> 
>> # psql -A -t -h /var/run/caldavd/PostgresSocket -U caldav caldav -c 'select 
>> icalendar_text from calendar_object limit 1;'
>> BEGIN:VCALENDAR
>> VERSION:2.0
>> PRODID:-//Apple Inc.//Web Calendar Client//
>> BEGIN:VEVENT
>> UID:c6b8d8ac-c23b-23b1-ade0-2756d3ca8fee
>> DTSTART;TZID=America/Los_Angeles:20150814T080000
>> DURATION:PT1H30M
>> DTSTAMP:20150813T182156Z
>> SEQUENCE:2
>> SUMMARY:New Event
>> END:VEVENT
>> BEGIN:X-CALENDARSERVER-PERUSER
>> UID:c6b8d8ac-c23b-23b1-ade0-2756d3ca8fee
>> X-CALENDARSERVER-PERUSER-UID:E1CB3592-E7BD-41C4-A27C-6E23FEFFD197
>> BEGIN:X-CALENDARSERVER-PERINSTANCE
>> TRANSP:OPAQUE
>> END:X-CALENDARSERVER-PERINSTANCE
>> END:X-CALENDARSERVER-PERUSER
>> END:VCALENDAR
>> 
>> (and finally, the X-CALENDARSERVER-PERINSTANCE component would not be 
>> exposed to clients; this component is internal to CalendarServer and is 
>> stripped from event bodies as they leave the server)
>> 
>> -dre
>> 
>> 
>>> 
>>> What is particularly weird is that this event was also sent to another of 
>>> our users ‘Robert Cole’, and I can load his calendar in WebCal and view the 
>>> event without trouble. There were no errors on Rob’s javascript console in 
>>> Safari.
>>> 
>>>     
>>> <PastedGraphic-1.png>
>>> 
>>> I exported Rob's calendar and found one of the 2 events. The ‘cancelled" 
>>> event was not in Rob’s calendar that I could find.  I’ve attached Rob's 
>>> event as an .ics file.  From what I could see Rob’s version didn’t have 
>>> lines related to the following properties:
>>> VCALENDAR
>>> X-CALENDARSERVER-PERUSER
>>> X-CALENDARSERVER-PERINSTANCE
>>> and there seemed to be minor parsing differences (quotes around certain 
>>> fields e.g. email addresses).
>>> 
>>> If these are not the source of the error on the boss’s ('Paul MacLean’) 
>>> WebCal display, might it be something else that is causing the error? The 
>>> event just before or the event just after this one? Or perhaps the volume 
>>> of events in the boss’s calendar - he never throws anything away!
>>> 
>>> TIA
>>> 
>>> Ian
>>> 450-465-1641
>>> 
>>> <Robs Event.ics>

_______________________________________________
calendarserver-users mailing list
calendarserver-users@lists.macosforge.org
https://lists.macosforge.org/mailman/listinfo/calendarserver-users

Reply via email to