Added v3 auth extension and updated v2 auth extension
This commit is contained in:
parent
ed319d1b57
commit
c2ea797565
|
@ -13,78 +13,112 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from cafe.engine.behaviors import BaseBehavior
|
|
||||||
from cafe.engine.http.client import AutoMarshallingHTTPClient
|
from cafe.engine.http.client import AutoMarshallingHTTPClient
|
||||||
|
|
||||||
from syntribos.extensions.rax_auth.models import auth_models
|
from syntribos.extensions.identity.models import v2, v3
|
||||||
from syntribos.extensions.rax_auth.auth_config import (
|
from syntribos.extensions.identity.config import (
|
||||||
UserAuthConfig, UserConfig)
|
EndpointConfig, UserConfig)
|
||||||
|
|
||||||
|
|
||||||
class TokensBehavior(BaseBehavior):
|
def authenticate_v2(
|
||||||
@classmethod
|
url, username=None, password=None, tenant_name=None,
|
||||||
def get_access_data_config(cls, user_config, userauth_config):
|
tenant_id=None, token=None, domain=None, serialize_format="json",
|
||||||
return cls.get_access_data(
|
deserialize_format="json"):
|
||||||
url=user_config.endpoint or userauth_config.endpoint,
|
url = '{0}/v2.0/tokens'.format(url)
|
||||||
username=user_config.username,
|
client = AutoMarshallingHTTPClient(serialize_format, deserialize_format)
|
||||||
password=user_config.password,
|
client.default_headers["Content-Type"] = "application/{0}".format(
|
||||||
tenant_name=user_config.tenant_name,
|
serialize_format)
|
||||||
tenant_id=user_config.tenant_id,
|
client.default_headers["Accept"] = "application/{0}".format(
|
||||||
token=user_config.token,
|
deserialize_format)
|
||||||
api_key=user_config.api_key,
|
|
||||||
serialize_format=userauth_config.serialize_format,
|
|
||||||
deserialize_format=userauth_config.deserialize_format)
|
|
||||||
|
|
||||||
@classmethod
|
kwargs = {}
|
||||||
def get_access_data(cls, *args, **kwargs):
|
kwargs["tenant_name"] = tenant_name
|
||||||
return cls.authenticate(*args, **kwargs).entity
|
kwargs["tenant_id"] = tenant_id
|
||||||
|
|
||||||
@classmethod
|
if password is not None:
|
||||||
def authenticate(
|
password_creds = v2.PasswordCredentials(
|
||||||
cls, url, username=None, password=None, tenant_name=None,
|
username=username, password=password)
|
||||||
tenant_id=None, token=None, api_key=None, rsa_key=None,
|
|
||||||
domain=None, serialize_format="json", deserialize_format="json"):
|
|
||||||
url = '{0}/tokens'.format(url)
|
|
||||||
client = AutoMarshallingHTTPClient(
|
|
||||||
serialize_format, deserialize_format)
|
|
||||||
|
|
||||||
client.default_headers["Content-Type"] = "application/{0}".format(
|
request_entity = v2.Auth(
|
||||||
serialize_format)
|
tenant_name=tenant_name, tenant_id=tenant_id,
|
||||||
client.default_headers["Accept"] = "application/{0}".format(
|
password_creds=password_creds)
|
||||||
deserialize_format)
|
|
||||||
|
|
||||||
kwargs = {}
|
r = client.request(
|
||||||
kwargs["tenant_name"] = tenant_name
|
"POST", url, request_entity=request_entity,
|
||||||
kwargs["tenant_id"] = tenant_id
|
response_entity_type=v2.AuthResponse)
|
||||||
|
|
||||||
if password is not None:
|
if not r.ok:
|
||||||
kwargs["password_creds"] = auth_models.PasswordCredentials(
|
raise Exception("Failed to authenticate")
|
||||||
username=username, password=password)
|
|
||||||
|
|
||||||
if token is not None:
|
if r.entity is None:
|
||||||
kwargs["token_creds"] = auth_models.Token(id_=token)
|
raise Exception("Failed to parse Auth response Body")
|
||||||
|
return r
|
||||||
if api_key is not None:
|
|
||||||
kwargs["api_key_creds"] = auth_models.APIKeyCredentials(
|
|
||||||
username=username, api_key=api_key)
|
|
||||||
|
|
||||||
request_entity = auth_models.Auth(**kwargs)
|
|
||||||
|
|
||||||
r = client.request(
|
|
||||||
"POST", url, request_entity=request_entity,
|
|
||||||
response_entity_type=auth_models.AuthResponse)
|
|
||||||
if not r.ok:
|
|
||||||
raise Exception("Failed to authenticate")
|
|
||||||
|
|
||||||
r.entity = auth_models.AuthResponse.deserialize(
|
|
||||||
r.content, deserialize_format)
|
|
||||||
if r.entity is None:
|
|
||||||
raise Exception("Failed to parse Auth response Body")
|
|
||||||
return r
|
|
||||||
|
|
||||||
|
|
||||||
def get_token(section_name):
|
def authenticate_v2_config(user_config, userauth_config):
|
||||||
access_data = TokensBehavior.get_access_data_config(
|
return authenticate_v2(
|
||||||
UserConfig(section_name=section_name), UserAuthConfig())
|
url=user_config.endpoint or userauth_config.endpoint,
|
||||||
|
username=user_config.username,
|
||||||
|
password=user_config.password,
|
||||||
|
tenant_name=user_config.tenant_name,
|
||||||
|
tenant_id=user_config.tenant_id,
|
||||||
|
token=user_config.token,
|
||||||
|
serialize_format=userauth_config.serialize_format,
|
||||||
|
deserialize_format=userauth_config.deserialize_format)
|
||||||
|
|
||||||
|
|
||||||
|
def get_token_v2(user_section_name=None, endpoint_section_name=None):
|
||||||
|
access_data = authenticate_v2_config(
|
||||||
|
UserConfig(section_name=user_section_name),
|
||||||
|
EndpointConfig(section_name=endpoint_section_name)).entity
|
||||||
return access_data.token.id_
|
return access_data.token.id_
|
||||||
|
|
||||||
|
|
||||||
|
def authenticate_v3(
|
||||||
|
url, username=None, password=None, user_id=None, domain_id=None,
|
||||||
|
domain_name=None, token=None):
|
||||||
|
|
||||||
|
url = '{0}/v3/auth/tokens'.format(url)
|
||||||
|
client = AutoMarshallingHTTPClient("json", "json")
|
||||||
|
client.default_headers["Content-Type"] = "application/json"
|
||||||
|
client.default_headers["Accept"] = "application/json"
|
||||||
|
|
||||||
|
if user_id is not None:
|
||||||
|
domain = None
|
||||||
|
username = None
|
||||||
|
else:
|
||||||
|
domain = v3.Domain(name=domain_name, id_=domain_id)
|
||||||
|
password = v3.Password(user=v3.User(
|
||||||
|
name=username, password=password, id_=user_id, domain=domain))
|
||||||
|
|
||||||
|
if token is not None:
|
||||||
|
kwargs = {"token": v3.Token(id_=token), "methods": ["token"]}
|
||||||
|
else:
|
||||||
|
kwargs = {"password": password, "methods": ["password"]}
|
||||||
|
request_entity = v3.Auth(identity=v3.Identity(**kwargs))
|
||||||
|
|
||||||
|
r = client.request(
|
||||||
|
"POST", url, request_entity=request_entity)
|
||||||
|
|
||||||
|
if not r.ok:
|
||||||
|
raise Exception("Failed to authenticate")
|
||||||
|
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
def authenticate_v3_config(user_config, endpoint_config):
|
||||||
|
return authenticate_v3(
|
||||||
|
url=user_config.endpoint or endpoint_config.endpoint,
|
||||||
|
username=user_config.username,
|
||||||
|
password=user_config.password,
|
||||||
|
user_id=user_config.user_id,
|
||||||
|
domain_id=user_config.domain_id,
|
||||||
|
domain_name=user_config.domain_name,
|
||||||
|
token=user_config.token)
|
||||||
|
|
||||||
|
|
||||||
|
def get_token_v3(user_section_name=None, endpoint_section_name=None):
|
||||||
|
r = authenticate_v3_config(
|
||||||
|
UserConfig(section_name=user_section_name),
|
||||||
|
EndpointConfig(section_name=endpoint_section_name))
|
||||||
|
return r.headers.get("X-Subject-Token")
|
||||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
||||||
from cafe.engine.models.data_interfaces import ConfigSectionInterface
|
from cafe.engine.models.data_interfaces import ConfigSectionInterface
|
||||||
|
|
||||||
|
|
||||||
class UserAuthConfig(ConfigSectionInterface):
|
class EndpointConfig(ConfigSectionInterface):
|
||||||
SECTION_NAME = 'auth'
|
SECTION_NAME = 'auth'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -44,6 +44,10 @@ class UserConfig(ConfigSectionInterface):
|
||||||
def password(self):
|
def password(self):
|
||||||
return self.get_raw("password")
|
return self.get_raw("password")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def user_id(self):
|
||||||
|
return self.get("user_id")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tenant_id(self):
|
def tenant_id(self):
|
||||||
return self.get("tenant_id")
|
return self.get("tenant_id")
|
||||||
|
@ -62,3 +66,11 @@ class UserConfig(ConfigSectionInterface):
|
||||||
example the admin user needs to use an internal endpoint.
|
example the admin user needs to use an internal endpoint.
|
||||||
"""
|
"""
|
||||||
return self.get("endpoint")
|
return self.get("endpoint")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def domain_id(self):
|
||||||
|
return self.get("domain_id")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def domain_name(self):
|
||||||
|
return self.get("domain_name")
|
|
@ -1,424 +0,0 @@
|
||||||
"""
|
|
||||||
Copyright 2015 Rackspace
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import json
|
|
||||||
from xml.etree import ElementTree as ET
|
|
||||||
from cafe.engine.models.base import (
|
|
||||||
AutoMarshallingModel, AutoMarshallingListModel)
|
|
||||||
|
|
||||||
|
|
||||||
class V2_0Constants(object):
|
|
||||||
XML_NS = 'http://docs.openstack.org/identity/api/v2.0'
|
|
||||||
XML_NS_OPENSTACK_COMMON = 'http://docs.openstack.org/common/api/v1.0'
|
|
||||||
XML_NS_XSI = 'http://www.w3.org/2001/XMLSchema-instance'
|
|
||||||
XML_NS_OS_KSADM = \
|
|
||||||
'http://docs.openstack.org/identity/api/ext/OS-KSADM/v1.0'
|
|
||||||
XML_NS_OS_KSEC2 = \
|
|
||||||
'http://docs.openstack.org/identity/api/ext/OS-KSEC2/v1.0'
|
|
||||||
XML_NS_ATOM = 'http://www.w3.org/2005/Atom'
|
|
||||||
|
|
||||||
|
|
||||||
class BaseIdentityModel(AutoMarshallingModel):
|
|
||||||
_namespaces = V2_0Constants
|
|
||||||
|
|
||||||
def __init__(self, kwargs):
|
|
||||||
super(BaseIdentityModel, self).__init__()
|
|
||||||
for var in kwargs:
|
|
||||||
if var != "self" and not var.startswith("_"):
|
|
||||||
setattr(self, var, kwargs.get(var))
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _remove_xml_namespaces(cls, element):
|
|
||||||
for key, value in cls._namespaces.__dict__.items():
|
|
||||||
if key.startswith("__"):
|
|
||||||
continue
|
|
||||||
element = cls._remove_namespace(element, value)
|
|
||||||
return element
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _remove_namespace(cls, element, XML_NS):
|
|
||||||
return cls._remove_xml_etree_namespace(element, XML_NS)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _json_to_obj(cls, serialized_str):
|
|
||||||
data_dict = json.loads(serialized_str)
|
|
||||||
return cls._dict_to_obj(data_dict)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _xml_to_obj(cls, serialized_str):
|
|
||||||
element = ET.fromstring(serialized_str)
|
|
||||||
return cls._xml_ele_to_obj(
|
|
||||||
cls._remove_xml_namespaces(element))
|
|
||||||
|
|
||||||
def _obj_to_json(self):
|
|
||||||
return json.dumps(self._obj_to_dict())
|
|
||||||
|
|
||||||
def _obj_to_xml(self):
|
|
||||||
element = self._obj_to_xml_ele()
|
|
||||||
return ET.tostring(element)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _find(element, tag):
|
|
||||||
if element is None:
|
|
||||||
return ET.Element(None)
|
|
||||||
new_element = element.find(tag)
|
|
||||||
if new_element is None:
|
|
||||||
return ET.Element(None)
|
|
||||||
return new_element
|
|
||||||
|
|
||||||
|
|
||||||
class BaseIdentityListModel(AutoMarshallingListModel, BaseIdentityModel):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class EmptyModel(object):
|
|
||||||
def _obj_to_dict(self):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _obj_to_xml_ele(self):
|
|
||||||
return ET.Element(None)
|
|
||||||
|
|
||||||
|
|
||||||
class AuthResponse(BaseIdentityModel):
|
|
||||||
def __init__(
|
|
||||||
self, token=None, service_catalog=None, user=None, metadata=None):
|
|
||||||
super(AuthResponse, self).__init__(locals())
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _dict_to_obj(cls, data):
|
|
||||||
return cls(
|
|
||||||
token=AuthResponseToken._dict_to_obj(data.get('token')),
|
|
||||||
metadata=Metadata._dict_to_obj(data.get('metadata')),
|
|
||||||
user=User._dict_to_obj(data.get('user')),
|
|
||||||
service_catalog=ServiceCatalog._dict_to_obj(
|
|
||||||
data.get('serviceCatalog')))
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _json_to_obj(cls, serialized_str):
|
|
||||||
data_dict = json.loads(serialized_str)
|
|
||||||
return cls._dict_to_obj(data_dict.get("access"))
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _xml_ele_to_obj(cls, ele):
|
|
||||||
return cls(
|
|
||||||
token=AuthResponseToken._xml_ele_to_obj(ele.find('token')),
|
|
||||||
metadata=Metadata._xml_ele_to_obj(ele.find('metadata')),
|
|
||||||
user=User._xml_ele_to_obj(ele.find('user')),
|
|
||||||
service_catalog=ServiceCatalog._xml_ele_to_obj(
|
|
||||||
ele.find('serviceCatalog')))
|
|
||||||
|
|
||||||
def get_service(self, name):
|
|
||||||
for service in self.service_catalog:
|
|
||||||
if service.name == name:
|
|
||||||
return service
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
class Metadata(BaseIdentityModel):
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _dict_to_obj(cls, data):
|
|
||||||
return data
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _xml_ele_to_obj(cls, ele):
|
|
||||||
return ele.attrib
|
|
||||||
|
|
||||||
|
|
||||||
class Tenant(BaseIdentityModel):
|
|
||||||
def __init__(self, enabled=None, description=None, name=None, id_=None):
|
|
||||||
super(Tenant, self).__init__(locals())
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _xml_ele_to_obj(cls, element):
|
|
||||||
if element.tag.lower() != "tenant":
|
|
||||||
raise Exception("wrong element")
|
|
||||||
enabled = True if element.attrib.get('enabled') == "true" else False
|
|
||||||
description = element.find('description')
|
|
||||||
description = "" if description is None else description.text
|
|
||||||
return cls(enabled=enabled,
|
|
||||||
description=description,
|
|
||||||
name=element.attrib.get('name'),
|
|
||||||
id_=element.attrib.get('id'))
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _dict_to_obj(cls, data_dict):
|
|
||||||
return cls(description=data_dict.get('description'),
|
|
||||||
enabled=data_dict.get('enabled'),
|
|
||||||
id_=data_dict.get('id'),
|
|
||||||
name=data_dict.get('name'))
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _json_to_obj(cls, serialized_str):
|
|
||||||
data_dict = json.loads(serialized_str)
|
|
||||||
return cls._dict_to_obj(data_dict.get('tenant'))
|
|
||||||
|
|
||||||
|
|
||||||
class AuthResponseToken(BaseIdentityModel):
|
|
||||||
def __init__(self, id_=None, issued_at=None, expires=None, tenant=None):
|
|
||||||
super(AuthResponseToken, self).__init__(locals())
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _dict_to_obj(cls, data):
|
|
||||||
return cls(id_=data.get('id'),
|
|
||||||
expires=data.get('expires'),
|
|
||||||
issued_at=data.get('issued_at'),
|
|
||||||
tenant=Tenant._dict_to_obj(data.get('tenant')))
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _xml_ele_to_obj(cls, ele):
|
|
||||||
return cls(id_=ele.attrib.get('id'),
|
|
||||||
expires=ele.attrib.get('expires'),
|
|
||||||
issued_at=ele.attrib.get('issued_at'),
|
|
||||||
tenant=Tenant._xml_ele_to_obj(ele.find('tenant')))
|
|
||||||
|
|
||||||
|
|
||||||
class ServiceCatalog(BaseIdentityListModel):
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _dict_to_obj(cls, data):
|
|
||||||
return ServiceCatalog(
|
|
||||||
[Service._dict_to_obj(service) for service in data])
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _xml_ele_to_obj(cls, element):
|
|
||||||
return ServiceCatalog(
|
|
||||||
[Service._xml_ele_to_obj(service) for service in element])
|
|
||||||
|
|
||||||
|
|
||||||
class User(BaseIdentityModel):
|
|
||||||
def __init__(
|
|
||||||
self, id_=None, name=None, username=None, roles=None,
|
|
||||||
roles_links=None):
|
|
||||||
super(User, self).__init__(locals())
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _dict_to_obj(cls, data):
|
|
||||||
return cls(
|
|
||||||
id_=data.get('id'),
|
|
||||||
name=data.get('name'),
|
|
||||||
username=data.get('username'),
|
|
||||||
roles=Roles._dict_to_obj(data.get('roles')),
|
|
||||||
roles_links=RolesLinks._dict_to_obj(data.get('roles_links')))
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _xml_ele_to_obj(cls, ele):
|
|
||||||
return cls(
|
|
||||||
id_=ele.attrib.get('id'),
|
|
||||||
name=ele.attrib.get('name'),
|
|
||||||
username=ele.attrib.get('username'),
|
|
||||||
roles=Roles._xml_ele_to_obj(ele.findall('role')),
|
|
||||||
roles_links=RolesLinks._xml_ele_to_obj(ele.find('roles_links')))
|
|
||||||
|
|
||||||
|
|
||||||
class Service(BaseIdentityModel):
|
|
||||||
def __init__(
|
|
||||||
self, endpoints=None, endpoints_links=None, name=None, type_=None):
|
|
||||||
super(Service, self).__init__(locals())
|
|
||||||
|
|
||||||
def get_endpoint(self, region):
|
|
||||||
"""
|
|
||||||
Returns the endpoint that matches the provided region,
|
|
||||||
or None if such an endpoint is not found
|
|
||||||
"""
|
|
||||||
for endpoint in self.endpoints:
|
|
||||||
if getattr(endpoint, 'region'):
|
|
||||||
if str(endpoint.region).lower() == str(region).lower():
|
|
||||||
return endpoint
|
|
||||||
return None
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _dict_to_obj(cls, data):
|
|
||||||
return cls(
|
|
||||||
endpoints=Endpoints._dict_to_obj(data.get('endpoints')),
|
|
||||||
endpoints_links=EndpointsLinks._dict_to_obj(
|
|
||||||
data.get('endpoints_links')),
|
|
||||||
name=data.get('name'), type_=data.get('type'))
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _xml_ele_to_obj(cls, ele):
|
|
||||||
return cls(
|
|
||||||
endpoints=Endpoints._xml_ele_to_obj(ele.findall("endpoint")),
|
|
||||||
endpoints_links=EndpointsLinks._xml_ele_to_obj(
|
|
||||||
ele.find('endpoints_links')),
|
|
||||||
name=ele.attrib.get('name'),
|
|
||||||
type_=ele.attrib.get('type'))
|
|
||||||
|
|
||||||
|
|
||||||
class Endpoints(BaseIdentityListModel):
|
|
||||||
@classmethod
|
|
||||||
def _xml_ele_to_obj(cls, elements):
|
|
||||||
if not elements:
|
|
||||||
return cls()
|
|
||||||
return cls([Endpoint._xml_ele_to_obj(endp) for endp in elements])
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _dict_to_obj(cls, data):
|
|
||||||
if not data:
|
|
||||||
return cls()
|
|
||||||
return cls([Endpoint._dict_to_obj(endpoint) for endpoint in data])
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _json_to_obj(cls, string):
|
|
||||||
data = json.loads(string)
|
|
||||||
return cls._dict_to_obj(data.get("endpoints"))
|
|
||||||
|
|
||||||
|
|
||||||
class EndpointsLinks(BaseIdentityListModel):
|
|
||||||
# always returns an empty list since no documentation on endpoint links
|
|
||||||
@classmethod
|
|
||||||
def _dict_to_obj(cls, data):
|
|
||||||
return EndpointsLinks()
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _xml_ele_to_obj(cls, ele):
|
|
||||||
return EndpointsLinks()
|
|
||||||
|
|
||||||
|
|
||||||
class Endpoint(BaseIdentityModel):
|
|
||||||
def __init__(
|
|
||||||
self, region=None, id_=None, public_url=None, admin_url=None,
|
|
||||||
internal_url=None, private_url=None, version_id=None,
|
|
||||||
version_info=None, version_list=None):
|
|
||||||
super(Endpoint, self).__init__(locals())
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _dict_to_obj(cls, data):
|
|
||||||
return cls(region=data.get('region'),
|
|
||||||
id_=data.get('Id'),
|
|
||||||
public_url=data.get('publicURL'),
|
|
||||||
private_url=data.get('privateURL'),
|
|
||||||
admin_url=data.get('adminURL'),
|
|
||||||
internal_url=data.get('internalURL'),
|
|
||||||
version_id=data.get('versionId'),
|
|
||||||
version_info=data.get('versionInfo'),
|
|
||||||
version_list=data.get('versionList'))
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _xml_ele_to_obj(cls, ele):
|
|
||||||
return cls(region=ele.attrib.get('region'),
|
|
||||||
id_=ele.attrib.get('Id'),
|
|
||||||
public_url=ele.attrib.get('publicURL'),
|
|
||||||
private_url=ele.attrib.get('privateURL'),
|
|
||||||
admin_url=ele.attrib.get('adminURL'),
|
|
||||||
internal_url=ele.attrib.get('internalURL'),
|
|
||||||
version_id=ele.attrib.get('versionId'),
|
|
||||||
version_info=ele.attrib.get('versionInfo'),
|
|
||||||
version_list=ele.attrib.get('versionList'))
|
|
||||||
|
|
||||||
|
|
||||||
class Roles(BaseIdentityListModel):
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _xml_ele_to_obj(cls, elements):
|
|
||||||
return Roles(
|
|
||||||
[Role._xml_ele_to_obj(element) for element in elements])
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _dict_to_obj(cls, data):
|
|
||||||
return Roles([Role._dict_to_obj(obj) for obj in data])
|
|
||||||
|
|
||||||
|
|
||||||
class RolesLinks(BaseIdentityListModel):
|
|
||||||
# always returns an empty list since no documentation on role links
|
|
||||||
@classmethod
|
|
||||||
def _dict_to_obj(cls, data):
|
|
||||||
return RolesLinks()
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _xml_ele_to_obj(cls, data):
|
|
||||||
return RolesLinks()
|
|
||||||
|
|
||||||
|
|
||||||
class Role(BaseIdentityModel):
|
|
||||||
def __init__(
|
|
||||||
self, id_=None, name=None, description=None,
|
|
||||||
rax_auth_propagate=None, tenant_id=None, service_id=None):
|
|
||||||
super(Role, self).__init__(locals())
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _xml_ele_to_obj(cls, element):
|
|
||||||
if element is None:
|
|
||||||
return None
|
|
||||||
return cls(
|
|
||||||
id_=element.attrib.get("id"),
|
|
||||||
name=element.attrib.get("name"),
|
|
||||||
description=element.attrib.get("description"))
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _dict_to_obj(cls, data):
|
|
||||||
if data is None:
|
|
||||||
return None
|
|
||||||
return cls(
|
|
||||||
id_=data.get("id"),
|
|
||||||
name=data.get("name"),
|
|
||||||
description=data.get("description"))
|
|
||||||
|
|
||||||
|
|
||||||
class Auth(BaseIdentityModel):
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self, username=None, password=None, tenant_name=None,
|
|
||||||
tenant_id=None, token=None):
|
|
||||||
super(Auth, self).__init__(locals())
|
|
||||||
|
|
||||||
def _obj_to_dict(self):
|
|
||||||
attrs = {
|
|
||||||
"tenantName": self.tenant_name,
|
|
||||||
"tenantId": self.tenant_id,
|
|
||||||
"passwordCredentials": self.password_credentials._obj_to_dict()}
|
|
||||||
return {'auth': self._remove_empty_values(attrs)}
|
|
||||||
|
|
||||||
def _obj_to_xml_ele(self):
|
|
||||||
element = ET.Element('auth')
|
|
||||||
element = self._set_xml_etree_element(
|
|
||||||
element, {"tenantName": self.tenant_name,
|
|
||||||
"tenantId": self.tenant_id})
|
|
||||||
element.append(self.password_credentials._obj_to_xml_ele())
|
|
||||||
return element
|
|
||||||
|
|
||||||
|
|
||||||
class PasswordCredentials(BaseIdentityModel):
|
|
||||||
|
|
||||||
def __init__(self, username=None, password=None):
|
|
||||||
super(PasswordCredentials, self).__init__(locals())
|
|
||||||
|
|
||||||
def _obj_to_dict(self):
|
|
||||||
attrs = {
|
|
||||||
"username": self.username,
|
|
||||||
"password": self.password}
|
|
||||||
return self._remove_empty_values(attrs)
|
|
||||||
|
|
||||||
def _obj_to_xml_ele(self):
|
|
||||||
element = ET.Element('passwordCredentials')
|
|
||||||
attrs = {
|
|
||||||
"username": self.username,
|
|
||||||
"password": self.password}
|
|
||||||
return self._set_xml_etree_element(element, attrs)
|
|
||||||
|
|
||||||
|
|
||||||
class Token(BaseIdentityModel):
|
|
||||||
def __init__(self, id_=None):
|
|
||||||
super(Token, self).__init__(locals())
|
|
||||||
|
|
||||||
def _obj_to_dict(self):
|
|
||||||
attrs = {"id": self.id_}
|
|
||||||
return self._remove_empty_values(attrs)
|
|
||||||
|
|
||||||
def _obj_to_xml_ele(self):
|
|
||||||
element = ET.Element('token')
|
|
||||||
attrs = {"id": self.id_}
|
|
||||||
return self._set_xml_etree_element(element, attrs)
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
import json
|
||||||
|
import six
|
||||||
|
from xml.etree import ElementTree as ET
|
||||||
|
|
||||||
|
from cafe.engine.models.base import AutoMarshallingModel
|
||||||
|
|
||||||
|
|
||||||
|
class Namespaces(object):
|
||||||
|
XMLNS_XSI = "http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
XMLNS = "http://docs.openstack.org/identity/api/v2.0"
|
||||||
|
XMLNS_KSKEY = "http://docs.rackspace.com/identity/api/ext/RAX-KSKEY/v1.0"
|
||||||
|
XMLNS_RAX_AUTH = "http://docs.rackspace.com/identity/api/ext/RAX-AUTH/v1.0"
|
||||||
|
|
||||||
|
|
||||||
|
class BaseIdentityModel(AutoMarshallingModel):
|
||||||
|
_namespaces = Namespaces
|
||||||
|
|
||||||
|
def __init__(self, kwargs):
|
||||||
|
super(BaseIdentityModel, self).__init__()
|
||||||
|
for k, v in kwargs.items():
|
||||||
|
if k != "self" and not k.startswith("_"):
|
||||||
|
setattr(self, k, v)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _remove_xml_namespaces(cls, element):
|
||||||
|
for key, value in vars(cls._namespaces).items():
|
||||||
|
if key.startswith("__"):
|
||||||
|
continue
|
||||||
|
element = cls._remove_xml_etree_namespace(element, value)
|
||||||
|
return element
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _json_to_obj(cls, serialized_str):
|
||||||
|
data_dict = json.loads(serialized_str, strict=False)
|
||||||
|
return cls._dict_to_obj(data_dict)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _xml_to_obj(cls, serialized_str, encoding="iso-8859-2"):
|
||||||
|
parser = ET.XMLParser(encoding=encoding)
|
||||||
|
element = ET.fromstring(serialized_str, parser=parser)
|
||||||
|
return cls._xml_ele_to_obj(cls._remove_xml_namespaces(element))
|
||||||
|
|
||||||
|
def _obj_to_json(self):
|
||||||
|
return json.dumps(self._obj_to_dict())
|
||||||
|
|
||||||
|
def _obj_to_xml(self):
|
||||||
|
element = self._obj_to_xml_ele()
|
||||||
|
element.attrib["xmlns"] = self._namespaces.XMLNS
|
||||||
|
return ET.tostring(element)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _find(element, tag):
|
||||||
|
if element is None:
|
||||||
|
return ET.Element(None)
|
||||||
|
new_element = element.find(tag)
|
||||||
|
if new_element is None:
|
||||||
|
return ET.Element(None)
|
||||||
|
return new_element
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _build_list_model(data, field_name, model):
|
||||||
|
if data is None:
|
||||||
|
return []
|
||||||
|
if isinstance(data, dict):
|
||||||
|
if data.get(field_name) is None:
|
||||||
|
return []
|
||||||
|
return [model._dict_to_obj(tmp) for tmp in data.get(field_name)]
|
||||||
|
return [model._xml_ele_to_obj(tmp) for tmp in data.findall(field_name)]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _build_list(items, element=None):
|
||||||
|
if element is None:
|
||||||
|
if items is None:
|
||||||
|
return []
|
||||||
|
return [item._obj_to_dict() for item in items]
|
||||||
|
else:
|
||||||
|
if items is None:
|
||||||
|
return element
|
||||||
|
for item in items:
|
||||||
|
element.append(item._obj_to_xml_ele())
|
||||||
|
return element
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _create_text_element(name, text):
|
||||||
|
element = ET.Element(name)
|
||||||
|
if text is True or text is False:
|
||||||
|
element.text = str(text).lower()
|
||||||
|
elif text is None:
|
||||||
|
return ET.Element(None)
|
||||||
|
else:
|
||||||
|
element.text = str(text)
|
||||||
|
return element
|
||||||
|
|
||||||
|
def __ne__(self, obj):
|
||||||
|
return not self.__eq__(obj)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _remove_empty_values(cls, data):
|
||||||
|
"""Returns a new dictionary based on 'dictionary', minus any keys with
|
||||||
|
values that evaluate to False
|
||||||
|
"""
|
||||||
|
if isinstance(data, dict):
|
||||||
|
return dict(
|
||||||
|
(k, v) for k, v in six.iteritems(data) if v not in (
|
||||||
|
[], {}, None))
|
||||||
|
elif isinstance(data, ET.Element):
|
||||||
|
if data.attrib:
|
||||||
|
data.attrib = cls._remove_empty_values(data.attrib)
|
||||||
|
data._children = [
|
||||||
|
c for c in data._children if c.tag is not None and (
|
||||||
|
c.attrib or c.text is not None or c._children)]
|
||||||
|
return data
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _get_sub_model(model, json=True):
|
||||||
|
if json:
|
||||||
|
if model is not None:
|
||||||
|
return model._obj_to_dict()
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
if model is not None:
|
||||||
|
return model._obj_to_xml_ele()
|
||||||
|
else:
|
||||||
|
return ET.Element(None)
|
|
@ -0,0 +1,237 @@
|
||||||
|
"""
|
||||||
|
Copyright 2015 Rackspace
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
"""
|
||||||
|
import json
|
||||||
|
from xml.etree import ElementTree as ET
|
||||||
|
|
||||||
|
from syntribos.extensions.identity.models.base import BaseIdentityModel
|
||||||
|
|
||||||
|
|
||||||
|
class AuthResponse(BaseIdentityModel):
|
||||||
|
def __init__(
|
||||||
|
self, token=None, service_catalog=None, user=None, metadata=None):
|
||||||
|
super(AuthResponse, self).__init__(locals())
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _dict_to_obj(cls, data):
|
||||||
|
return cls(
|
||||||
|
token=Token._dict_to_obj(data.get('token')),
|
||||||
|
metadata=Metadata._dict_to_obj(data.get('metadata')),
|
||||||
|
user=User._dict_to_obj(data.get('user')),
|
||||||
|
service_catalog=cls._build_list_model(
|
||||||
|
data, "serviceCatalog", Service))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _json_to_obj(cls, serialized_str):
|
||||||
|
data_dict = json.loads(serialized_str)
|
||||||
|
return cls._dict_to_obj(data_dict.get("access"))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _xml_ele_to_obj(cls, data):
|
||||||
|
return cls(
|
||||||
|
service_catalog=cls._build_list_model(
|
||||||
|
cls._find(data, "serviceCatalog"), "service", Service),
|
||||||
|
token_model=Token._xml_ele_to_obj(cls._find(data, "token")),
|
||||||
|
user_model=User._xml_ele_to_obj(cls._find(data, "user")))
|
||||||
|
|
||||||
|
def get_service(self, name):
|
||||||
|
for service in self.service_catalog:
|
||||||
|
if service.name == name:
|
||||||
|
return service
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class Metadata(BaseIdentityModel):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _dict_to_obj(cls, data):
|
||||||
|
return data
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _xml_ele_to_obj(cls, data):
|
||||||
|
return data.attrib
|
||||||
|
|
||||||
|
|
||||||
|
class Tenant(BaseIdentityModel):
|
||||||
|
def __init__(self, enabled=None, description=None, name=None, id_=None):
|
||||||
|
super(Tenant, self).__init__(locals())
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _xml_ele_to_obj(cls, data):
|
||||||
|
description = data.findtext('description')
|
||||||
|
return cls(
|
||||||
|
name=data.attrib.get("name"),
|
||||||
|
id_=data.attrib.get("id"),
|
||||||
|
enabled=True if data.attrib.get('enabled') == "true" else False,
|
||||||
|
description=description)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _dict_to_obj(cls, data_dict):
|
||||||
|
return cls(description=data_dict.get('description'),
|
||||||
|
enabled=data_dict.get('enabled'),
|
||||||
|
id_=data_dict.get('id'),
|
||||||
|
name=data_dict.get('name'))
|
||||||
|
|
||||||
|
|
||||||
|
class Token(BaseIdentityModel):
|
||||||
|
def __init__(self, id_=None, issued_at=None, expires=None, tenant=None):
|
||||||
|
super(Token, self).__init__(locals())
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _dict_to_obj(cls, data):
|
||||||
|
return cls(id_=data.get('id'),
|
||||||
|
expires=data.get('expires'),
|
||||||
|
issued_at=data.get('issued_at'),
|
||||||
|
tenant=Tenant._dict_to_obj(data.get('tenant')))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _xml_ele_to_obj(cls, data):
|
||||||
|
return cls(id_=data.attrib.get('id'),
|
||||||
|
expires=data.attrib.get('expires'),
|
||||||
|
issued_at=data.attrib.get('issued_at'),
|
||||||
|
tenant=Tenant._xml_ele_to_obj(data.find('tenant')))
|
||||||
|
|
||||||
|
|
||||||
|
class User(BaseIdentityModel):
|
||||||
|
def __init__(
|
||||||
|
self, id_=None, name=None, username=None, roles=None):
|
||||||
|
super(User, self).__init__(locals())
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _dict_to_obj(cls, data):
|
||||||
|
return cls(
|
||||||
|
id_=data.get('id'),
|
||||||
|
name=data.get('name'),
|
||||||
|
username=data.get('username'),
|
||||||
|
roles=cls._build_list_model(data, "roles", Role))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _xml_ele_to_obj(cls, data):
|
||||||
|
return cls(
|
||||||
|
id_=data.attrib.get('id'),
|
||||||
|
name=data.attrib.get('name'),
|
||||||
|
username=data.attrib.get('username'),
|
||||||
|
roles=cls._build_list_model(
|
||||||
|
cls._find(data, "roles"), "role", Role))
|
||||||
|
|
||||||
|
|
||||||
|
class Service(BaseIdentityModel):
|
||||||
|
def __init__(
|
||||||
|
self, endpoints=None, name=None, type_=None):
|
||||||
|
super(Service, self).__init__(locals())
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _dict_to_obj(cls, data):
|
||||||
|
return cls(
|
||||||
|
endpoints=cls._build_list_model(data, "endpoints", Endpoint),
|
||||||
|
name=data.get("name"), type_=data.get("type"))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _xml_ele_to_obj(cls, data):
|
||||||
|
return cls(
|
||||||
|
endpoints=cls._build_list_model(data, "endpoint", Endpoint),
|
||||||
|
name=data.attrib.get("name"), type_=data.attrib.get("type"))
|
||||||
|
|
||||||
|
|
||||||
|
class Endpoint(BaseIdentityModel):
|
||||||
|
def __init__(
|
||||||
|
self, region=None, id_=None, public_url=None, admin_url=None,
|
||||||
|
internal_url=None, private_url=None, version_id=None,
|
||||||
|
version_info=None, version_list=None):
|
||||||
|
super(Endpoint, self).__init__(locals())
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _dict_to_obj(cls, data):
|
||||||
|
return cls(region=data.get('region'),
|
||||||
|
id_=data.get('Id'),
|
||||||
|
public_url=data.get('publicURL'),
|
||||||
|
private_url=data.get('privateURL'),
|
||||||
|
admin_url=data.get('adminURL'),
|
||||||
|
internal_url=data.get('internalURL'),
|
||||||
|
version_id=data.get('versionId'),
|
||||||
|
version_info=data.get('versionInfo'),
|
||||||
|
version_list=data.get('versionList'))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _xml_ele_to_obj(cls, ele):
|
||||||
|
return cls(region=ele.attrib.get('region'),
|
||||||
|
id_=ele.attrib.get('Id'),
|
||||||
|
public_url=ele.attrib.get('publicURL'),
|
||||||
|
private_url=ele.attrib.get('privateURL'),
|
||||||
|
admin_url=ele.attrib.get('adminURL'),
|
||||||
|
internal_url=ele.attrib.get('internalURL'),
|
||||||
|
version_id=ele.attrib.get('versionId'),
|
||||||
|
version_info=ele.attrib.get('versionInfo'),
|
||||||
|
version_list=ele.attrib.get('versionList'))
|
||||||
|
|
||||||
|
|
||||||
|
class Role(BaseIdentityModel):
|
||||||
|
def __init__(
|
||||||
|
self, id_=None, name=None, description=None,
|
||||||
|
tenant_id=None, service_id=None):
|
||||||
|
super(Role, self).__init__(locals())
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _xml_ele_to_obj(cls, element):
|
||||||
|
if element is None:
|
||||||
|
return None
|
||||||
|
return cls(
|
||||||
|
id_=element.attrib.get("id"),
|
||||||
|
name=element.attrib.get("name"),
|
||||||
|
description=element.attrib.get("description"))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _dict_to_obj(cls, data):
|
||||||
|
if data is None:
|
||||||
|
return None
|
||||||
|
return cls(
|
||||||
|
id_=data.get("id"),
|
||||||
|
name=data.get("name"),
|
||||||
|
description=data.get("description"))
|
||||||
|
|
||||||
|
|
||||||
|
class Auth(BaseIdentityModel):
|
||||||
|
def __init__(
|
||||||
|
self, password_creds=None, tenant_id=None, tenant_name=None):
|
||||||
|
super(Auth, self).__init__(locals())
|
||||||
|
|
||||||
|
def _obj_to_dict(self):
|
||||||
|
dic = {}
|
||||||
|
dic["passwordCredentials"] = self._get_sub_model(
|
||||||
|
self.password_creds)
|
||||||
|
dic["tenantId"] = self.tenant_id
|
||||||
|
dic["tenantName"] = self.tenant_name
|
||||||
|
return {"auth": self._remove_empty_values(dic)}
|
||||||
|
|
||||||
|
def _obj_to_xml_ele(self):
|
||||||
|
ele = ET.Element("auth")
|
||||||
|
ele.append(self._get_sub_model(self.password_creds, False))
|
||||||
|
ele.attrib["tenantId"] = self.tenant_id
|
||||||
|
return self._remove_empty_values(ele)
|
||||||
|
|
||||||
|
|
||||||
|
class PasswordCredentials(BaseIdentityModel):
|
||||||
|
def __init__(self, username=None, password=None):
|
||||||
|
super(PasswordCredentials, self).__init__(locals())
|
||||||
|
|
||||||
|
def _obj_to_dict(self):
|
||||||
|
dic = {"username": self.username, "password": self.password}
|
||||||
|
return self._remove_empty_values(dic)
|
||||||
|
|
||||||
|
def _obj_to_xml_ele(self):
|
||||||
|
ele = ET.Element("passwordCredentials")
|
||||||
|
ele.attrib["username"] = self.username
|
||||||
|
ele.attrib["password"] = self.password
|
||||||
|
return self._remove_empty_values(ele)
|
|
@ -0,0 +1,98 @@
|
||||||
|
"""
|
||||||
|
Copyright 2015 Rackspace
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
"""
|
||||||
|
from syntribos.extensions.identity.models.base import BaseIdentityModel
|
||||||
|
|
||||||
|
|
||||||
|
class Auth(BaseIdentityModel):
|
||||||
|
def __init__(
|
||||||
|
self, identity=None, scope=None):
|
||||||
|
super(Auth, self).__init__(locals())
|
||||||
|
|
||||||
|
def _obj_to_dict(self):
|
||||||
|
return {"auth": self._remove_empty_values({
|
||||||
|
"identity": self._get_sub_model(self.identity),
|
||||||
|
"scope": self._get_sub_model(self.scope)})}
|
||||||
|
|
||||||
|
|
||||||
|
class Identity(BaseIdentityModel):
|
||||||
|
def __init__(self, token=None, password=None, methods=None):
|
||||||
|
super(Identity, self).__init__(locals())
|
||||||
|
|
||||||
|
def _obj_to_dict(self):
|
||||||
|
return self._remove_empty_values({
|
||||||
|
"methods": self.methods or [],
|
||||||
|
"password": self._get_sub_model(self.password),
|
||||||
|
"token": self._get_sub_model(self.token)})
|
||||||
|
|
||||||
|
|
||||||
|
class Password(BaseIdentityModel):
|
||||||
|
def __init__(self, user=None):
|
||||||
|
super(Password, self).__init__(locals())
|
||||||
|
|
||||||
|
def _obj_to_dict(self):
|
||||||
|
return self._remove_empty_values({
|
||||||
|
"user": self._get_sub_model(self.user)})
|
||||||
|
|
||||||
|
|
||||||
|
class User(BaseIdentityModel):
|
||||||
|
def __init__(self, id_=None, password=None, name=None, domain=None):
|
||||||
|
super(User, self).__init__(locals())
|
||||||
|
|
||||||
|
def _obj_to_dict(self):
|
||||||
|
return self._remove_empty_values({
|
||||||
|
"id": self.id_,
|
||||||
|
"password": self.password,
|
||||||
|
"name": self.name,
|
||||||
|
"domain": self._get_sub_model(self.domain)})
|
||||||
|
|
||||||
|
|
||||||
|
class Token(BaseIdentityModel):
|
||||||
|
def __init__(self, id_=None):
|
||||||
|
super(Token, self).__init__(locals())
|
||||||
|
|
||||||
|
def _obj_to_dict(self):
|
||||||
|
return self._remove_empty_values({"id": self.id_})
|
||||||
|
|
||||||
|
|
||||||
|
class Scope(BaseIdentityModel):
|
||||||
|
def __init__(self, project=None, domain=None):
|
||||||
|
super(Scope, self).__init__(locals())
|
||||||
|
|
||||||
|
def _obj_to_dict(self):
|
||||||
|
return self._remove_empty_values({
|
||||||
|
"project": self._get_sub_model(self.project),
|
||||||
|
"domain": self._get_sub_model(self.domain)})
|
||||||
|
|
||||||
|
|
||||||
|
class Domain(BaseIdentityModel):
|
||||||
|
def __init__(self, name=None, id_=None):
|
||||||
|
super(Domain, self).__init__(locals())
|
||||||
|
|
||||||
|
def _obj_to_dict(self):
|
||||||
|
return self._remove_empty_values({
|
||||||
|
"name": self.name,
|
||||||
|
"id": self.id_})
|
||||||
|
|
||||||
|
|
||||||
|
class Project(Domain):
|
||||||
|
def __init__(self, name=None, id_=None, domain=None):
|
||||||
|
super(Project, self).__init__(locals())
|
||||||
|
|
||||||
|
def _obj_to_dict(self):
|
||||||
|
return self._remove_empty_values({
|
||||||
|
"name": self.name,
|
||||||
|
"id": self.id_,
|
||||||
|
"domain": self._get_sub_model(self.domain)})
|
Loading…
Reference in New Issue