def get_normalized_request_content(model, req): """Initialize a model from json/xml contents of request body""" if req.content_type == "application/xml": return model.from_xml(req.body) elif req.content_type == "application/json": return model.from_json(req.body) else: raise fault.IdentityFault("I don't understand the content type", code=415)
def to_xml(self): """ Returns only Diablo syntax (can only have one root in XML) This middleware is designed to provide D5 compatibility but NOT at the expense of breaking the Diablo contract.""" if self.xml is None: if self.json is None: raise NotImplementedError else: raise fault.IdentityFault("%s not initialized with data" % \ self.__class__.__str__) return etree.tostring(self.xml)
def check_error(*args, **kwargs): try: return func(*args, **kwargs) except Exception as err: if isinstance(err, fault.IdentityFault): return send_error(err.code, kwargs['req'], err) elif isinstance(err, fault.ItemNotFoundFault): return send_error(err.code, kwargs['req'], err) else: logging.exception(err) return send_error( 500, kwargs['req'], fault.IdentityFault("Unhandled error", str(err)))
def to_xml(self): """ Convert to D5 syntax from Diablo""" if self.xml is None: if self.json is None: raise NotImplementedError else: raise fault.IdentityFault("%s not initialized with data" % \ self.__class__.__str__) dom = etree.Element( "auth", xmlns="http://docs.openstack.org/identity/api/v2.0") for element in self.xml: dom.append(element) return etree.tostring(dom)
def to_json(self): """ Convert to D5 syntax from Diablo""" if self.json is None: if self.xml is None: raise NotImplementedError else: raise fault.IdentityFault("%s not initialized with data" % \ self.__class__.__str__) d5_data = {"auth": self.json.copy()} if 'auth' in d5_data and 'serviceCatalog' in d5_data['auth']: d5_data['auth']['serviceCatalog'] = \ dict([(s['type'], s['endpoints']) for s in d5_data['auth']['serviceCatalog']]) return json.dumps(d5_data)
def detect_credential_type(req): """Return the credential type name by detecting them in json/xml body""" if req.content_type == "application/xml": dom = etree.Element("root") dom.append(etree.fromstring(req.body)) root = dom.find("{http://docs.openstack.org/identity/api/v2.0}" "auth") if root is None: # Try legacy without wrapper creds = dom.find("*") if creds: logger.warning("Received old syntax credentials not wrapped in" "'auth'") else: creds = root.find("*") if creds is None: raise fault.BadRequestFault("Request is missing credentials") name = creds.tag if "}" in name: #trim away namespace if it is there name = name[name.rfind("}") + 1:] return name elif req.content_type == "application/json": obj = json.loads(req.body) if len(obj) == 0: raise fault.BadRequestFault("Expecting 'auth'") tag = obj.keys()[0] if tag == "auth": if len(obj[tag]) == 0: raise fault.BadRequestFault("Expecting Credentials") for key, value in obj[tag].iteritems(): # pylint: disable=W0612 if key not in ['tenantId', 'tenantName']: return key raise fault.BadRequestFault("Credentials missing from request") else: credentials_type = tag return credentials_type else: logging.debug("Unsupported content-type passed: %s" % req.content_type) raise fault.IdentityFault("I don't understand the content type", code=415)
def to_json(self): """ Returns both Diablo and D5 syntax ("access" and "auth")""" if self.json is None: if self.xml is None: raise NotImplementedError else: raise fault.IdentityFault("%s not initialized with data" % \ self.__class__.__str__) d5_data = self.json.copy() auth = {} for key, value in self.json["access"].iteritems(): auth[key] = copy.copy(value) if "user" in auth: # D5 returns 'username' only user = auth["user"] user["username"] = user["name"] del user["name"] del user["id"] # D5 has 'tenantId' under token token = auth["token"] if 'tenant' in token: tenant = token["tenant"] token["tenantId"] = tenant["id"] if "roles" in auth["user"]: auth["user"]["roleRefs"] = [] rolerefs = auth["user"]["roleRefs"] for role in auth["user"]["roles"]: ref = {} ref["id"] = role["id"] ref["roleId"] = role["name"] if "tenantId" in role: ref["tenantId"] = role["tenantId"] rolerefs.append(ref) del auth["user"]["roles"] d5_data["auth"] = auth return json.dumps(d5_data)