Skip to content

Commit

Permalink
Merge "normalize identity"
Browse files Browse the repository at this point in the history
  • Loading branch information
Jenkins authored and openstack-gerrit committed Nov 27, 2012
2 parents d970e5f + 1012bd4 commit ede63fb
Show file tree
Hide file tree
Showing 9 changed files with 290 additions and 12 deletions.
1 change: 1 addition & 0 deletions keystone/common/sql/core.py
Expand Up @@ -46,6 +46,7 @@
IntegrityError = sql.exc.IntegrityError
NotFound = sql.orm.exc.NoResultFound
Boolean = sql.Boolean
Text = sql.Text


def set_global_engine(engine):
Expand Down
@@ -0,0 +1,61 @@
# 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 json
import string

from sqlalchemy import Column, MetaData, String, Table, Text, types
from sqlalchemy.orm import sessionmaker


#this won't work on sqlite. It doesn't support dropping columns
def downgrade_user_table(meta, migrate_engine):
user_table = Table('user', meta, autoload=True)
user_table.columns["password"].drop()
user_table.columns["enabled"].drop()


def downgrade_tenant_table(meta, migrate_engine):
tenant_table = Table('tenant', meta, autoload=True)
tenant_table.columns["description"].drop()
tenant_table.columns["enabled"].drop()


def upgrade_user_table(meta, migrate_engine):
user_table = Table('user', meta, autoload=True)
user_table.create_column(Column("password", String(128)))
user_table.create_column(Column("enabled", types.Boolean,
default=True))


def upgrade_tenant_table(meta, migrate_engine):
tenant_table = Table('tenant', meta, autoload=True)
tenant_table.create_column(Column("description", Text()))
tenant_table.create_column(Column("enabled", types.Boolean))


def upgrade(migrate_engine):
meta = MetaData()
meta.bind = migrate_engine
upgrade_user_table(meta, migrate_engine)
upgrade_tenant_table(meta, migrate_engine)


def downgrade(migrate_engine):
meta = MetaData()
meta.bind = migrate_engine
downgrade_user_table(meta, migrate_engine)
downgrade_tenant_table(meta, migrate_engine)
@@ -0,0 +1,5 @@
-- not supported by sqlite, but should be:
-- alter TABLE tenant drop column description;
-- alter TABLE tenant drop column enabled;
-- The downgrade process will fail without valid SQL in this file
select count(*) from tenant;
@@ -0,0 +1,146 @@
# 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 json
import string

from sqlalchemy import Column, MetaData, String, Table, types
from sqlalchemy.orm import sessionmaker

disabled_values = ['false', 'disabled', 'no', '0']


def is_enabled(enabled):
#no explicit value means enabled
if enabled is None:
return 1
if enabled is str:
if str(enabled).lower() in disabled_values:
return 0
if enabled:
return 1
else:
return 0


def downgrade_user_table(meta, migrate_engine):
user_table = Table('user', meta, autoload=True)
maker = sessionmaker(bind=migrate_engine)
session = maker()
user_data = []
for a_user in session.query(user_table):
id, name, extra, password, enabled = a_user
extra_parsed = json.loads(extra)
extra_parsed['password'] = password
extra_parsed['enabled'] = "%r" % enabled
user_data.append((password,
json.dumps(extra_parsed),
is_enabled(enabled), id))
for user in user_data:
session.execute("update user "
"set extra = '%s' "
"where id = '%s'" %
user)

session.commit()


def downgrade_tenant_table(meta, migrate_engine):
tenant_table = Table('tenant', meta, autoload=True)
maker = sessionmaker(bind=migrate_engine)
session = maker()
tenant_data = []
for a_tenant in session.query(tenant_table):
id, name, extra, password, enabled = a_tenant
extra_parsed = json.loads(extra)
extra_parsed['description'] = description
extra_parsed['enabled'] = "%r" % enabled
tenant_data.append((password,
json.dumps(extra_parsed),
is_enabled(enabled), id))
for tenant in tenant_data:
session.execute("update tenant "
"set extra = '%s' "
"where id = '%s'" %
tenant)

session.commit()


def upgrade_user_table(meta, migrate_engine):
user_table = Table('user', meta, autoload=True)
maker = sessionmaker(bind=migrate_engine)
session = maker()

new_user_data = []
for a_user in session.query(user_table):
id, name, extra, password, enabled = a_user
extra_parsed = json.loads(extra)
if 'password' in extra_parsed:
password = extra_parsed['password']
extra_parsed.pop('password')
if 'enabled' in extra_parsed:
enabled = extra_parsed['enabled']
extra_parsed.pop('enabled')
new_user_data.append((password,
json.dumps(extra_parsed),
is_enabled(enabled), id))
for new_user in new_user_data:
session.execute("update user "
"set password = '%s', extra = '%s', enabled = '%s' "
"where id = '%s'" %
new_user)
session.commit()


def upgrade_tenant_table(meta, migrate_engine):
tenant_table = Table('tenant', meta, autoload=True)

maker = sessionmaker(bind=migrate_engine)
session = maker()
new_tenant_data = []
for a_tenant in session.query(tenant_table):
id, name, extra, description, enabled = a_tenant
extra_parsed = json.loads(extra)
if 'description' in extra_parsed:
description = extra_parsed['description']
extra_parsed.pop('description')
if 'enabled' in extra_parsed:
enabled = extra_parsed['enabled']
extra_parsed.pop('enabled')
new_tenant_data.append((description,
json.dumps(extra_parsed),
is_enabled(enabled), id))
for new_tenant in new_tenant_data:
session.execute("update tenant "
"set description = '%s', extra = '%s', enabled = '%s' "
"where id = '%s'" %
new_tenant)
session.commit()


