diff options
Diffstat (limited to 'coip/apps/scim/__init__.py')
| -rw-r--r-- | coip/apps/scim/__init__.py | 86 | 
1 files changed, 86 insertions, 0 deletions
diff --git a/coip/apps/scim/__init__.py b/coip/apps/scim/__init__.py new file mode 100644 index 0000000..0520e65 --- /dev/null +++ b/coip/apps/scim/__init__.py @@ -0,0 +1,86 @@ +import logging + +class NotRegistered(Exception): +    pass + +class NotAvailable(Exception): +    pass + +class ObjectHandler(object): +    def __init__(self,model,schemas): +        self.model = model +        self.schemas = schemas +         +    def serialize(self,o): +        d = {'meta': {},'schemas':[]} +        for schema in self.schemas: +            if schema.URI == 'urn:scim:schemas:core:1.0': +                d.update(self.as_dict(schema,o)) +            else: +                d.update({schema.URI: self.as_dict(schema,o)}) +            d['schemas'].append(schema.URI) +        return d +     +    def create(self,d): +        for schema in self.schemas: +            if schema.URI in d['schemas']: +                data = d +                if schema.URI != 'urn:scim:schemas:core:1.0': +                    data = d[schema.URI] +                try: +                    return schema.create(self.model,data) +                except NotAvailable: +                    pass +        raise NotAvailable("No way to create this object") +     +    def as_dict(self,schema,o): +        d = dict([(a,schema.__class__.__dict__[a].__get__(o)) for a in schema.ATTRIBUTES]) +        logging.debug(d) +        return d +             +    def update(self,o,d,replace=False): +        meta_attributes = d['meta'].get('attributes',{}) +        for schema in self.schemas: +            if schema in d['schemas']: +                data = d +                if schema.URI != 'urn:scim:schemas:core:1.0': +                    data = d[schema] +                     +                for a in schema.ATTRIBUTES: +                    v = data[a] +                    t = type(v) +                    p = getattr(schema,a) +                    if a in meta_attributes: +                        if not data.has_key(a): +                            p.__delete__(o) +                        else: +                            p.__set__(o,v) ## replace +                    else: #add / remove +                        if t is dict: #merge +                            p.__set__(o,p.__get__(o).update(v)) +                        elif (t is list or t is tuple) and not t is str: +                            for i in v: +                                if type(i) is dict: +                                    if i.get('operation',None) == 'delete': +                                        p.remove(o,i) +                                    else: +                                        p.update(o,i) +                                else: # no nested lists +                                    p.add(o,i) +                        else: +                            p.__set__(o,v) # simple type +                     +class ObjectTypeRegistry(object): +    def __init__(self): +        self._registry = {} +         +    def register(self,model,prefix,schemas): +        if prefix == None: +            prefix = "%ss" % model.__name__ +        #for schema in schemas:                 +        #    for attr in schema.ATTRIBUTES: +        #        setattr(model,attr,schema.__dict__['externalId']) +                 +        self._registry[prefix] = ObjectHandler(model,schemas) + +types = ObjectTypeRegistry()
\ No newline at end of file  | 
