From f1493d5585ea7cdc2d48c8e83f8cfecae14ac821 Mon Sep 17 00:00:00 2001 From: Ramana Juvvadi Date: Sun, 8 May 2011 16:02:22 -0500 Subject: merging changes from sai branch --- keystone/auth_server.py | 110 ++++++++++++++++++++++++++++++++++++++-- keystone/db/sqlalchemy/api.py | 70 ++++++++++++++++++++++++++ keystone/logic/types/tenant.py | 112 ++++++++++++++++++++--------------------- 3 files changed, 230 insertions(+), 62 deletions(-) diff --git a/keystone/auth_server.py b/keystone/auth_server.py index 90651d9d..f766c4eb 100755 --- a/keystone/auth_server.py +++ b/keystone/auth_server.py @@ -359,12 +359,86 @@ class UserController(wsgi.Controller): rval = service.set_user_password(get_auth_token(req), user_id, user, tenant_id) return send_result(204, req, rval) - def set_user_enabled(self, req, user_id,tenant_id): - rval = service.enable_disable_user(get_auth_token(req), user_id, tenant_id) + # To be checked with Abdul not finished yet + def set_user_enabled(self, req, user_id, tenant_id): + user = get_normalized_request_content(users.User_Update, req) + rval = service.enable_disable_user(get_auth_token(req), user_id, user, tenant_id) + return send_result(204, req, rval) + + + +class GroupsController(wsgi.Controller): + + def __init__(self, options): + self.options = options + + def create_group(self, req): + group = get_normalized_request_content(tenants.Group, req) + return send_result(201, req, + service.create_global_group(get_auth_token(req), + group)) + def get_groups(self, req): + marker = None + if "marker" in req.GET: + marker = req.GET["marker"] + + if "limit" in req.GET: + limit = req.GET["limit"] + else: + limit = 10 + + url = '%s://%s:%s%s' % (req.environ['wsgi.url_scheme'], + req.environ.get("SERVER_NAME"), + req.environ.get("SERVER_PORT"), + req.environ['PATH_INFO']) + groups = service.get_global_groups(get_auth_token(req), + marker, limit, url) + return send_result(200, req, groups) + + def get_group(self, req, group_id): + tenant = service.get_global_group(get_auth_token(req), group_id) + return send_result(200, req, tenant) + + def update_group(self, req, group_id): + group = get_normalized_request_content(tenants.Group, req) + rval = service.update_global_group(get_auth_token(req), + group_id, group) + return send_result(200, req, rval) + + def delete_group(self, req, group_id): + rval = service.delete_global_group(get_auth_token(req), group_id) return send_result(204, req, rval) + def get_users_group(self, req, group_id): + marker = None + if "marker" in req.GET: + marker = req.GET["marker"] -class Auth_API(wsgi.Router): + if "limit" in req.GET: + limit = req.GET["limit"] + else: + limit = 10 + + url = '%s://%s:%s%s' % (req.environ['wsgi.url_scheme'], + req.environ.get("SERVER_NAME"), + req.environ.get("SERVER_PORT"), + req.environ['PATH_INFO']) + + users = service.get_users_global_group(get_auth_token(req), + group_id, marker, limit, url) + return send_result(200, req, users) + + + def add_user_group(self, req, group_id, user_id): + return send_result(201, req, + service.add_user_global_group(get_auth_token(req), + group_id, user_id)) + def delete_user_group(self, req, group_id, user_id): + return send_result(204, req, + service.delete_user_global_group(get_auth_token(req), + group_id, user_id)) + +class KeystoneAPI(wsgi.Router): """WSGI entry point for all Keystone Auth API requests.""" def __init__(self, options): @@ -417,6 +491,34 @@ class Auth_API(wsgi.Router): action="update_user", conditions=dict(method=["PUT"])) mapper.connect("/v1.0/tenants/{tenant_id}/users/{user_id}", controller=user_controller, action="delete_user", conditions=dict(method=["DELETE"])) + mapper.connect("/v1.0/tenants/{tenant_id}/users/{user_id}/password", controller=user_controller, + action="set_user_password", conditions=dict(method=["PUT"])) + + # Test this, test failed + mapper.connect("/v1.0/tenants/{tenant_id}/users/{user_id}/enabled", controller=user_controller, + action="set_user_enabled", conditions=dict(method=["PUT"])) + + #Global Groups + groups_controller = GroupsController(options) + mapper.connect("/v1.0/groups", controller=groups_controller, + action="create_group", conditions=dict(method=["POST"])) + mapper.connect("/v1.0/groups", controller=groups_controller, + action="get_groups", conditions=dict(method=["GET"])) + mapper.connect("/v1.0/groups/{group_id}", controller=groups_controller, + action="get_group", conditions=dict(method=["GET"])) + mapper.connect("/v1.0/groups/{group_id}", controller=groups_controller, + action="update_group", conditions=dict(method=["PUT"])) + mapper.connect("/v1.0/groups/{group_id}", controller=groups_controller, + action="delete_group", conditions=dict(method=["DELETE"])) + mapper.connect("/v1.0/groups/{group_id}/users/{user_id}", controller=groups_controller, + action="add_user_group", conditions=dict(method=["PUT"])) + mapper.connect("/v1.0/groups/{group_id}/users/{user_id}", controller=groups_controller, + action="delete_user_group", conditions=dict(method=["DELETE"])) + + #Not working yet, somebody who has touched its models, please handle + mapper.connect("/v1.0/groups/{group_id}/users", controller=groups_controller, + action="get_users_group", conditions=dict(method=["GET"])) + # Miscellaneous Operations @@ -446,4 +548,4 @@ def app_factory(global_conf, **local_conf): conf.update(local_conf) except Exception as err: print err - return Auth_API(conf) + return KeystoneAPI(conf) diff --git a/keystone/db/sqlalchemy/api.py b/keystone/db/sqlalchemy/api.py index 751721f5..049c1bac 100644 --- a/keystone/db/sqlalchemy/api.py +++ b/keystone/db/sqlalchemy/api.py @@ -221,6 +221,22 @@ def user_get_by_group(user_id, group_id, session=None): return result +def user_tenant_group(values): + user_ref = models.UserGroupAssociation() + user_ref.update(values) + user_ref.save() + return user_ref + + +def user_tenant_group_delete(id, group_id, session=None): + if not session: + session = get_session() + with session.begin(): + usertenantgroup_ref = user_get_by_group(id, group_id, session) + session.delete(usertenantgroup_ref) + + + def user_create(values): user_ref = models.User() user_ref.update(values) @@ -252,6 +268,60 @@ def user_update(id, values, session=None): user_ref.update(values) user_ref.save(session=session) +def users_tenant_group_get_page(group_id, marker, limit, session=None): + if not session: + session = get_session() + uga = aliased(models.UserGroupAssociation) + user = aliased(models.User) + if marker: + return session.query(user, uga).join( + (uga, uga.user_id == user.id)).\ + filter(uga.group_id == group_id).\ + filter("id>=:marker").params( + marker='%s' % marker).order_by( + user.id).limit(limit).all() + else: + return session.query(user, uga).\ + join((uga, uga.user_id == user.id)).\ + filter(uga.group_id == group_id).order_by( + user.id).limit(limit).all() +def users_tenant_group_get_page_markers(group_id, marker,limit,session=None): + if not session: + session = get_session() + first = session.query(models.User).order_by(\ + models.User.id).first() + last = session.query(models.User).order_by(\ + models.User.id.desc()).first() + if marker is None: + marker = first.id + next = session.query(models.User).filter_by(\ + group_id=group_id).filter("id > :marker").params(\ + marker = '%s' % marker).order_by(\ + models.User.id).limit(limit).all() + prev=session.query(models.User).filter_by(\ + group_id = group_id).filter("id < :marker").params(\ + marker = '%s' % marker).order_by(\ + models.User.id.desc()).limit(int(limit)).all() + if len(next) == 0: + next = last + else: + for t in next: + next = t + if len(prev) == 0: + prev = first + else: + for t in prev: + prev = t + if prev.id == marker: + prev = None + else: + prev=prev.id + if next.id == last.id: + next = None + else: + next = next.id + return (prev, next) + def group_get(id, session=None): if not session: diff --git a/keystone/logic/types/tenant.py b/keystone/logic/types/tenant.py index 5e933b9b..876a45d8 100644 --- a/keystone/logic/types/tenant.py +++ b/keystone/logic/types/tenant.py @@ -109,14 +109,14 @@ class Tenants(object): def to_xml(self): dom = etree.Element("tenants") - dom.set(u"xmlns","http://docs.openstack.org/idm/api/v1.0") - + dom.set(u"xmlns","http://docs.openstack.org/idm/api/v1.0") + for t in self.values: dom.append(t.to_dom()) - + for t in self.links: dom.append(t.to_dom()) - + return etree.tostring(dom) def to_json(self): @@ -125,15 +125,16 @@ class Tenants(object): return json.dumps({"tenants": {"values": values,"links":links}}) - class Group(object): - "Describes a group in the auth system" + "Describes a group in the auth system" def __init__(self, group_id, description, tenant_id=''): - self.description = description self.group_id = group_id - self.tenant_id = tenant_id + if tenant_id: + self.tenant_id = tenant_id + else: + self.tenant_id = None @staticmethod def from_xml(xml_str): @@ -144,9 +145,8 @@ class Group(object): if root == None: raise fault.BadRequestFault("Expecting Group") group_id = root.get("id") - tenant_id = root.get("tenantId") - - + if root.get("tenantId"): + tenant_id = root.get("tenantId") desc = root.find("{http://docs.openstack.org/idm/api/v1.0}" "description") if desc == None: @@ -159,21 +159,21 @@ class Group(object): def from_json(json_str): try: obj = json.loads(json_str) - + if not "group" in obj: raise fault.BadRequestFault("Expecting group") group = obj["group"] - + if not "id" in group: group_id = None else: group_id = group["id"] - + if not "tenantId" in group: tenantId = None else: tenantId = group["tenantId"] - + if not "description" in group: raise fault.BadRequestFault("Expecting Group Description") description = group["description"] @@ -186,13 +186,9 @@ class Group(object): xmlns="http://docs.openstack.org/idm/api/v1.0") if self.group_id: dom.set("id", self.group_id) - if self.tenant_id: dom.set("tenantId", self.tenant_id) - - desc = etree.Element("description") - desc.text = self.description dom.append(desc) return dom @@ -205,8 +201,8 @@ class Group(object): if self.group_id: group["id"] = self.group_id group["description"] = self.description - group["tenantId"] = self.tenant_id - + if self.tenant_id: + group["tenantId"] = self.tenant_id return {'group': group} def to_json(self): @@ -222,31 +218,38 @@ class Groups(object): def to_xml(self): dom = etree.Element("groups") - dom.set(u"xmlns","http://docs.openstack.org/idm/api/v1.0") - + dom.set(u"xmlns","http://docs.openstack.org/idm/api/v1.0") + for t in self.values: dom.append(t.to_dom()) - + for t in self.links: dom.append(t.to_dom()) - + return etree.tostring(dom) def to_json(self): values = [t.to_dict()["group"] for t in self.values] links = [t.to_dict()["links"] for t in self.links] return json.dumps({"groups": {"values": values,"links":links}}) - - - + + + + + class User(object): - "Describes a user in the auth system" - def __init__(self, user_id, email, group_id, tenant_id, enabled): - + "Describes a user in the auth system" + def __init__(self, user_id, email, enabled, tenant_id='', group_id=''): self.user_id = user_id - - self.tenant_id = tenant_id + if group_id: + self.group_id = group_id + else: + self.group_id = None + if tenant_id: + self.tenant_id = tenant_id + else: + self.tenant_id = None self.email = email self.enabled = enabled and True or False @@ -259,8 +262,6 @@ class User(object): if root == None: raise fault.BadRequestFault("Expecting Group") group_id = root.get("id") - - desc = root.find("{http://docs.openstack.org/idm/api/v1.0}" "description") if desc == None: @@ -273,16 +274,13 @@ class User(object): def from_json(json_str): try: obj = json.loads(json_str) - if not "group" in obj: raise fault.BadRequestFault("Expecting group") group = obj["group"] - if not "id" in group: group_id = None else: group_id = group["id"] - if not "description" in group: raise fault.BadRequestFault("Expecting Group Description") description = group["description"] @@ -290,22 +288,19 @@ class User(object): except (ValueError, TypeError) as e: raise fault.BadRequestFault("Cannot parse Group", str(e)) """ - def to_dom(self): dom = etree.Element("user", xmlns="http://docs.openstack.org/idm/api/v1.0") - if self.group_id: - dom.set("id", self.group_id) - + if self.group_id != None: + dom.set("group_id", self.group_id) + if self.user_id: + dom.set("id", self.user_id) if self.tenant_id: dom.set("tenantId", self.tenant_id) - - if self.tenant_id: + if self.email: dom.set("email", self.email) - - if self.tenant_id: - dom.set("enabled", self.enabled) - + if self.enabled: + dom.set("enabled", string.lower(str(self.enabled))) return dom def to_xml(self): @@ -313,12 +308,13 @@ class User(object): def to_dict(self): user = {} - if self.group_id: - group["id"] = self.group_id - group["email"] = self.email - group["enabled"] = self.enabled - group["tenantId"] = self.tenant_id - + if self.group_id != None: + user["group_id"] = self.group_id + user["id"] = self.user_id + user["email"] = self.email + user["enabled"] = string.lower(str(self.enabled)) + if self.tenant_id: + user["tenantId"] = self.tenant_id return {'user': user} def to_json(self): @@ -334,14 +330,14 @@ class Users(object): def to_xml(self): dom = etree.Element("users") - dom.set(u"xmlns","http://docs.openstack.org/idm/api/v1.0") - + dom.set(u"xmlns","http://docs.openstack.org/idm/api/v1.0") + for t in self.values: dom.append(t.to_dom()) - + for t in self.links: dom.append(t.to_dom()) - + return etree.tostring(dom) def to_json(self): -- cgit