summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZiad Sawalha <gihub@highbridgellc.com>2011-06-17 11:48:37 -0700
committerZiad Sawalha <gihub@highbridgellc.com>2011-06-17 11:48:37 -0700
commitaf8e879ea67f7373ea199095124283da585a4bc2 (patch)
tree2ae8588960be2b69aa567c6f58acbb91a3149124
parentc3ac911f7cf70c6e8debc7c31d347795c3c6a7d3 (diff)
parentb93c9b8ebe2b563e8fae0b608a35cc0c887bedc9 (diff)
downloadkeystone-af8e879ea67f7373ea199095124283da585a4bc2.tar.gz
keystone-af8e879ea67f7373ea199095124283da585a4bc2.tar.xz
keystone-af8e879ea67f7373ea199095124283da585a4bc2.zip
Merge pull request #45 from yogirackspace/master
WADL Updates and changes to allow user creation without tenant.
-rw-r--r--doc/guide/src/docbkx/identity.wadl301
-rwxr-xr-x[-rw-r--r--]doc/guide/src/docbkx/xsd/api.xsd1
-rwxr-xr-x[-rw-r--r--]doc/guide/src/docbkx/xsd/baseURLs.xsd17
-rwxr-xr-x[-rw-r--r--]doc/guide/src/docbkx/xsd/roles.xsd29
-rwxr-xr-xdoc/guide/src/docbkx/xsd/user.xsd100
-rwxr-xr-x[-rw-r--r--]keystone/db/sqlalchemy/api/tenant.py0
-rwxr-xr-x[-rw-r--r--]keystone/db/sqlalchemy/api/user.py2
-rwxr-xr-xkeystone/logic/service.py41
-rwxr-xr-xkeystone/test/unit/test_users.py22
9 files changed, 473 insertions, 40 deletions
diff --git a/doc/guide/src/docbkx/identity.wadl b/doc/guide/src/docbkx/identity.wadl
index 4b68f9a7..b153904d 100644
--- a/doc/guide/src/docbkx/identity.wadl
+++ b/doc/guide/src/docbkx/identity.wadl
@@ -27,7 +27,7 @@
<method href="#getExtension"/>
</resource>
</resource>
- <resource id="token" path="token">
+ <resource id="tokens" path="tokens">
<method href="#authenticate" />
<resource id="tokenId" path="{tokenId}">
<param name="X-Auth-Token" style="header" type="xsd:string" required="true"/>
@@ -65,20 +65,49 @@
</resource>
</resource>
</resource>
- <resource id="baseURLs" path="baseURLs">
+
+ <resource id="users" path="users">
+ <param name="X-Auth-Token" style="header" type="xsd:string" required="true"/>
+ <method href="#getUsers" />
+ <method href="#createUser" />
+ <resource id="userId" path="{userId}">
+ <param name="X-Auth-Token" style="header" type="xsd:string" required="true"/>
+ <param name="userId" style="template" type="xsd:string"/>
+ <method href="#getUser" />
+ <method href="#updateUser" />
+ <method href="#deleteUser" />
+ <resource id="enabled" path="enabled">
+ <method href="#setUserEnabled"/>
+ </resource>
+ <resource id="password" path="password">
+ <method href="#setUserPassword"/>
+ </resource>
+ <resource id="tenant" path="tenant">
+ <method href="#setUserTenant"/>
+ </resource>
+ </resource>
+ </resource>
+
+ <resource id="baseURLs" path="baseURLs">
+ <param name="X-Auth-Token" style="header" type="xsd:string" required="true"/>
<method href="#getBaseURLs"/>
<resource id="baseURLId" path="{baseURLId}">
+ <param name="X-Auth-Token" style="header" type="xsd:string" required="true"/>
<param name="baseURLId" style="template" type="xsd:int"/>
<method href="#getBaseURL"/>
</resource>
</resource>
+
<resource id="roles" path="roles">
+ <param name="X-Auth-Token" style="header" type="xsd:string" required="true"/>
<method href="#getRoles"/>
<resource id="roleId" path="{roleId}">
+ <param name="X-Auth-Token" style="header" type="xsd:string" required="true"/>
<param name="roleId" style="template" type="xsd:int"/>
<method href="#getRole"/>
</resource>
</resource>
+
</resource>
</resources>
@@ -267,7 +296,7 @@
</response>
</method>
- <method name="POST" id="createTenant">
+ <method name="PUT" id="createTenant">
<request>
<representation mediaType="application/xml" element="identity:tenant"/>
<representation mediaType="application/json"/>
@@ -384,8 +413,272 @@
</response>
</method>
- <!-- Base URLs -->
+ <!--User Operations-->
+ <method name="GET" id="getUsers">
+ <request>
+ <param name="marker" style="query"
+ required="false" type="xsd:string"/>
+ <param name="limit" style="query"
+ required="false" type="xsd:int"/>
+ </request>
+ <response status="200 203">
+ <representation mediaType="application/xml" element="identity:users"/>
+ <representation mediaType="application/json"/>
+ </response>
+ <response status="401">
+ <representation mediaType="application/xml" element="identity:unauthorized"/>
+ </response>
+ <response status="403">
+ <representation mediaType="application/xml" element="identity:forbidden"/>
+ </response>
+ <response status="400">
+ <representation mediaType="application/xml" element="identity:badRequest"/>
+ </response>
+ <response status="404">
+ <representation mediaType="application/xml" element="identity:itemNotFound"/>
+ </response>
+ <response status="500">
+ <representation mediaType="application/xml" element="identity:identityFault"/>
+ </response>
+ <response status="503">
+ <representation mediaType="application/xml" element="identity:serviceUnavailable"/>
+ </response>
+ <response status="400 401 403 404 500 503">
+ <representation mediaType="application/json"/>
+ </response>
+ </method>
+
+ <method name="PUT" id="createUser">
+ <request>
+ <representation mediaType="application/xml" element="identity:tenant"/>
+ <representation mediaType="application/json"/>
+ </request>
+ <response status="201">
+ <representation mediaType="application/xml" element="identity:tenant"/>
+ <representation mediaType="application/json"/>
+ </response>
+ <response status="401">
+ <representation mediaType="application/xml" element="identity:unauthorized"/>
+ </response>
+ <response status="403">
+ <representation mediaType="application/xml" element="identity:forbidden"/>
+ </response>
+ <response status="400">
+ <representation mediaType="application/xml" element="identity:badRequest"/>
+ </response>
+ <response status="409">
+ <representation mediaType="application/xml" element="identity:tenantConflict"/>
+ </response>
+ <response status="500">
+ <representation mediaType="application/xml" element="identity:identityFault"/>
+ </response>
+ <response status="503">
+ <representation mediaType="application/xml" element="identity:serviceUnavailable"/>
+ </response>
+ <response status="401 403 400 409 500 503">
+ <representation mediaType="application/json"/>
+ </response>
+ </method>
+
+ <method name="GET" id="getUser">
+ <response status="200 203">
+ <representation mediaType="application/xml" element="identity:user"/>
+ <representation mediaType="application/json"/>
+ </response>
+ <response status="401">
+ <representation mediaType="application/xml" element="identity:unauthorized"/>
+ </response>
+ <response status="403">
+ <representation mediaType="application/xml" element="identity:forbidden"/>
+ </response>
+ <response status="400">
+ <representation mediaType="application/xml" element="identity:badRequest"/>
+ </response>
+ <response status="404">
+ <representation mediaType="application/xml" element="identity:itemNotFound"/>
+ </response>
+ <response status="500">
+ <representation mediaType="application/xml" element="identity:identityFault"/>
+ </response>
+ <response status="503">
+ <representation mediaType="application/xml" element="identity:serviceUnavailable"/>
+ </response>
+ <response status="400 401 403 404 500 503">
+ <representation mediaType="application/json"/>
+ </response>
+ </method>
+
+ <method name="PUT" id="updateUser">
+ <request>
+ <representation mediaType="application/xml" element="identity:tenant"/>
+ <representation mediaType="application/json"/>
+ </request>
+ <response status="200">
+ <representation mediaType="application/xml" element="identity:tenant"/>
+ <representation mediaType="application/json"/>
+ </response>
+ <response status="401">
+ <representation mediaType="application/xml" element="identity:unauthorized"/>
+ </response>
+ <response status="403">
+ <representation mediaType="application/xml" element="identity:forbidden"/>
+ </response>
+ <response status="404">
+ <representation mediaType="application/xml" element="identity:itemNotFound"/>
+ </response>
+ <response status="400">
+ <representation mediaType="application/xml" element="identity:badRequest"/>
+ </response>
+ <response status="500">
+ <representation mediaType="application/xml" element="identity:identityFault"/>
+ </response>
+ <response status="503">
+ <representation mediaType="application/xml" element="identity:serviceUnavailable"/>
+ </response>
+ <response status="401 403 404 400 500 503">
+ <representation mediaType="application/json"/>
+ </response>
+ </method>
+
+ <method name="DELETE" id="deleteUser">
+ <response status="204"/>
+ <response status="401">
+ <representation mediaType="application/xml" element="identity:unauthorized"/>
+ </response>
+ <response status="403">
+ <representation mediaType="application/xml" element="identity:forbidden"/>
+ </response>
+ <response status="400">
+ <representation mediaType="application/xml" element="identity:badRequest"/>
+ </response>
+ <response status="404">
+ <representation mediaType="application/xml" element="identity:itemNotFound"/>
+ </response>
+ <response status="500">
+ <representation mediaType="application/xml" element="identity:identityFault"/>
+ </response>
+ <response status="503">
+ <representation mediaType="application/xml" element="identity:serviceUnavailable"/>
+ </response>
+ <response status="400 401 403 404 500 503">
+ <representation mediaType="application/json"/>
+ </response>
+ </method>
+ <method name="PUT" id="setUserEnabled">
+ <request>
+ <representation mediaType="application/xml" element="identity:user">
+ <param name="user" style="plain"
+ path="/" type="identity:UserWithOnlyEnabled"/>
+ </representation>
+ <representation mediaType="application/json"/>
+ </request>
+ <response status="200 203">
+ <representation mediaType="application/xml" element="identity:user">
+ <param name="user" style="plain"
+ path="/" type="identity:UserWithOnlyEnabled"/>
+ </representation>
+ <representation mediaType="application/json"/>
+ </response>
+ <response status="401">
+ <representation mediaType="application/xml" element="identity:unauthorized"/>
+ </response>
+ <response status="403">
+ <representation mediaType="application/xml" element="identity:forbidden"/>
+ </response>
+ <response status="404">
+ <representation mediaType="application/xml" element="identity:itemNotFound"/>
+ </response>
+ <response status="400">
+ <representation mediaType="application/xml" element="identity:badRequest"/>
+ </response>
+ <response status="500">
+ <representation mediaType="application/xml" element="identity:identityFault"/>
+ </response>
+ <response status="503">
+ <representation mediaType="application/xml" element="identity:serviceUnavailable"/>
+ </response>
+ <response status="401 403 404 400 500 503">
+ <representation mediaType="application/json"/>
+ </response>
+ </method>
+
+ <method name="PUT" id="setUserPassword">
+ <request>
+ <representation mediaType="application/xml" element="identity:user">
+ <param name="user" style="plain"
+ path="/" type="identity:UserWithOnlyPassword"/>
+ </representation>
+ <representation mediaType="application/json"/>
+ </request>
+ <response status="200 203">
+ <representation mediaType="application/xml" element="identity:user">
+ <param name="user" style="plain"
+ path="/" type="identity:UserWithOnlyPassword"/>
+ </representation>
+ <representation mediaType="application/json"/>
+ </response>
+ <response status="401">
+ <representation mediaType="application/xml" element="identity:unauthorized"/>
+ </response>
+ <response status="403">
+ <representation mediaType="application/xml" element="identity:forbidden"/>
+ </response>
+ <response status="404">
+ <representation mediaType="application/xml" element="identity:itemNotFound"/>
+ </response>
+ <response status="400">
+ <representation mediaType="application/xml" element="identity:badRequest"/>
+ </response>
+ <response status="500">
+ <representation mediaType="application/xml" element="identity:identityFault"/>
+ </response>
+ <response status="503">
+ <representation mediaType="application/xml" element="identity:serviceUnavailable"/>
+ </response>
+ <response status="401 403 404 400 500 503">
+ <representation mediaType="application/json"/>
+ </response>
+ </method>
+
+ <method name="PUT" id="setUserTenant">
+ <request>
+ <representation mediaType="application/xml" element="identity:user">
+ <param name="user" style="plain"
+ path="/" type="identity:UserWithOnlyTenant"/>
+ </representation>
+ <representation mediaType="application/json"/>
+ </request>
+ <response status="200 203">
+ <representation mediaType="application/xml" element="identity:user">
+ <param name="user" style="plain"
+ path="/" type="identity:UserWithOnlyTenant"/>
+ </representation>
+ <representation mediaType="application/json"/>
+ </response>
+ <response status="401">
+ <representation mediaType="application/xml" element="identity:unauthorized"/>
+ </response>
+ <response status="403">
+ <representation mediaType="application/xml" element="identity:forbidden"/>
+ </response>
+ <response status="404">
+ <representation mediaType="application/xml" element="identity:itemNotFound"/>
+ </response>
+ <response status="400">
+ <representation mediaType="application/xml" element="identity:badRequest"/>
+ </response>
+ <response status="500">
+ <representation mediaType="application/xml" element="identity:identityFault"/>
+ </response>
+ <response status="503">
+ <representation mediaType="application/xml" element="identity:serviceUnavailable"/>
+ </response>
+ <response status="401 403 404 400 500 503">
+ <representation mediaType="application/json"/>
+ </response>
+ </method>
+
<method name="GET" id="getBaseURLs">
<request>
<param name="serviceName" style="query"
diff --git a/doc/guide/src/docbkx/xsd/api.xsd b/doc/guide/src/docbkx/xsd/api.xsd
index a23abd99..ebb1ca3b 100644..100755
--- a/doc/guide/src/docbkx/xsd/api.xsd
+++ b/doc/guide/src/docbkx/xsd/api.xsd
@@ -13,4 +13,5 @@
<include schemaLocation="fault.xsd"/>
<include schemaLocation="baseURLs.xsd"/>
<include schemaLocation="roles.xsd"/>
+ <include schemaLocation="user.xsd"/>
</schema>
diff --git a/doc/guide/src/docbkx/xsd/baseURLs.xsd b/doc/guide/src/docbkx/xsd/baseURLs.xsd
index 54869140..e1d63887 100644..100755
--- a/doc/guide/src/docbkx/xsd/baseURLs.xsd
+++ b/doc/guide/src/docbkx/xsd/baseURLs.xsd
@@ -5,8 +5,15 @@
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:idm="http://docs.openstack.org/identity/api/v2.0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
+ xmlns:atom="http://www.w3.org/2005/Atom"
targetNamespace="http://docs.openstack.org/identity/api/v2.0"
>
+
+ <!-- Import ATOM specific schema definitions -->
+ <import vc:minVersion="1.1" namespace="http://www.w3.org/2005/Atom"
+ schemaLocation="atom/atom.xsd" />
+
<element name="baseURLs" type="idm:BaseURLList">
<annotation>
<xsd:documentation
@@ -145,6 +152,7 @@
</xsd:documentation>
</annotation>
</attribute>
+ <anyAttribute namespace="##other" processContents="lax"/>
</complexType>
<complexType name="BaseURLRef">
@@ -165,22 +173,29 @@
xml:lang="EN"
xmlns="http://www.w3.org/1999/xhtml">
<p>
- A hyperlink refrence to the base URL.
+ A hyperlink reference to the base URL.
</p>
</xsd:documentation>
</annotation>
</attribute>
+ <anyAttribute namespace="##other" processContents="lax"/>
</complexType>
<complexType name="BaseURLList">
<sequence>
<element name="baseURL" type="idm:BaseURL" minOccurs="0" maxOccurs="unbounded"/>
+ <element vc:minVersion="1.1" ref="atom:link" minOccurs="0" maxOccurs="unbounded" />
+ <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
</sequence>
+ <anyAttribute namespace="##other" processContents="lax"/>
</complexType>
<complexType name="BaseURLRefList">
<sequence>
<element name="baseURLRef" type="idm:BaseURLRef" minOccurs="0" maxOccurs="unbounded"/>
+ <element vc:minVersion="1.1" ref="atom:link" minOccurs="0" maxOccurs="unbounded" />
+ <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
</sequence>
+ <anyAttribute namespace="##other" processContents="lax"/>
</complexType>
</schema>
diff --git a/doc/guide/src/docbkx/xsd/roles.xsd b/doc/guide/src/docbkx/xsd/roles.xsd
index 6f8cc207..c01c190a 100644..100755
--- a/doc/guide/src/docbkx/xsd/roles.xsd
+++ b/doc/guide/src/docbkx/xsd/roles.xsd
@@ -4,12 +4,19 @@
elementFormDefault="qualified"
attributeFormDefault="unqualified"
xmlns="http://www.w3.org/2001/XMLSchema"
- xmlns:idm="http://docs.openstack.org/identity/api/v2.0"
+ xmlns:identity="http://docs.openstack.org/identity/api/v2.0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
+ xmlns:atom="http://www.w3.org/2005/Atom"
targetNamespace="http://docs.openstack.org/identity/api/v2.0"
>
+
+ <!-- Import ATOM specific schema definitions -->
+ <import vc:minVersion="1.1" namespace="http://www.w3.org/2005/Atom"
+ schemaLocation="atom/atom.xsd" />
+
<!-- Elements -->
- <element name="roles" type="idm:RoleList" >
+ <element name="roles" type="identity:RoleList" >
<annotation>
<xsd:documentation
xml:lang="EN"
@@ -21,7 +28,7 @@
</annotation>
</element>
- <element name="role" type="idm:Role" >
+ <element name="role" type="identity:Role" >
<annotation>
<xsd:documentation
xml:lang="EN"
@@ -34,7 +41,7 @@
</element>
- <element name="roleRefs" type="idm:RoleRefList" >
+ <element name="roleRefs" type="identity:RoleRefList" >
<annotation>
<xsd:documentation
xml:lang="EN"
@@ -46,7 +53,7 @@
</annotation>
</element>
- <element name="roleRef" type="idm:RoleRef" >
+ <element name="roleRef" type="identity:RoleRef" >
<annotation>
<xsd:documentation
xml:lang="EN"
@@ -63,12 +70,16 @@
<complexType name="Role">
<attribute name="id" type="xsd:string" use="required"/>
<attribute name="description" type="xsd:string" use="optional"/>
+ <anyAttribute namespace="##other" processContents="lax"/>
</complexType>
<complexType name="RoleList">
<sequence>
- <element name="role" type="idm:Role" minOccurs="0" maxOccurs="unbounded"/>
+ <element name="role" type="identity:Role" minOccurs="0" maxOccurs="unbounded"/>
+ <element vc:minVersion="1.1" ref="atom:link" minOccurs="0" maxOccurs="unbounded" />
+ <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
</sequence>
+ <anyAttribute namespace="##other" processContents="lax"/>
</complexType>
@@ -86,12 +97,16 @@
</xsd:documentation>
</annotation>
</attribute>
+ <anyAttribute namespace="##other" processContents="lax"/>
</complexType>
<complexType name="RoleRefList">
<sequence>
- <element name="role" type="idm:RoleRef" minOccurs="0" maxOccurs="unbounded"/>
+ <element name="role" type="identity:RoleRef" minOccurs="0" maxOccurs="unbounded"/>
+ <element vc:minVersion="1.1" ref="atom:link" minOccurs="0" maxOccurs="unbounded" />
+ <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
</sequence>
+ <anyAttribute namespace="##other" processContents="lax"/>
</complexType>
</schema> \ No newline at end of file
diff --git a/doc/guide/src/docbkx/xsd/user.xsd b/doc/guide/src/docbkx/xsd/user.xsd
new file mode 100755
index 00000000..991a1fb4
--- /dev/null
+++ b/doc/guide/src/docbkx/xsd/user.xsd
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?xml-stylesheet type="text/xsl" href="../xslt/schema.xslt"?>
+
+<!-- (C) 2010 Rackspace Hosting, All Rights Reserved -->
+
+<schema
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:identity="http://docs.openstack.org/identity/api/v2.0"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
+ xmlns:atom="http://www.w3.org/2005/Atom"
+ targetNamespace="http://docs.openstack.org/identity/api/v2.0"
+>
+
+ <!-- Import ATOM specific schema definitions -->
+ <import vc:minVersion="1.1" namespace="http://www.w3.org/2005/Atom"
+ schemaLocation="atom/atom.xsd" />
+
+ <element name="users" type="identity:UserList" >
+ <annotation>
+ <xsd:documentation
+ xml:lang="EN"
+ xmlns="http://www.w3.org/2001/XMLSchema">
+ <p>
+ A list of Users.
+ </p>
+ </xsd:documentation>
+ </annotation>
+ </element>
+
+ <element name="user" type="identity:User">
+ <annotation>
+ <xsd:documentation
+ xml:lang="EN"
+ xmlns="http://www.w3.org/2001/XMLSchema">
+ <p>
+ A Keystone User.
+ </p>
+ </xsd:documentation>
+ </annotation>
+ </element>
+
+ <!-- Complex Types -->
+ <complexType name="User">
+ <attribute name="id" type="xsd:ID" use="optional"/>
+ <attribute name="password" type="xsd:string" use="optional"/>
+ <attribute name="tenantId" type="xsd:string" use="optional"/>
+ <attribute name="email" type="xsd:string" use="optional"/>
+ <attribute name="enabled" type="xsd:boolean" default="true" use="optional"/>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </complexType>
+
+ <complexType name="UserWithOnlyEnabled">
+ <complexContent>
+ <restriction base="identity:User">
+ <attribute name="id" type="xsd:ID" use="prohibited"/>
+ <attribute name="password" type="xsd:string" use="prohibited"/>
+ <attribute name="tenantId" type="xsd:string" use="prohibited"/>
+ <attribute name="email" type="xsd:string" use="prohibited"/>
+ <attribute name="enabled" type="xsd:boolean" use="required"/>
+ </restriction>
+ </complexContent>
+ </complexType>
+
+ <complexType name="UserWithOnlyPassword">
+ <complexContent>
+ <restriction base="identity:User">
+ <attribute name="id" type="xsd:ID" use="prohibited"/>
+ <attribute name="tenantId" type="xsd:string" use="prohibited"/>
+ <attribute name="email" type="xsd:string" use="prohibited"/>
+ <attribute name="enabled" type="xsd:boolean" use="prohibited"/>
+ <attribute name="password" type="xsd:string" use="required"/>
+ </restriction>
+ </complexContent>
+ </complexType>
+
+ <complexType name="UserWithOnlyTenant">
+ <complexContent>
+ <restriction base="identity:User">
+ <attribute name="id" type="xsd:ID" use="prohibited"/>
+ <attribute name="email" type="xsd:string" use="prohibited"/>
+ <attribute name="enabled" type="xsd:boolean" use="prohibited"/>
+ <attribute name="password" type="xsd:string" use="prohibited"/>
+ <attribute name="tenantId" type="xsd:string" use="required"/>
+ </restriction>
+ </complexContent>
+ </complexType>
+
+ <complexType name="UserList">
+ <sequence>
+ <element name="user" type="identity:User" minOccurs="0" maxOccurs="unbounded"/>
+ <element vc:minVersion="1.1" ref="atom:link" minOccurs="0" maxOccurs="unbounded" />
+ <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
+ </sequence>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </complexType>
+
+</schema>
diff --git a/keystone/db/sqlalchemy/api/tenant.py b/keystone/db/sqlalchemy/api/tenant.py
index 2af370a0..2af370a0 100644..100755
--- a/keystone/db/sqlalchemy/api/tenant.py
+++ b/keystone/db/sqlalchemy/api/tenant.py
diff --git a/keystone/db/sqlalchemy/api/user.py b/keystone/db/sqlalchemy/api/user.py
index dfc7bbcf..9d2f901f 100644..100755
--- a/keystone/db/sqlalchemy/api/user.py
+++ b/keystone/db/sqlalchemy/api/user.py
@@ -245,7 +245,7 @@ def get_group_by_tenant(id, session=None):
return user_group
-def delete_tenant(id, tenant_id, session=None):
+def delete_tenant_user(id, tenant_id, session=None):
if not session:
session = get_session()
with session.begin():
diff --git a/keystone/logic/service.py b/keystone/logic/service.py
index 5306c1f4..6840a3d7 100755
--- a/keystone/logic/service.py
+++ b/keystone/logic/service.py
@@ -211,6 +211,7 @@ class IdentityService(object):
#
# Tenant Group Operations
#
+
def create_tenant_group(self, admin_token, tenant, group):
self.__validate_token(admin_token)
@@ -430,12 +431,7 @@ class IdentityService(object):
def create_user(self, admin_token, user):
self.__validate_token(admin_token)
- dtenant = db_api.tenant.get(user.tenant_id)
- if dtenant == None:
- raise fault.UnauthorizedFault("Unauthorized")
-
- if not dtenant.enabled:
- raise fault.TenantDisabledFault("Your account has been disabled")
+ dtenant = self.validate_and_fetch_user_tenant(user.tenant_id)
if not isinstance(user, get_users.User):
raise fault.BadRequestFault("Expecting a User")
@@ -461,6 +457,18 @@ class IdentityService(object):
return user
+ def validate_and_fetch_user_tenant(self, tenant_id):
+ if tenant_id != None and len(tenant_id) > 0:
+ dtenant = db_api.tenant.get(tenant_id)
+ if dtenant == None:
+ raise fault.ItemNotFoundFault("The tenant is not found")
+ elif not dtenant.enabled:
+ raise fault.TenantDisabledFault(
+ "Your account has been disabled")
+ return dtenant
+ else:
+ return None
+
def get_tenant_users(self, admin_token, tenant_id, marker, limit, url):
self.__validate_token(admin_token)
@@ -507,7 +515,6 @@ class IdentityService(object):
(url, next, limit)))
return get_users.Users(ts, links)
-
def get_user(self, admin_token, user_id):
self.__validate_token(admin_token)
duser = db_api.user.get(user_id)
@@ -528,10 +535,6 @@ class IdentityService(object):
return get_users.User_Update(None, duser.id, duser.tenant_id, duser.email,
duser.enabled, ts)
- ##
- ## GET Users with Pagination
- ##
-
def update_user(self, admin_token, user_id, user):
self.__validate_token(admin_token)
@@ -610,16 +613,7 @@ class IdentityService(object):
if duser == None:
raise fault.ItemNotFoundFault("The user could not be found")
-
- dtenant = db_api.tenant.get(user.tenant_id)
-
- #Check if tenant exists.If user has passed a tenant that does not exist throw error.
- #If user is trying to update to a tenant that is disabled throw an error.
- if dtenant == None and len(user.tenant_id) > 0:
- raise fault.ItemNotFoundFault("The tenant not found")
- elif not dtenant.enabled:
- raise fault.TenantDisabledFault("Your account has been disabled")
-
+ dtenant = self.validate_and_fetch_user_tenant(user.tenant_id)
values = {'tenant_id': user.tenant_id}
db_api.user.update(user_id, values)
return get_users.User_Update(None, None, user.tenant_id, None, None, None)
@@ -631,7 +625,10 @@ class IdentityService(object):
raise fault.ItemNotFoundFault("The user could not be found")
dtenant = db_api.tenant.get(duser.tenant_id)
- db_api.user.delete_tenant(user_id, dtenant.id)
+ if dtenant != None:
+ db_api.user.delete_tenant_user(user_id, dtenant.id)
+ else:
+ db_api.user.delete(user_id)
return None
def get_user_groups(self, admin_token, user_id, marker, limit,
diff --git a/keystone/test/unit/test_users.py b/keystone/test/unit/test_users.py
index b93672f8..7bde945c 100755
--- a/keystone/test/unit/test_users.py
+++ b/keystone/test/unit/test_users.py
@@ -35,6 +35,7 @@ class UserTest(unittest.TestCase):
self.password = utils.get_password()
self.email = utils.get_email()
self.user = utils.get_user()
+ self.user1 = 'test_user1'
self.userdisabled = utils.get_userdisabled()
self.auth_token = utils.get_auth_token()
self.exp_auth_token = utils.get_exp_auth_token()
@@ -56,19 +57,29 @@ class CreateUserTest(UserTest):
resp = utils.delete_user(self.user, str(self.auth_token))
- resp, content = utils.create_user(self.tenant, 'test_user1',
+ resp, content = utils.create_user(self.tenant, self.user1,
str(self.auth_token))
- self.user = 'test_user1'
+ self.user = self.user1
resp_val = int(resp['status'])
utils.handle_user_resp(self, content, resp_val,
utils.content_type(resp))
self.assertEqual(201, resp_val)
+
+ def test_a_user_witn_no_tenant(self):
+ resp = utils.delete_user(self.user1, str(self.auth_token))
+ resp, content = utils.create_user(None, self.user1,
+ str(self.auth_token))
+ self.user = self.user1
+ resp_val = int(resp['status'])
+ utils.handle_user_resp(self, content, resp_val,
+ utils.content_type(resp))
+ self.assertEqual(201, resp_val)
+
def test_a_user_create_xml(self):
- utils.delete_user_xml(self.tenant, self.user, str(self.auth_token))
- resp, content = utils.create_user_xml(self.tenant, 'test_user1',
+ utils.delete_user_xml(self.tenant, self.user1, str(self.auth_token))
+ resp, content = utils.create_user_xml(self.tenant, self.user1,
str(self.auth_token))
- self.user = 'test_user1'
resp_val = int(resp['status'])
utils.handle_user_resp(self, content, resp_val,
utils.content_type(resp))
@@ -1584,6 +1595,7 @@ class AddUserTest(UserTest):
self.assertEqual(201, resp_val)
def test_add_user_tenant_xml(self):
+ utils.delete_user(self.user, str(self.auth_token))
utils.create_tenant(self.tenant, str(self.auth_token))
resp, content = utils.create_user_xml(self.tenant,
self.user,