[Cosmo-dev] JSON-RPC considered harmful
Bobby Rullo
br at osafoundation.org
Tue Dec 5 22:04:04 PST 2006
One thing to note here, for those who are concerned with schedules
and whatnot is that the code in RPCServiceImpl will be almost
completely reused - we are not talking about Travis reimplementing
everything that RPC does - only the way that RPC methods are invoked
really.
Having all the information necessary for authorization available in
the URL and headers makes it easy for our security filters to reject
quickly unauthorized requests, and allows us to re-use code that is
already written for DAV and CMP.
It may seem like what is being proposed is a whole new protocol, and
perhaps in some ways it is, but it's really a taking a bunch of
pieces that already exist in Cosmo (JSON serialized objects, ticket
processing code, Cosmo UI RPC methods, RESTful Http protocols) and
putting them together in a new way.
Bobby
On Dec 5, 2006, at 6:07 PM, Travis Vachon wrote:
> 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
> _______________________________________________
> cosmo-dev mailing list
> cosmo-dev at lists.osafoundation.org
> http://lists.osafoundation.org/mailman/listinfo/cosmo-dev
More information about the cosmo-dev
mailing list