Added v3 auth extension and updated v2 auth extension

This commit is contained in:
Nathan Buckner 2015-08-20 20:14:09 -05:00
parent ed319d1b57
commit c2ea797565
6 changed files with 569 additions and 487 deletions

View File

@ -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
limitations under the License.
"""
from cafe.engine.behaviors import BaseBehavior
from cafe.engine.http.client import AutoMarshallingHTTPClient
from syntribos.extensions.rax_auth.models import auth_models
from syntribos.extensions.rax_auth.auth_config import (
UserAuthConfig, UserConfig)
from syntribos.extensions.identity.models import v2, v3
from syntribos.extensions.identity.config import (
EndpointConfig, UserConfig)
class TokensBehavior(BaseBehavior):
@classmethod
def get_access_data_config(cls, user_config, userauth_config):
return cls.get_access_data(
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,
api_key=user_config.api_key,
serialize_format=userauth_config.serialize_format,
deserialize_format=userauth_config.deserialize_format)
def authenticate_v2(
url, username=None, password=None, tenant_name=None,
tenant_id=None, token=None, domain=None, serialize_format="json",
deserialize_format="json"):
url = '{0}/v2.0/tokens'.format(url)
client = AutoMarshallingHTTPClient(serialize_format, deserialize_format)
client.default_headers["Content-Type"] = "application/{0}".format(
serialize_format)
client.default_headers["Accept"] = "application/{0}".format(
deserialize_format)
@classmethod
def get_access_data(cls, *args, **kwargs):
return cls.authenticate(*args, **kwargs).entity
kwargs = {}
kwargs["tenant_name"] = tenant_name
kwargs["tenant_id"] = tenant_id
@classmethod
def authenticate(
cls, url, username=None, password=None, tenant_name=None,
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)
if password is not None:
password_creds = v2.PasswordCredentials(
username=username, password=password)
client.default_headers["Content-Type"] = "application/{0}".format(
serialize_format)
client.default_headers["Accept"] = "application/{0}".format(
deserialize_format)
request_entity = v2.Auth(
tenant_name=tenant_name, tenant_id=tenant_id,
password_creds=password_creds)
kwargs = {}
kwargs["tenant_name"] = tenant_name
kwargs["tenant_id"] = tenant_id
r = client.request(
"POST", url, request_entity=request_entity,
response_entity_type=v2.AuthResponse)
if password is not None:
kwargs["password_creds"] = auth_models.PasswordCredentials(
username=username, password=password)
if not r.ok:
raise Exception("Failed to authenticate")
if token is not None:
kwargs["token_creds"] = auth_models.Token(id_=token)
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
if r.entity is None:
raise Exception("Failed to parse Auth response Body")
return r
def get_token(section_name):
access_data = TokensBehavior.get_access_data_config(
UserConfig(section_name=section_name), UserAuthConfig())
def authenticate_v2_config(user_config, userauth_config):
return authenticate_v2(
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_
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")

View File

@ -17,7 +17,7 @@ limitations under the License.
from cafe.engine.models.data_interfaces import ConfigSectionInterface
class UserAuthConfig(ConfigSectionInterface):
class EndpointConfig(ConfigSectionInterface):
SECTION_NAME = 'auth'
@property
@ -44,6 +44,10 @@ class UserConfig(ConfigSectionInterface):
def password(self):
return self.get_raw("password")
@property
def user_id(self):
return self.get("user_id")
@property
def tenant_id(self):
return self.get("tenant_id")
@ -62,3 +66,11 @@ class UserConfig(ConfigSectionInterface):
example the admin user needs to use an internal 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")

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)})