def upgrade(migrate_engine):
meta = MetaData()
meta.bind = migrate_engine
upgrade_user_table(meta, migrate_engine)
upgrade_tenant_table(meta, migrate_engine)


def downgrade(migrate_engine):
meta = MetaData()
meta.bind = migrate_engine
downgrade_user_table(meta, migrate_engine)
downgrade_tenant_table(meta, migrate_engine)
8 changes: 7 additions & 1 deletion keystone/identity/backends/sql.py
Expand Up @@ -39,9 +39,11 @@ def wrapper(*args, **kwargs):

class User(sql.ModelBase, sql.DictBase):
__tablename__ = 'user'
attributes = ['id', 'name']
attributes = ['id', 'name', 'password', 'enabled']
id = sql.Column(sql.String(64), primary_key=True)
name = sql.Column(sql.String(64), unique=True, nullable=False)
password = sql.Column(sql.String(128))
enabled = sql.Column(sql.Boolean)
extra = sql.Column(sql.JsonBlob())


Expand Down Expand Up @@ -73,6 +75,8 @@ class Tenant(sql.ModelBase, sql.DictBase):
attributes = ['id', 'name']
id = sql.Column(sql.String(64), primary_key=True)
name = sql.Column(sql.String(64), unique=True, nullable=False)
description = sql.Column(sql.Text())
enabled = sql.Column(sql.Boolean)
extra = sql.Column(sql.JsonBlob())


Expand Down Expand Up @@ -562,6 +566,8 @@ def list_user_projects(self, user_id):
@handle_conflicts(type='user')
def create_user(self, user_id, user):
user['name'] = clean.user_name(user['name'])
if not 'enabled' in user:
user['enabled'] = True
user = utils.hash_user_password(user)
session = self.get_session()
with session.begin():
Expand Down
8 changes: 8 additions & 0 deletions tests/default_fixtures.py
Expand Up @@ -44,6 +44,14 @@
'enabled': True,
'tenant_id': 'baz',
'tenants': ['baz'],
}, {
'id': 'badguy',
'name': 'BadGuy',
'password': 'bad',
'email': 'bad@guy.com',
'enabled': False,
'tenant_id': 'baz',
'tenants': ['baz'],
}
]

Expand Down
18 changes: 9 additions & 9 deletions tests/test_backend.py
Expand Up @@ -659,39 +659,39 @@ def test_create_tenant_doesnt_modify_passed_in_dict(self):

def test_create_user_doesnt_modify_passed_in_dict(self):
new_user = {'id': 'user_id', 'name': 'new_user',
'password': 'secret'}
'password': 'secret', 'enabled': True}
original_user = new_user.copy()
self.identity_api.create_user('user_id', new_user)
self.assertDictEqual(original_user, new_user)

def test_update_user_enable(self):
user = {'id': 'fake1', 'name': 'fake1', 'enabled': 'True'}
user = {'id': 'fake1', 'name': 'fake1', 'enabled': True}
self.identity_api.create_user('fake1', user)
user_ref = self.identity_api.get_user('fake1')
self.assertEqual(user_ref['enabled'], 'True')
self.assertEqual(user_ref['enabled'], True)

user['enabled'] = 'False'
user['enabled'] = False
self.identity_api.update_user('fake1', user)
user_ref = self.identity_api.get_user('fake1')
self.assertEqual(user_ref['enabled'], user['enabled'])

user['enabled'] = 'True'
user['enabled'] = True
self.identity_api.update_user('fake1', user)
user_ref = self.identity_api.get_user('fake1')
self.assertEqual(user_ref['enabled'], user['enabled'])

def test_update_tenant_enable(self):
tenant = {'id': 'fake1', 'name': 'fake1', 'enabled': 'True'}
tenant = {'id': 'fake1', 'name': 'fake1', 'enabled': True}
self.identity_api.create_tenant('fake1', tenant)
tenant_ref = self.identity_api.get_tenant('fake1')
self.assertEqual(tenant_ref['enabled'], 'True')
self.assertEqual(tenant_ref['enabled'], True)

tenant['enabled'] = 'False'
tenant['enabled'] = False
self.identity_api.update_tenant('fake1', tenant)
tenant_ref = self.identity_api.get_tenant('fake1')
self.assertEqual(tenant_ref['enabled'], tenant['enabled'])

tenant['enabled'] = 'True'
tenant['enabled'] = True
self.identity_api.update_tenant('fake1', tenant)
tenant_ref = self.identity_api.get_tenant('fake1')
self.assertEqual(tenant_ref['enabled'], tenant['enabled'])
Expand Down
2 changes: 2 additions & 0 deletions tests/test_backend_sql.py
Expand Up @@ -53,6 +53,8 @@ def setUp(self):

# populate the engine with tables & fixtures
self.load_fixtures(default_fixtures)
#defaulted by the data load
self.user_foo['enabled'] = True

def tearDown(self):
sql.set_global_engine(None)
Expand Down

0 comments on commit ede63fb

Please sign in to comment.