[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