diff options
Diffstat (limited to 'keystone')
5 files changed, 220 insertions, 1 deletions
diff --git a/keystone/common/sql/core.py b/keystone/common/sql/core.py index a376ed87..0e18f8d5 100644 --- a/keystone/common/sql/core.py +++ b/keystone/common/sql/core.py @@ -46,6 +46,7 @@ DateTime = sql.DateTime IntegrityError = sql.exc.IntegrityError NotFound = sql.orm.exc.NoResultFound Boolean = sql.Boolean +Text = sql.Text def set_global_engine(engine): diff --git a/keystone/common/sql/migrate_repo/versions/008_normalize_identity.py b/keystone/common/sql/migrate_repo/versions/008_normalize_identity.py new file mode 100644 index 00000000..c473e787 --- /dev/null +++ b/keystone/common/sql/migrate_repo/versions/008_normalize_identity.py @@ -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) diff --git a/keystone/common/sql/migrate_repo/versions/008_sqlite_downgrade.sql b/keystone/common/sql/migrate_repo/versions/008_sqlite_downgrade.sql new file mode 100644 index 00000000..4dec683a --- /dev/null +++ b/keystone/common/sql/migrate_repo/versions/008_sqlite_downgrade.sql @@ -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; diff --git a/keystone/common/sql/migrate_repo/versions/009_normalize_identity_migration.py b/keystone/common/sql/migrate_repo/versions/009_normalize_identity_migration.py new file mode 100644 index 00000000..888334a6 --- /dev/null +++ b/keystone/common/sql/migrate_repo/versions/009_normalize_identity_migration.py @@ -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) diff --git a/keystone/identity/backends/sql.py b/keystone/identity/backends/sql.py index 209ec2f0..73d58b94 100644 --- a/keystone/identity/backends/sql.py +++ b/keystone/identity/backends/sql.py @@ -39,9 +39,11 @@ def handle_conflicts(type='object'): 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()) @@ -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()) @@ -562,6 +566,8 @@ class Identity(sql.Base, identity.Driver): @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(): |
