[Cosmo-dev] JSON-RPC considered harmful
Travis Vachon
travis at osafoundation.org
Tue Dec 5 18:07:26 PST 2006
Hi folks
I've started design work for bug 7370. For background, please check out:
http://wiki.osafoundation.org/bin/view/Journal/
BrianMoseleyCosmoCasualCollaborator (ticket vs. login)
https://bugzilla.osafoundation.org/show_bug.cgi?id=7370
http://wiki.osafoundation.org/bin/view/Journal/ZeroSixTaskBreakdown
( anonymous access)
The problem is to allow clients (in this case, the PIM ui) read or
write access to collections based on a ticket id.
Currently, ticketed access to collections relies on information
presented in the url. For example, if I request /cosmo/collection/
{collectionId}?ticket={ticketId}, the TicketAuthenticationProvider
pulls the collectionId and ticketId out of the url and makes a
decision to allow access based on this information.
Problem is, the PIM ui uses JSON-RPC, which always makes a request
to /cosmo/JSON-RPC. This means the collection and ticket information
would need to be embedded either in a headers or in the JSON content
body of the request.
There are a couple problems with doing either of these:
headers - we already have the collectionId in the content body. If we
duplicate this information, we run into problems where a malicious
user could specify different collectionIds in the header and JSON
content body. We could work around this, making sure the two match,
but this would require parsing JSON in the
TicketAuthenticationProvider. We could also just ignore the
collectionId in the content body, but this would require some ugly
retooling of the JSON service. The necessity of having these also
begs the question of why we are even using JSON.
JSON content body - this would definitely require parsing the JSON in
the TicketAuthenticationProvider. If we're ok doing this, this might
be the most expedient way to get this feature working. That said,
Bobby and I agree that this isn't a great solution. First, we're
parsing JSON twice over the course of the request (once in the
TicketAuthenticationProvider and once in the RPCService). Next, the
JSON-RPC method signatures wouldn't necessarily guarantee a position
for the ticket id, so figuring out exactly where in the content body
the ticket lives would be dicey at best.
Given this, Bobby and I are of the opinion that it would be more
worth our time to start moving away from JSON-RPC. Leaving the
current system in place, we would add on the new functionality we
need by implementing an HTTP based protocol which would return JSON
identical to the JSON currently returned by the ScoobyService object.
To start (to fix 7370), we would implement the following requests,
each of which corresponds to a current JSON-RPC method;
getEvent(calendarName, id) -> (GET /item/{itemUid}?ticket={ticketId}
getEvents(calendarPath, beginDate, endDate) -> (GET /collection/
{collectionUid}?bDate={beginDate}&eDate={endDate}&ticket={ticketId}
saveEvent(calendarPath, event) -> PUT /item/{collectionUid}/{itemUid}
w/ JSON item representation as content
removeEvent(calendarPath, event) -> DELETE /item/{itemUid}
getRecurrenceRules(calendarPath, eventIds) -> GET /item/{itemUid}/
recurrence?iid={e1}&iid={e2}&...&iid={eN}
saveRecurrenceRule(calendarPath, eventId, recurrenceRule) -> PUT /
item/{itemUid}/recurrence w/ JSON recurrenceRule representation as
content
expandEvents(calendarPath, eventIds, utcStartTime, utcEndTime) ->
GET /collection/{collectionUid}?iid={e1}&iid={e2}&...&iid={eN}&stime=
{startTime}&etime={endTime}
saveNewEventBreakRecurrence(String calendarPath, event,
originalEventId, originalEventEndDate) ->
PUT /breakevent/{originalEventUid}?date=originalEventEndDate w/ JSON
event as content
You'll notice this scheme also takes into account the work I'm going
to be doing for bug 7405 (RPC calls by ID not path). I'm probably
going to fix 7405 before moving ahead with 7370, since it will makes
things considerably less confusing and prevent duplication of effort.
Finally, you'll notice some of these requests use methods other than
GET or POST. This is a problem for safari. Google has solved this
problem in their GData protocol with a new header X-HTTP-Method-
Override (http://code.google.com/apis/gdata/protocol.html#Updating-an-
entry). I worked on this idea a couple months ago after talking with
BCM, and have a ServletFilter implemented that will provide this
functionality, it just needs to be checked in.
These would used by any Calendars on the client side that require
ticket based access. Bobby has a few ideas about the specifics about
how this should be designed in the short term on the client side, but
I'd like to leave that for a future e-mail.
We've been talking this through quite a bit today, and would
definitely like feedback. Thoughts?
Thanks,
Travis
More information about the cosmo-dev
mailing list