From b5dc3e6b948416ddc82fb4954d69f589123a9b8f Mon Sep 17 00:00:00 2001 From: adamscmRH Date: Mon, 25 Jun 2018 14:39:04 -0400 Subject: [PATCH 1/5] patch session length settings --- awx/api/conf.py | 8 +++++--- awx/conf/fields.py | 8 ++++++++ awx/settings/defaults.py | 3 ++- .../system-form/sub-forms/system-misc.form.js | 4 ++-- docs/CHANGELOG.md | 2 +- docs/auth/session.md | 4 ++-- 6 files changed, 20 insertions(+), 9 deletions(-) diff --git a/awx/api/conf.py b/awx/api/conf.py index 58aa9b4cc8..c4c18f7cc4 100644 --- a/awx/api/conf.py +++ b/awx/api/conf.py @@ -5,18 +5,20 @@ from django.utils.translation import ugettext_lazy as _ from awx.conf import fields, register from awx.api.fields import OAuth2ProviderField from oauth2_provider.settings import oauth2_settings - +from django.conf import settings register( - 'SESSION_COOKIE_AGE', - field_class=fields.IntegerField, + 'AUTH_TOKEN_EXPIRATION', + field_class=fields.AuthTokenField, min_value=60, max_value=30000000000, # approx 1,000 years, higher values give OverflowError + default={'AUTH_TOKEN_EXPIRATION': settings.AUTH_TOKEN_EXPIRATION}, label=_('Idle Time Force Log Out'), help_text=_('Number of seconds that a user is inactive before they will need to login again.'), category=_('Authentication'), category_slug='authentication', ) + register( 'SESSIONS_PER_USER', field_class=fields.IntegerField, diff --git a/awx/conf/fields.py b/awx/conf/fields.py index b98b925447..582499e351 100644 --- a/awx/conf/fields.py +++ b/awx/conf/fields.py @@ -6,6 +6,7 @@ from collections import OrderedDict # Django from django.core.validators import URLValidator from django.utils.translation import ugettext_lazy as _ +from django.conf import settings # Django REST Framework from rest_framework.fields import * # noqa @@ -42,6 +43,13 @@ class IntegerField(IntegerField): if ret == '' and self.allow_null and not getattr(self, 'allow_blank', False): return None return ret + + +class AuthTokenField(IntegerField): + + def to_internal_value(self, data): + settings.SESSION_COOKIE_AGE = data + return super(AuthTokenField, self).to_internal_value(data) class StringListField(ListField): diff --git a/awx/settings/defaults.py b/awx/settings/defaults.py index b159ef3d61..5c09d4daf6 100644 --- a/awx/settings/defaults.py +++ b/awx/settings/defaults.py @@ -200,7 +200,8 @@ SESSION_COOKIE_SECURE = True # Seconds before sessions expire. # Note: This setting may be overridden by database settings. -SESSION_COOKIE_AGE = 1209600 +AUTH_TOKEN_EXPIRATION = 1800 +SESSION_COOKIE_AGE = AUTH_TOKEN_EXPIRATION # Maximum number of per-user valid, concurrent sessions. # -1 is unlimited diff --git a/awx/ui/client/src/configuration/system-form/sub-forms/system-misc.form.js b/awx/ui/client/src/configuration/system-form/sub-forms/system-misc.form.js index 02b71edaec..2920e8f7e0 100644 --- a/awx/ui/client/src/configuration/system-form/sub-forms/system-misc.form.js +++ b/awx/ui/client/src/configuration/system-form/sub-forms/system-misc.form.js @@ -24,11 +24,11 @@ export default ['i18n', function(i18n) { MANAGE_ORGANIZATION_AUTH: { type: 'toggleSwitch', }, - SESSION_COOKIE_AGE: { + AUTH_TOKEN_EXPIRATION: { type: 'number', integer: true, min: 60, - reset: 'SESSION_COOKIE_AGE', + reset: 'AUTH_TOKEN_EXPIRATION', }, SESSIONS_PER_USER: { type: 'number', diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 96cd3b7bc4..6698f04a60 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -49,7 +49,7 @@ * Impose stricter criteria to admin users - organization admin role now necessary for all organizations target user is member of. * Remove unused `admin_role` associated with users. -* Enforce max value for `SESSION_COOKIE_AGE` +* Enforce max value for `AUTH_TIMEOUT_EXPIRATION` [[#1651](https://github.com/ansible/awx/issues/1651)]. * Add stricter validation to `order_by` query params [[#776](https://github.com/ansible/awx/issues/776)]. diff --git a/docs/auth/session.md b/docs/auth/session.md index 1e31375adc..bc19f53f31 100644 --- a/docs/auth/session.md +++ b/docs/auth/session.md @@ -45,7 +45,7 @@ Any client should follow the standard rules of [cookie protocol](https://tools.i parse that header to obtain information about the session, such as session cookie name (`session_id`), session cookie value, expiration date, duration, etc. -The duration of the cookie is configurable by Tower Configuration setting `SESSION_COOKIE_AGE` under +The duration of the cookie is configurable by Tower Configuration setting `AUTH_TOKEN_EXPIRATION` under category `authentication`. It is an integer denoting the number of seconds the session cookie should live. The default session cookie age is 2 weeks. @@ -76,7 +76,7 @@ is updated, all sessions she owned will be invalidated and deleted. * User should be able to log in via `/api/login/` endpoint by correctly providing all necessary fields. * Logged in users should be able to authenticate themselves by providing correct session auth info. * Logged in users should be able to log out via `/api/logout/`. -* The duration of a session cookie should be configurable by `SESSION_COOKIE_AGE`. +* The duration of a session cookie should be configurable by `AUTH_TOKEN_EXPIRATION`. * The maximum number of concurrent login for one user should be configurable by `SESSIONS_PER_USER`, and over-limit user sessions should be warned by websocket. * When a user's password is changed, all her sessions should be invalidated and deleted. From 4c84d400a800c9867ddb2f28c3187b4aea93efac Mon Sep 17 00:00:00 2001 From: adamscmRH Date: Wed, 27 Jun 2018 15:16:07 -0400 Subject: [PATCH 2/5] migrate session length setting --- awx/api/conf.py | 8 +-- awx/conf/fields.py | 8 --- .../0005_v330_rename_two_session_settings.py | 62 +++++++++++++++++++ awx/settings/defaults.py | 3 +- .../system-form/sub-forms/system-misc.form.js | 4 +- docs/CHANGELOG.md | 4 +- docs/auth/session.md | 4 +- 7 files changed, 73 insertions(+), 20 deletions(-) create mode 100644 awx/conf/migrations/0005_v330_rename_two_session_settings.py diff --git a/awx/api/conf.py b/awx/api/conf.py index c4c18f7cc4..58aa9b4cc8 100644 --- a/awx/api/conf.py +++ b/awx/api/conf.py @@ -5,20 +5,18 @@ from django.utils.translation import ugettext_lazy as _ from awx.conf import fields, register from awx.api.fields import OAuth2ProviderField from oauth2_provider.settings import oauth2_settings -from django.conf import settings + register( - 'AUTH_TOKEN_EXPIRATION', - field_class=fields.AuthTokenField, + 'SESSION_COOKIE_AGE', + field_class=fields.IntegerField, min_value=60, max_value=30000000000, # approx 1,000 years, higher values give OverflowError - default={'AUTH_TOKEN_EXPIRATION': settings.AUTH_TOKEN_EXPIRATION}, label=_('Idle Time Force Log Out'), help_text=_('Number of seconds that a user is inactive before they will need to login again.'), category=_('Authentication'), category_slug='authentication', ) - register( 'SESSIONS_PER_USER', field_class=fields.IntegerField, diff --git a/awx/conf/fields.py b/awx/conf/fields.py index 582499e351..b98b925447 100644 --- a/awx/conf/fields.py +++ b/awx/conf/fields.py @@ -6,7 +6,6 @@ from collections import OrderedDict # Django from django.core.validators import URLValidator from django.utils.translation import ugettext_lazy as _ -from django.conf import settings # Django REST Framework from rest_framework.fields import * # noqa @@ -43,13 +42,6 @@ class IntegerField(IntegerField): if ret == '' and self.allow_null and not getattr(self, 'allow_blank', False): return None return ret - - -class AuthTokenField(IntegerField): - - def to_internal_value(self, data): - settings.SESSION_COOKIE_AGE = data - return super(AuthTokenField, self).to_internal_value(data) class StringListField(ListField): diff --git a/awx/conf/migrations/0005_v330_rename_two_session_settings.py b/awx/conf/migrations/0005_v330_rename_two_session_settings.py new file mode 100644 index 0000000000..21eecfb556 --- /dev/null +++ b/awx/conf/migrations/0005_v330_rename_two_session_settings.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +from django.utils import timezone +from django.db import migrations + + +def copy_session_settings(apps, schema_editor): + + + def rename_setting(old_key, new_key): + Setting = apps.get_model('conf', 'Setting') + + if Setting.objects.filter(key=new_key).exists(): + logger.error('Setting', new_key, 'unexpectedly exists before this migration, \ + it will be replaced by the value of the', AUTH_TOKEN_EXPIRATION, 'setting.') + + + + + Setting = apps.get_model('conf', 'Setting') + + mapping = { + 'AUTH_TOKEN_EXPIRATION': 'SESSION_COOKIE_AGE', + 'AUTH_TOKEN_PER_USER': 'SESSIONS_PER_USER' +} +for before, after in mapping.items(): + ... + + + for setting_name in mapping: + old_setting = Setting.objects.filter(key=setting_name).first() + if + + if Setting.objects.filter(key='SESSION_COOKIE_AGE').exists(): + logger.error('Setting SESSION_COOKIE_AGE unexpectedly exists before this migration, it will be replaced by AUTH_TOKEN_EXPIRATION setting') + + + if Setting.objects.filter(key='AUTH_TOKEN_EXPIRATION').exists(): + Setting.objects.filter(key='SESSION_COOKIE_AGE').delete() + Setting.objects.get_or_create(key='SESSION_COOKIE_AGE', + value=Setting.objects.get(key='AUTH_TOKEN_EXPIRATION').value, + created=timezone.now(), + modified=timezone.now()) + + if Setting.objects.filter(key='AUTH_TOKEN_PER_USER').exists(): + Setting.objects.filter(key='SESSIONS_PER_USER').delete() + Setting.objects.get_or_create(key='SESSIONS_PER_USER', + value=Setting.objects.get(key='AUTH_TOKEN_PER_USER').value, + created=timezone.now(), + modified=timezone.now()) + + +class Migration(migrations.Migration): + + dependencies = [ + ('conf', '0004_v320_reencrypt'), + ] + + operations = [ + migrations.RunPython(copy_session_settings), + ] + \ No newline at end of file diff --git a/awx/settings/defaults.py b/awx/settings/defaults.py index 5c09d4daf6..6d1374fa6e 100644 --- a/awx/settings/defaults.py +++ b/awx/settings/defaults.py @@ -200,8 +200,7 @@ SESSION_COOKIE_SECURE = True # Seconds before sessions expire. # Note: This setting may be overridden by database settings. -AUTH_TOKEN_EXPIRATION = 1800 -SESSION_COOKIE_AGE = AUTH_TOKEN_EXPIRATION +SESSION_COOKIE_AGE = 1800 # Maximum number of per-user valid, concurrent sessions. # -1 is unlimited diff --git a/awx/ui/client/src/configuration/system-form/sub-forms/system-misc.form.js b/awx/ui/client/src/configuration/system-form/sub-forms/system-misc.form.js index 2920e8f7e0..02b71edaec 100644 --- a/awx/ui/client/src/configuration/system-form/sub-forms/system-misc.form.js +++ b/awx/ui/client/src/configuration/system-form/sub-forms/system-misc.form.js @@ -24,11 +24,11 @@ export default ['i18n', function(i18n) { MANAGE_ORGANIZATION_AUTH: { type: 'toggleSwitch', }, - AUTH_TOKEN_EXPIRATION: { + SESSION_COOKIE_AGE: { type: 'number', integer: true, min: 60, - reset: 'AUTH_TOKEN_EXPIRATION', + reset: 'SESSION_COOKIE_AGE', }, SESSIONS_PER_USER: { type: 'number', diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 6698f04a60..db33422427 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -49,7 +49,7 @@ * Impose stricter criteria to admin users - organization admin role now necessary for all organizations target user is member of. * Remove unused `admin_role` associated with users. -* Enforce max value for `AUTH_TIMEOUT_EXPIRATION` +* Enforce max value for `SESSION_COOKIE_AGE` [[#1651](https://github.com/ansible/awx/issues/1651)]. * Add stricter validation to `order_by` query params [[#776](https://github.com/ansible/awx/issues/776)]. @@ -71,6 +71,8 @@ * Implemented OAuth2 support for token based authentication [[#21](https://github.com/ansible/awx/issues/21)]. * Added the ability to forcibly expire sessions through `awx-manage expire_sessions`. * Disallowed using HTTP PUT/PATCH methods to modify existing jobs in Job Details API endpoint. +* Changed the name of the session length setting from `AUTH_TOKEN_EXPIRATION` to `SESSION_COOKIE_AGE`. +* Changed the name of the session length setting from `AUTH_TOKEN_PER_USER` to `SESSIONS_PER_USER`. 3.2.0 ===== diff --git a/docs/auth/session.md b/docs/auth/session.md index bc19f53f31..1e31375adc 100644 --- a/docs/auth/session.md +++ b/docs/auth/session.md @@ -45,7 +45,7 @@ Any client should follow the standard rules of [cookie protocol](https://tools.i parse that header to obtain information about the session, such as session cookie name (`session_id`), session cookie value, expiration date, duration, etc. -The duration of the cookie is configurable by Tower Configuration setting `AUTH_TOKEN_EXPIRATION` under +The duration of the cookie is configurable by Tower Configuration setting `SESSION_COOKIE_AGE` under category `authentication`. It is an integer denoting the number of seconds the session cookie should live. The default session cookie age is 2 weeks. @@ -76,7 +76,7 @@ is updated, all sessions she owned will be invalidated and deleted. * User should be able to log in via `/api/login/` endpoint by correctly providing all necessary fields. * Logged in users should be able to authenticate themselves by providing correct session auth info. * Logged in users should be able to log out via `/api/logout/`. -* The duration of a session cookie should be configurable by `AUTH_TOKEN_EXPIRATION`. +* The duration of a session cookie should be configurable by `SESSION_COOKIE_AGE`. * The maximum number of concurrent login for one user should be configurable by `SESSIONS_PER_USER`, and over-limit user sessions should be warned by websocket. * When a user's password is changed, all her sessions should be invalidated and deleted. From 3e1aaec9fe986a860a3db919703e3cde7db7a6d0 Mon Sep 17 00:00:00 2001 From: adamscmRH Date: Mon, 2 Jul 2018 14:16:16 -0400 Subject: [PATCH 3/5] add generic setting method --- .../0005_v330_rename_two_session_settings.py | 51 ++----------------- awx/conf/migrations/_rename_setting.py | 37 ++++++++++++++ awx/settings/defaults.py | 2 +- 3 files changed, 43 insertions(+), 47 deletions(-) create mode 100644 awx/conf/migrations/_rename_setting.py diff --git a/awx/conf/migrations/0005_v330_rename_two_session_settings.py b/awx/conf/migrations/0005_v330_rename_two_session_settings.py index 21eecfb556..f7077561bd 100644 --- a/awx/conf/migrations/0005_v330_rename_two_session_settings.py +++ b/awx/conf/migrations/0005_v330_rename_two_session_settings.py @@ -1,53 +1,12 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.utils import timezone from django.db import migrations - - +from awx.conf.migrations import _rename_setting + + def copy_session_settings(apps, schema_editor): - - - def rename_setting(old_key, new_key): - Setting = apps.get_model('conf', 'Setting') - - if Setting.objects.filter(key=new_key).exists(): - logger.error('Setting', new_key, 'unexpectedly exists before this migration, \ - it will be replaced by the value of the', AUTH_TOKEN_EXPIRATION, 'setting.') - - - - - Setting = apps.get_model('conf', 'Setting') - - mapping = { - 'AUTH_TOKEN_EXPIRATION': 'SESSION_COOKIE_AGE', - 'AUTH_TOKEN_PER_USER': 'SESSIONS_PER_USER' -} -for before, after in mapping.items(): - ... - - - for setting_name in mapping: - old_setting = Setting.objects.filter(key=setting_name).first() - if - - if Setting.objects.filter(key='SESSION_COOKIE_AGE').exists(): - logger.error('Setting SESSION_COOKIE_AGE unexpectedly exists before this migration, it will be replaced by AUTH_TOKEN_EXPIRATION setting') - - - if Setting.objects.filter(key='AUTH_TOKEN_EXPIRATION').exists(): - Setting.objects.filter(key='SESSION_COOKIE_AGE').delete() - Setting.objects.get_or_create(key='SESSION_COOKIE_AGE', - value=Setting.objects.get(key='AUTH_TOKEN_EXPIRATION').value, - created=timezone.now(), - modified=timezone.now()) - - if Setting.objects.filter(key='AUTH_TOKEN_PER_USER').exists(): - Setting.objects.filter(key='SESSIONS_PER_USER').delete() - Setting.objects.get_or_create(key='SESSIONS_PER_USER', - value=Setting.objects.get(key='AUTH_TOKEN_PER_USER').value, - created=timezone.now(), - modified=timezone.now()) + _rename_setting.rename_setting(apps, schema_editor, old_key='AUTH_TOKEN_PER_USER', new_key='SESSION_COOKIE_AGE') + _rename_setting.rename_setting(apps, schema_editor, old_key='AUTH_TOKEN_EXPIRATION', new_key='SESSIONS_PER_USER') class Migration(migrations.Migration): diff --git a/awx/conf/migrations/_rename_setting.py b/awx/conf/migrations/_rename_setting.py new file mode 100644 index 0000000000..69e95630da --- /dev/null +++ b/awx/conf/migrations/_rename_setting.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +import logging + +logger = logging.getLogger('awx.conf.settings') + +__all__ = ['rename_setting'] + + +def rename_setting(apps, schema_editor, old_key, new_key): + + Setting = apps.get_model('conf', 'Setting') + + if Setting.objects.filter(key=new_key).exists(): + logger.error('Setting', new_key, 'unexpectedly exists before this migration, \ + it will be replaced by the value of the', old_key, 'setting.') + Setting.objects.filter(key=new_key).delete() + + old_setting = Setting.objects.filter(key=old_key).first() + if old_setting is not None: + Setting.objects.create(key=new_key, value=old_setting.value) + Setting.objects.filter(key=old_key).delete() + +def reverse_rename_setting(apps, schema_editor, old_key, new_key): + + Setting = apps.get_model('conf', 'Setting') + + if Setting.objects.filter(key=old_key).exists(): + logger.error('Setting', old_key, 'unexpectedly exists before this migration, \ + it will be replaced by the value of the', new_key, 'setting.') + Setting.objects.filter(key=old_key).delete() + + new_setting = Setting.objects.filter(key=new_key).first() + if new_setting is not None: + Setting.objects.create(key=old_key, value=new_setting.value) + Setting.objects.filter(key=new_key).delete() + \ No newline at end of file diff --git a/awx/settings/defaults.py b/awx/settings/defaults.py index 6d1374fa6e..b159ef3d61 100644 --- a/awx/settings/defaults.py +++ b/awx/settings/defaults.py @@ -200,7 +200,7 @@ SESSION_COOKIE_SECURE = True # Seconds before sessions expire. # Note: This setting may be overridden by database settings. -SESSION_COOKIE_AGE = 1800 +SESSION_COOKIE_AGE = 1209600 # Maximum number of per-user valid, concurrent sessions. # -1 is unlimited From 9ac92c0ee0f01fabf01848914c6cedf575e1b80b Mon Sep 17 00:00:00 2001 From: adamscmRH Date: Thu, 5 Jul 2018 10:54:54 -0400 Subject: [PATCH 4/5] refactor code --- .../0005_v330_rename_two_session_settings.py | 7 +++++- awx/conf/migrations/_rename_setting.py | 23 ++++++------------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/awx/conf/migrations/0005_v330_rename_two_session_settings.py b/awx/conf/migrations/0005_v330_rename_two_session_settings.py index f7077561bd..1dd9c040e8 100644 --- a/awx/conf/migrations/0005_v330_rename_two_session_settings.py +++ b/awx/conf/migrations/0005_v330_rename_two_session_settings.py @@ -9,6 +9,11 @@ def copy_session_settings(apps, schema_editor): _rename_setting.rename_setting(apps, schema_editor, old_key='AUTH_TOKEN_EXPIRATION', new_key='SESSIONS_PER_USER') +def reverse_copy_session_settings(apps, schema_editor): + _rename_setting.rename_setting(apps, schema_editor, old_key='SESSION_COOKIE_AGE', new_key='AUTH_TOKEN_PER_USER') + _rename_setting.rename_setting(apps, schema_editor, old_key='SESSIONS_PER_USER', new_key='SESSIONS_PER_USER''AUTH_TOKEN_EXPIRATION') + + class Migration(migrations.Migration): dependencies = [ @@ -16,6 +21,6 @@ class Migration(migrations.Migration): ] operations = [ - migrations.RunPython(copy_session_settings), + migrations.RunPython(copy_session_settings, reverse_copy_session_settings), ] \ No newline at end of file diff --git a/awx/conf/migrations/_rename_setting.py b/awx/conf/migrations/_rename_setting.py index 69e95630da..1d9c91884f 100644 --- a/awx/conf/migrations/_rename_setting.py +++ b/awx/conf/migrations/_rename_setting.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals import logging +from django.utils.timezone import now logger = logging.getLogger('awx.conf.settings') @@ -12,26 +13,16 @@ def rename_setting(apps, schema_editor, old_key, new_key): Setting = apps.get_model('conf', 'Setting') if Setting.objects.filter(key=new_key).exists(): - logger.error('Setting', new_key, 'unexpectedly exists before this migration, \ - it will be replaced by the value of the', old_key, 'setting.') + logger.info('Setting ' + new_key + ' unexpectedly exists before this migration, it will be replaced by the value of the ' + old_key + ' setting.') Setting.objects.filter(key=new_key).delete() old_setting = Setting.objects.filter(key=old_key).first() if old_setting is not None: - Setting.objects.create(key=new_key, value=old_setting.value) + Setting.objects.create(key=new_key, + value=old_setting.value, + created=now(), + modified=now() + ) Setting.objects.filter(key=old_key).delete() -def reverse_rename_setting(apps, schema_editor, old_key, new_key): - - Setting = apps.get_model('conf', 'Setting') - - if Setting.objects.filter(key=old_key).exists(): - logger.error('Setting', old_key, 'unexpectedly exists before this migration, \ - it will be replaced by the value of the', new_key, 'setting.') - Setting.objects.filter(key=old_key).delete() - - new_setting = Setting.objects.filter(key=new_key).first() - if new_setting is not None: - Setting.objects.create(key=old_key, value=new_setting.value) - Setting.objects.filter(key=new_key).delete() \ No newline at end of file From cb6514777dcfc78bd66960641a501463ab0122d5 Mon Sep 17 00:00:00 2001 From: adamscmRH Date: Fri, 6 Jul 2018 08:53:35 -0400 Subject: [PATCH 5/5] grab on-disk setting --- .../0005_v330_rename_two_session_settings.py | 8 ++++---- awx/conf/migrations/_rename_setting.py | 20 +++++++++++-------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/awx/conf/migrations/0005_v330_rename_two_session_settings.py b/awx/conf/migrations/0005_v330_rename_two_session_settings.py index 1dd9c040e8..4e4b561ec4 100644 --- a/awx/conf/migrations/0005_v330_rename_two_session_settings.py +++ b/awx/conf/migrations/0005_v330_rename_two_session_settings.py @@ -5,13 +5,13 @@ from awx.conf.migrations import _rename_setting def copy_session_settings(apps, schema_editor): - _rename_setting.rename_setting(apps, schema_editor, old_key='AUTH_TOKEN_PER_USER', new_key='SESSION_COOKIE_AGE') - _rename_setting.rename_setting(apps, schema_editor, old_key='AUTH_TOKEN_EXPIRATION', new_key='SESSIONS_PER_USER') + _rename_setting.rename_setting(apps, schema_editor, old_key='AUTH_TOKEN_PER_USER', new_key='SESSIONS_PER_USER') + _rename_setting.rename_setting(apps, schema_editor, old_key='AUTH_TOKEN_EXPIRATION', new_key='SESSION_COOKIE_AGE') def reverse_copy_session_settings(apps, schema_editor): - _rename_setting.rename_setting(apps, schema_editor, old_key='SESSION_COOKIE_AGE', new_key='AUTH_TOKEN_PER_USER') - _rename_setting.rename_setting(apps, schema_editor, old_key='SESSIONS_PER_USER', new_key='SESSIONS_PER_USER''AUTH_TOKEN_EXPIRATION') + _rename_setting.rename_setting(apps, schema_editor, old_key='SESSION_COOKIE_AGE', new_key='AUTH_TOKEN_EXPIRATION') + _rename_setting.rename_setting(apps, schema_editor, old_key='SESSIONS_PER_USER', new_key='AUTH_TOKEN_PER_USER') class Migration(migrations.Migration): diff --git a/awx/conf/migrations/_rename_setting.py b/awx/conf/migrations/_rename_setting.py index 1d9c91884f..dbbc347edf 100644 --- a/awx/conf/migrations/_rename_setting.py +++ b/awx/conf/migrations/_rename_setting.py @@ -2,6 +2,7 @@ from __future__ import unicode_literals import logging from django.utils.timezone import now +from django.conf import settings logger = logging.getLogger('awx.conf.settings') @@ -9,20 +10,23 @@ __all__ = ['rename_setting'] def rename_setting(apps, schema_editor, old_key, new_key): - + + old_setting = None Setting = apps.get_model('conf', 'Setting') - - if Setting.objects.filter(key=new_key).exists(): + if Setting.objects.filter(key=new_key).exists() or hasattr(settings, new_key): logger.info('Setting ' + new_key + ' unexpectedly exists before this migration, it will be replaced by the value of the ' + old_key + ' setting.') Setting.objects.filter(key=new_key).delete() - - old_setting = Setting.objects.filter(key=old_key).first() + # Look for db setting, which wouldn't be picked up by SettingsWrapper because the register method is gone + if Setting.objects.filter(key=old_key).exists(): + old_setting = Setting.objects.filter(key=old_key).last().value + Setting.objects.filter(key=old_key).delete() + # Look for "on-disk" setting (/etc/tower/conf.d) + if hasattr(settings, old_key): + old_setting = getattr(settings, old_key) if old_setting is not None: Setting.objects.create(key=new_key, - value=old_setting.value, + value=old_setting, created=now(), modified=now() ) - Setting.objects.filter(key=old_key).delete() - \ No newline at end of file