''' Created on Apr 10, 2012 @author: leifj ''' from django.http import HttpResponseNotFound, HttpResponseBadRequest,\ HttpResponse from coip.apps.resource.models import object_for_uuid from django.utils import simplejson from coip.apps.name.models import Name, lookup from uuid import UUID from coip.apps.scim import types import logging def get_handler_for_prefix(prefix): if not prefix in types._registry.keys(): return None return types._registry[prefix] def scim_response(d,status=200): content = None if d != None: content = simplejson.dumps(d) r = HttpResponse(content=content,status=status,content_type='application/json') if not d.has_key('meta'): d['meta'] = {} location = d['meta'].get('location',None) if location is not None: r['Location'] = location return r def _resolve_name(nid): if nid == None: return None if '/' in nid: return lookup(nid) try: pk = int(nid) return Name.objects.get(id=pk) except ValueError: pass try: return object_for_uuid(str(UUID(nid))) except ValueError: pass return None def scim_v1_get(request,name,handler,uuid): o = object_for_uuid(uuid) if o == None: return HttpResponseNotFound if not isinstance(o, handler.model): return HttpResponseBadRequest("%s does not resolve to an object of type %s" % (uuid,handler.model.__name__)) d = handler.serialize(o) #logging.debug(d) d['meta']['location'] = request.build_absolute_uri() return scim_response(d) def scim_v1_post(request,name,handler): # authorize request based on name d = simplejson.loads(request.raw_post_data) o = handler.create(d) d = handler.serialize(o) d['meta']['location'] = request.build_absolute_uri() return scim_response(d,201) def scim_v1_delete(request,name,handler,uuid): o = object_for_uuid(uuid) if o == None: return HttpResponseNotFound if not isinstance(o, handler.model): return HttpResponseBadRequest("%s does not resolve to an object of type %s" % (uuid,handler.model.__name__)) o.delete() return scim_response(200) def scim_v1_put(request,name,handler,uuid): o = object_for_uuid(uuid) if o == None: return HttpResponseNotFound if not isinstance(o,handler.model): return HttpResponseBadRequest("%s does not resolve to an object of type %s" % (uuid,handler.model.__name__)) d = simplejson.loads(request.raw_post_data) handler.update(o,d,replace=True) o.save() d = handler.serialize(o) d['meta']['location'] = request.build_absolute_uri() return scim_response(d,200) def scim_v1_patch(request,name,handler,uuid): o = object_for_uuid(uuid) if o == None: return HttpResponseNotFound() if not isinstance(o, handler.model): return HttpResponseBadRequest("%s does not resolve to an object of type %s" % (uuid,handler.model.__name__)) d = simplejson.loads(request.raw_post_data) handler.update(o,d,replace=False) o.save() return scim_response(204) def scim_v1(request,nid=None,prefix='Groups',uuid=None): name = _resolve_name(nid) handler = get_handler_for_prefix(prefix) if handler == None: return HttpResponseNotFound("Unknown SCIM resource type %s" % prefix) if request.method == 'GET': return scim_v1_get(request,name,handler,uuid) if request.method == 'POST': #if name == None: # return HttpResponseNotFound("No such name") if uuid != None: return HttpResponseBadRequest("POSTing to resource is not allowed. Use PUT to update a resource.") return scim_v1_post(request,name,handler) if request.method == 'DELETE': if uuid == None: return HttpResponseBadRequest("Missing resource") return scim_v1_delete(request,name,handler,uuid) if request.method == 'PATCH': if uuid == None: return HttpResponseBadRequest("Missing resource") return scim_v1_patch(request,name,handler,uuid) if request.method == 'PUT': if uuid == None: return HttpResponseBadRequest("Missing resource") return scim_v1_put(request,name,handler,uuid) return HttpResponseBadRequest()