Skip to content

Commit

Permalink
Keystone server support for user groups
Browse files Browse the repository at this point in the history
This implements the server side of groups of users.  This
set of code provides all the crud functionality for groups as
well as the corresponding support for role assignments.

blueprint user-groups

The following deficiencies existing with the current version and
will be corrected ahead of the final Grizzly release:

1) There is only placeholder support for LDAP (Bug #1092187)
2) Domain role grants are accepted but not yet honored (Bug #1093248)
3) Token invalidation does not occur with group changes (Bug #1093493)

This update also fills in missing v3 grant unit testing and v3 grant
support within the kvs backend.  In addition, there is a fix for
Bug #1092200 (uncaught exception when listing grants)

DocImpact

Change-Id: Ibd1783b04b2d7804eff90312e5ef591dca4d0695
  • Loading branch information
henrynash committed Jan 8, 2013
1 parent 9460ff5 commit 4fae928
Show file tree
Hide file tree
Showing 20 changed files with 1,669 additions and 106 deletions.
4 changes: 4 additions & 0 deletions keystone/clean.py
Expand Up @@ -55,3 +55,7 @@ def tenant_name(name):

def user_name(name):
return check_name('User', name)


def group_name(name):
return check_name('Group', name)
17 changes: 17 additions & 0 deletions keystone/common/models.py
Expand Up @@ -99,6 +99,23 @@ class User(Model):
optional_keys = ('password', 'description', 'email', 'enabled')


class Group(Model):
"""Group object.
Required keys:
id
name
Optional keys:
domain_id
description
"""

required_keys = ('id', 'name')
optional_keys = ('domain_id', 'description')


class Tenant(Model):
"""Tenant object.
Expand Down
93 changes: 93 additions & 0 deletions keystone/common/sql/migrate_repo/versions/013_add_group_tables.py
@@ -0,0 +1,93 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2012 OpenStack LLC
#
# 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 sqlalchemy as sql


def upgrade(migrate_engine):
meta = sql.MetaData()
meta.bind = migrate_engine

sql.Table('domain', meta, autoload=True)
group_table = sql.Table(
'group',
meta,
sql.Column('id', sql.String(64), primary_key=True),
sql.Column('domain_id', sql.String(64), sql.ForeignKey('domain.id')),
sql.Column('name', sql.String(64), unique=True, nullable=False),
sql.Column('description', sql.Text()),
sql.Column('extra', sql.Text()))
group_table.create(migrate_engine, checkfirst=True)

sql.Table('user', meta, autoload=True)
user_group_membership_table = sql.Table(
'user_group_membership',
meta,
sql.Column(
'user_id',
sql.String(64),
sql.ForeignKey('user.id'),
primary_key=True),
sql.Column(
'group_id',
sql.String(64),
sql.ForeignKey('group.id'),
primary_key=True))
user_group_membership_table.create(migrate_engine, checkfirst=True)

sql.Table('tenant', meta, autoload=True)
group_project_metadata_table = sql.Table(
'group_project_metadata',
meta,
sql.Column(
'group_id',
sql.String(64),
sql.ForeignKey('group.id'),
primary_key=True),
sql.Column(
'project_id',
sql.String(64),
sql.ForeignKey('tenant.id'),
primary_key=True),
sql.Column('data', sql.Text()))
group_project_metadata_table.create(migrate_engine, checkfirst=True)

group_domain_metadata_table = sql.Table(
'group_domain_metadata',
meta,
sql.Column(
'group_id',
sql.String(64),
sql.ForeignKey('group.id'),
primary_key=True),
sql.Column(
'domain_id',
sql.String(64),
sql.ForeignKey('domain.id'),
primary_key=True),
sql.Column('data', sql.Text()))
group_domain_metadata_table.create(migrate_engine, checkfirst=True)


def downgrade(migrate_engine):
meta = sql.MetaData()
meta.bind = migrate_engine

tables = ['user_group_membership', 'group_project_metadata',
'group_domain_metadata', 'group']
for t in tables:
table = sql.Table(t, meta, autoload=True)
table.drop(migrate_engine, checkfirst=True)
11 changes: 11 additions & 0 deletions keystone/config.py
Expand Up @@ -226,6 +226,17 @@ def register_cli_int(*args, **kw):
register_bool('role_allow_update', group='ldap', default=True)
register_bool('role_allow_delete', group='ldap', default=True)

register_str('group_tree_dn', group='ldap', default=None)
register_str('group_filter', group='ldap', default=None)
register_str('group_objectclass', group='ldap', default='groupOfNames')
register_str('group_id_attribute', group='ldap', default='cn')
register_str('group_name_attribute', group='ldap', default='ou')
register_str('group_member_attribute', group='ldap', default='member')
register_str('group_desc_attribute', group='ldap', default='desc')
register_list('group_attribute_ignore', group='ldap', default='')
register_bool('group_allow_create', group='ldap', default=True)
register_bool('group_allow_update', group='ldap', default=True)
register_bool('group_allow_delete', group='ldap', default=True)
#pam
register_str('url', group='pam', default=None)
register_str('userid', group='pam', default=None)
Expand Down
4 changes: 4 additions & 0 deletions keystone/exception.py
Expand Up @@ -148,6 +148,10 @@ class UserNotFound(NotFound):
"""Could not find user: %(user_id)s"""


class GroupNotFound(NotFound):
"""Could not find group: %(group_id)s"""


class Conflict(Error):
"""Conflict occurred attempting to store %(type)s.
Expand Down

0 comments on commit 4fae928

Please sign in to comment.