summaryrefslogtreecommitdiff
path: root/coip/apps/scim/__init__.py
diff options
context:
space:
mode:
authorLeif Johansson <leifj@sunet.se>2012-04-20 10:42:45 +0200
committerLeif Johansson <leifj@sunet.se>2012-04-20 10:42:45 +0200
commit131f7f2d869d394ac6e942c1135529033f1e0ca2 (patch)
tree128e490a425be8e9834ffdc216743c306d96c84e /coip/apps/scim/__init__.py
parent241905ce73223ed97b6ac9c62d8250b9659f6e3a (diff)
scim v0.1newprofiles2
Diffstat (limited to 'coip/apps/scim/__init__.py')
-rw-r--r--coip/apps/scim/__init__.py86
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