"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "keystone/tests/unit/test_v3_domain_config.py" between
keystone-16.0.1.tar.gz and keystone-17.0.0.tar.gz

About: OpenStack Keystone (Core Service: Identity) provides an authentication and authorization service for other OpenStack services. Provides a catalog of endpoints for all OpenStack services.
The "Ussuri" series (latest release).

test_v3_domain_config.py  (keystone-16.0.1):test_v3_domain_config.py  (keystone-17.0.0)
skipping to change at line 16 skipping to change at line 16
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import copy import copy
import uuid import uuid
from six.moves import http_client import http.client
from keystone.common import provider_api from keystone.common import provider_api
import keystone.conf import keystone.conf
from keystone import exception from keystone import exception
from keystone.tests import unit from keystone.tests import unit
from keystone.tests.unit import test_v3 from keystone.tests.unit import test_v3
CONF = keystone.conf.CONF CONF = keystone.conf.CONF
PROVIDERS = provider_api.ProviderAPIs PROVIDERS = provider_api.ProviderAPIs
skipping to change at line 44 skipping to change at line 44
PROVIDERS.resource_api.create_domain(self.domain['id'], self.domain) PROVIDERS.resource_api.create_domain(self.domain['id'], self.domain)
self.config = {'ldap': {'url': uuid.uuid4().hex, self.config = {'ldap': {'url': uuid.uuid4().hex,
'user_tree_dn': uuid.uuid4().hex}, 'user_tree_dn': uuid.uuid4().hex},
'identity': {'driver': uuid.uuid4().hex}} 'identity': {'driver': uuid.uuid4().hex}}
def test_create_config(self): def test_create_config(self):
"""Call ``PUT /domains/{domain_id}/config``.""" """Call ``PUT /domains/{domain_id}/config``."""
url = '/domains/%(domain_id)s/config' % { url = '/domains/%(domain_id)s/config' % {
'domain_id': self.domain['id']} 'domain_id': self.domain['id']}
r = self.put(url, body={'config': self.config}, r = self.put(url, body={'config': self.config},
expected_status=http_client.CREATED) expected_status=http.client.CREATED)
res = PROVIDERS.domain_config_api.get_config(self.domain['id']) res = PROVIDERS.domain_config_api.get_config(self.domain['id'])
self.assertEqual(self.config, r.result['config']) self.assertEqual(self.config, r.result['config'])
self.assertEqual(self.config, res) self.assertEqual(self.config, res)
def test_create_config_invalid_domain(self): def test_create_config_invalid_domain(self):
"""Call ``PUT /domains/{domain_id}/config``. """Call ``PUT /domains/{domain_id}/config``.
While creating Identity API-based domain config with an invalid domain While creating Identity API-based domain config with an invalid domain
id provided, the request shall be rejected with a response, 404 domain id provided, the request shall be rejected with a response, 404 domain
not found. not found.
skipping to change at line 67 skipping to change at line 67
url = '/domains/%(domain_id)s/config' % { url = '/domains/%(domain_id)s/config' % {
'domain_id': invalid_domain_id} 'domain_id': invalid_domain_id}
self.put(url, body={'config': self.config}, self.put(url, body={'config': self.config},
expected_status=exception.DomainNotFound.code) expected_status=exception.DomainNotFound.code)
def test_create_config_twice(self): def test_create_config_twice(self):
"""Check multiple creates don't throw error.""" """Check multiple creates don't throw error."""
self.put('/domains/%(domain_id)s/config' % { self.put('/domains/%(domain_id)s/config' % {
'domain_id': self.domain['id']}, 'domain_id': self.domain['id']},
body={'config': self.config}, body={'config': self.config},
expected_status=http_client.CREATED) expected_status=http.client.CREATED)
self.put('/domains/%(domain_id)s/config' % { self.put('/domains/%(domain_id)s/config' % {
'domain_id': self.domain['id']}, 'domain_id': self.domain['id']},
body={'config': self.config}, body={'config': self.config},
expected_status=http_client.OK) expected_status=http.client.OK)
def test_delete_config(self): def test_delete_config(self):
"""Call ``DELETE /domains{domain_id}/config``.""" """Call ``DELETE /domains{domain_id}/config``."""
PROVIDERS.domain_config_api.create_config( PROVIDERS.domain_config_api.create_config(
self.domain['id'], self.config self.domain['id'], self.config
) )
self.delete('/domains/%(domain_id)s/config' % { self.delete('/domains/%(domain_id)s/config' % {
'domain_id': self.domain['id']}) 'domain_id': self.domain['id']})
self.get('/domains/%(domain_id)s/config' % { self.get('/domains/%(domain_id)s/config' % {
'domain_id': self.domain['id']}, 'domain_id': self.domain['id']},
skipping to change at line 133 skipping to change at line 133
def test_get_head_config(self): def test_get_head_config(self):
"""Call ``GET & HEAD for /domains{domain_id}/config``.""" """Call ``GET & HEAD for /domains{domain_id}/config``."""
PROVIDERS.domain_config_api.create_config( PROVIDERS.domain_config_api.create_config(
self.domain['id'], self.config self.domain['id'], self.config
) )
url = '/domains/%(domain_id)s/config' % { url = '/domains/%(domain_id)s/config' % {
'domain_id': self.domain['id']} 'domain_id': self.domain['id']}
r = self.get(url) r = self.get(url)
self.assertEqual(self.config, r.result['config']) self.assertEqual(self.config, r.result['config'])
self.head(url, expected_status=http_client.OK) self.head(url, expected_status=http.client.OK)
def test_get_head_config_by_group(self): def test_get_head_config_by_group(self):
"""Call ``GET & HEAD /domains{domain_id}/config/{group}``.""" """Call ``GET & HEAD /domains{domain_id}/config/{group}``."""
PROVIDERS.domain_config_api.create_config( PROVIDERS.domain_config_api.create_config(
self.domain['id'], self.config self.domain['id'], self.config
) )
url = '/domains/%(domain_id)s/config/ldap' % { url = '/domains/%(domain_id)s/config/ldap' % {
'domain_id': self.domain['id']} 'domain_id': self.domain['id']}
r = self.get(url) r = self.get(url)
self.assertEqual({'ldap': self.config['ldap']}, r.result['config']) self.assertEqual({'ldap': self.config['ldap']}, r.result['config'])
self.head(url, expected_status=http_client.OK) self.head(url, expected_status=http.client.OK)
def test_get_head_config_by_group_invalid_domain(self): def test_get_head_config_by_group_invalid_domain(self):
"""Call ``GET & HEAD /domains{domain_id}/config/{group}``. """Call ``GET & HEAD /domains{domain_id}/config/{group}``.
While retrieving Identity API-based domain config by group with an While retrieving Identity API-based domain config by group with an
invalid domain id provided, the request shall be rejected with a invalid domain id provided, the request shall be rejected with a
response 404 domain not found. response 404 domain not found.
""" """
PROVIDERS.domain_config_api.create_config( PROVIDERS.domain_config_api.create_config(
self.domain['id'], self.config self.domain['id'], self.config
skipping to change at line 173 skipping to change at line 173
def test_get_head_config_by_option(self): def test_get_head_config_by_option(self):
"""Call ``GET & HEAD /domains{domain_id}/config/{group}/{option}``.""" """Call ``GET & HEAD /domains{domain_id}/config/{group}/{option}``."""
PROVIDERS.domain_config_api.create_config( PROVIDERS.domain_config_api.create_config(
self.domain['id'], self.config self.domain['id'], self.config
) )
url = '/domains/%(domain_id)s/config/ldap/url' % { url = '/domains/%(domain_id)s/config/ldap/url' % {
'domain_id': self.domain['id']} 'domain_id': self.domain['id']}
r = self.get(url) r = self.get(url)
self.assertEqual({'url': self.config['ldap']['url']}, self.assertEqual({'url': self.config['ldap']['url']},
r.result['config']) r.result['config'])
self.head(url, expected_status=http_client.OK) self.head(url, expected_status=http.client.OK)
def test_get_head_config_by_option_invalid_domain(self): def test_get_head_config_by_option_invalid_domain(self):
"""Call ``GET & HEAD /domains{domain_id}/config/{group}/{option}``. """Call ``GET & HEAD /domains{domain_id}/config/{group}/{option}``.
While retrieving Identity API-based domain config by option with an While retrieving Identity API-based domain config by option with an
invalid domain id provided, the request shall be rejected with a invalid domain id provided, the request shall be rejected with a
response 404 domain not found. response 404 domain not found.
""" """
PROVIDERS.domain_config_api.create_config( PROVIDERS.domain_config_api.create_config(
self.domain['id'], self.config self.domain['id'], self.config
skipping to change at line 197 skipping to change at line 197
'domain_id': invalid_domain_id} 'domain_id': invalid_domain_id}
) )
self.get(url, expected_status=exception.DomainNotFound.code) self.get(url, expected_status=exception.DomainNotFound.code)
self.head(url, expected_status=exception.DomainNotFound.code) self.head(url, expected_status=exception.DomainNotFound.code)
def test_get_head_non_existant_config(self): def test_get_head_non_existant_config(self):
"""Call ``GET /domains{domain_id}/config when no config defined``.""" """Call ``GET /domains{domain_id}/config when no config defined``."""
url = ('/domains/%(domain_id)s/config' % { url = ('/domains/%(domain_id)s/config' % {
'domain_id': self.domain['id']} 'domain_id': self.domain['id']}
) )
self.get(url, expected_status=http_client.NOT_FOUND) self.get(url, expected_status=http.client.NOT_FOUND)
self.head(url, expected_status=http_client.NOT_FOUND) self.head(url, expected_status=http.client.NOT_FOUND)
def test_get_head_non_existant_config_invalid_domain(self): def test_get_head_non_existant_config_invalid_domain(self):
"""Call ``GET & HEAD /domains/{domain_id}/config with invalid domain``. """Call ``GET & HEAD /domains/{domain_id}/config with invalid domain``.
While retrieving non-existent Identity API-based domain config with an While retrieving non-existent Identity API-based domain config with an
invalid domain id provided, the request shall be rejected with a invalid domain id provided, the request shall be rejected with a
response 404 domain not found. response 404 domain not found.
""" """
invalid_domain_id = uuid.uuid4().hex invalid_domain_id = uuid.uuid4().hex
url = ('/domains/%(domain_id)s/config' % { url = ('/domains/%(domain_id)s/config' % {
skipping to change at line 221 skipping to change at line 221
self.get(url, expected_status=exception.DomainNotFound.code) self.get(url, expected_status=exception.DomainNotFound.code)
self.head(url, expected_status=exception.DomainNotFound.code) self.head(url, expected_status=exception.DomainNotFound.code)
def test_get_head_non_existant_config_group(self): def test_get_head_non_existant_config_group(self):
"""Call ``GET /domains/{domain_id}/config/{group_not_exist}``.""" """Call ``GET /domains/{domain_id}/config/{group_not_exist}``."""
config = {'ldap': {'url': uuid.uuid4().hex}} config = {'ldap': {'url': uuid.uuid4().hex}}
PROVIDERS.domain_config_api.create_config(self.domain['id'], config) PROVIDERS.domain_config_api.create_config(self.domain['id'], config)
url = ('/domains/%(domain_id)s/config/identity' % { url = ('/domains/%(domain_id)s/config/identity' % {
'domain_id': self.domain['id']} 'domain_id': self.domain['id']}
) )
self.get(url, expected_status=http_client.NOT_FOUND) self.get(url, expected_status=http.client.NOT_FOUND)
self.head(url, expected_status=http_client.NOT_FOUND) self.head(url, expected_status=http.client.NOT_FOUND)
def test_get_head_non_existant_config_group_invalid_domain(self): def test_get_head_non_existant_config_group_invalid_domain(self):
"""Call ``GET & HEAD /domains/{domain_id}/config/{group}``. """Call ``GET & HEAD /domains/{domain_id}/config/{group}``.
While retrieving non-existent Identity API-based domain config group While retrieving non-existent Identity API-based domain config group
with an invalid domain id provided, the request shall be rejected with with an invalid domain id provided, the request shall be rejected with
a response, 404 domain not found. a response, 404 domain not found.
""" """
config = {'ldap': {'url': uuid.uuid4().hex}} config = {'ldap': {'url': uuid.uuid4().hex}}
PROVIDERS.domain_config_api.create_config(self.domain['id'], config) PROVIDERS.domain_config_api.create_config(self.domain['id'], config)
skipping to change at line 252 skipping to change at line 252
Call ``GET & HEAD /domains/{domain_id}/config/{group}/{opt_not_exist}`` Call ``GET & HEAD /domains/{domain_id}/config/{group}/{opt_not_exist}``
and ensure a Not Found is returned because the option isn't defined and ensure a Not Found is returned because the option isn't defined
within the group. within the group.
""" """
config = {'ldap': {'url': uuid.uuid4().hex}} config = {'ldap': {'url': uuid.uuid4().hex}}
PROVIDERS.domain_config_api.create_config(self.domain['id'], config) PROVIDERS.domain_config_api.create_config(self.domain['id'], config)
url = ('/domains/%(domain_id)s/config/ldap/user_tree_dn' % { url = ('/domains/%(domain_id)s/config/ldap/user_tree_dn' % {
'domain_id': self.domain['id']} 'domain_id': self.domain['id']}
) )
self.get(url, expected_status=http_client.NOT_FOUND) self.get(url, expected_status=http.client.NOT_FOUND)
self.head(url, expected_status=http_client.NOT_FOUND) self.head(url, expected_status=http.client.NOT_FOUND)
def test_get_head_non_existant_config_option_with_invalid_domain(self): def test_get_head_non_existant_config_option_with_invalid_domain(self):
"""Test that Domain Not Found is returned with invalid domain. """Test that Domain Not Found is returned with invalid domain.
Call ``GET & HEAD /domains/{domain_id}/config/{group}/{opt_not_exist}`` Call ``GET & HEAD /domains/{domain_id}/config/{group}/{opt_not_exist}``
While retrieving non-existent Identity API-based domain config option While retrieving non-existent Identity API-based domain config option
with an invalid domain id provided, the request shall be rejected with with an invalid domain id provided, the request shall be rejected with
a response, 404 domain not found. a response, 404 domain not found.
""" """
skipping to change at line 359 skipping to change at line 359
) )
# Trying to update a group that is neither whitelisted or sensitive # Trying to update a group that is neither whitelisted or sensitive
# should result in Forbidden. # should result in Forbidden.
invalid_group = uuid.uuid4().hex invalid_group = uuid.uuid4().hex
new_config = {invalid_group: {'url': uuid.uuid4().hex, new_config = {invalid_group: {'url': uuid.uuid4().hex,
'user_filter': uuid.uuid4().hex}} 'user_filter': uuid.uuid4().hex}}
self.patch('/domains/%(domain_id)s/config/%(invalid_group)s' % { self.patch('/domains/%(domain_id)s/config/%(invalid_group)s' % {
'domain_id': self.domain['id'], 'invalid_group': invalid_group}, 'domain_id': self.domain['id'], 'invalid_group': invalid_group},
body={'config': new_config}, body={'config': new_config},
expected_status=http_client.FORBIDDEN) expected_status=http.client.FORBIDDEN)
# Trying to update a valid group, but one that is not in the current # Trying to update a valid group, but one that is not in the current
# config should result in NotFound # config should result in NotFound
config = {'ldap': {'suffix': uuid.uuid4().hex}} config = {'ldap': {'suffix': uuid.uuid4().hex}}
PROVIDERS.domain_config_api.create_config(self.domain['id'], config) PROVIDERS.domain_config_api.create_config(self.domain['id'], config)
new_config = {'identity': {'driver': uuid.uuid4().hex}} new_config = {'identity': {'driver': uuid.uuid4().hex}}
self.patch('/domains/%(domain_id)s/config/identity' % { self.patch('/domains/%(domain_id)s/config/identity' % {
'domain_id': self.domain['id']}, 'domain_id': self.domain['id']},
body={'config': new_config}, body={'config': new_config},
expected_status=http_client.NOT_FOUND) expected_status=http.client.NOT_FOUND)
def test_update_config_invalid_group_invalid_domain(self): def test_update_config_invalid_group_invalid_domain(self):
"""Call ``PATCH /domains/{domain_id}/config/{invalid_group}``. """Call ``PATCH /domains/{domain_id}/config/{invalid_group}``.
While updating Identity API-based domain config with an invalid group While updating Identity API-based domain config with an invalid group
and an invalid domain id provided, the request shall be rejected and an invalid domain id provided, the request shall be rejected
with a response, 404 domain not found. with a response, 404 domain not found.
""" """
PROVIDERS.domain_config_api.create_config( PROVIDERS.domain_config_api.create_config(
self.domain['id'], self.config self.domain['id'], self.config
skipping to change at line 436 skipping to change at line 436
) )
invalid_option = uuid.uuid4().hex invalid_option = uuid.uuid4().hex
new_config = {'ldap': {invalid_option: uuid.uuid4().hex}} new_config = {'ldap': {invalid_option: uuid.uuid4().hex}}
# Trying to update an option that is neither whitelisted or sensitive # Trying to update an option that is neither whitelisted or sensitive
# should result in Forbidden. # should result in Forbidden.
self.patch( self.patch(
'/domains/%(domain_id)s/config/ldap/%(invalid_option)s' % { '/domains/%(domain_id)s/config/ldap/%(invalid_option)s' % {
'domain_id': self.domain['id'], 'domain_id': self.domain['id'],
'invalid_option': invalid_option}, 'invalid_option': invalid_option},
body={'config': new_config}, body={'config': new_config},
expected_status=http_client.FORBIDDEN) expected_status=http.client.FORBIDDEN)
# Trying to update a valid option, but one that is not in the current # Trying to update a valid option, but one that is not in the current
# config should result in NotFound # config should result in NotFound
new_config = {'suffix': uuid.uuid4().hex} new_config = {'suffix': uuid.uuid4().hex}
self.patch( self.patch(
'/domains/%(domain_id)s/config/ldap/suffix' % { '/domains/%(domain_id)s/config/ldap/suffix' % {
'domain_id': self.domain['id']}, 'domain_id': self.domain['id']},
body={'config': new_config}, body={'config': new_config},
expected_status=http_client.NOT_FOUND) expected_status=http.client.NOT_FOUND)
def test_update_config_invalid_option_invalid_domain(self): def test_update_config_invalid_option_invalid_domain(self):
"""Call ``PATCH /domains/{domain_id}/config/{group}/{invalid}``. """Call ``PATCH /domains/{domain_id}/config/{group}/{invalid}``.
While updating Identity API-based domain config with an invalid option While updating Identity API-based domain config with an invalid option
and an invalid domain id provided, the request shall be rejected and an invalid domain id provided, the request shall be rejected
with a response, 404 domain not found. with a response, 404 domain not found.
""" """
PROVIDERS.domain_config_api.create_config( PROVIDERS.domain_config_api.create_config(
self.domain['id'], self.config self.domain['id'], self.config
skipping to change at line 480 skipping to change at line 480
PROVIDERS.domain_config_api.create_config( PROVIDERS.domain_config_api.create_config(
self.domain['id'], self.config self.domain['id'], self.config
) )
url = '/domains/config/default' url = '/domains/config/default'
r = self.get(url) r = self.get(url)
default_config = r.result['config'] default_config = r.result['config']
for group in default_config: for group in default_config:
for option in default_config[group]: for option in default_config[group]:
self.assertEqual(getattr(getattr(CONF, group), option), self.assertEqual(getattr(getattr(CONF, group), option),
default_config[group][option]) default_config[group][option])
self.head(url, expected_status=http_client.OK) self.head(url, expected_status=http.client.OK)
def test_get_head_config_default_by_group(self): def test_get_head_config_default_by_group(self):
"""Call ``GET & HEAD /domains/config/{group}/default``.""" """Call ``GET & HEAD /domains/config/{group}/default``."""
# Create a config that overrides a few of the options so that we can # Create a config that overrides a few of the options so that we can
# check that only the defaults are returned. # check that only the defaults are returned.
PROVIDERS.domain_config_api.create_config( PROVIDERS.domain_config_api.create_config(
self.domain['id'], self.config self.domain['id'], self.config
) )
url = '/domains/config/ldap/default' url = '/domains/config/ldap/default'
r = self.get(url) r = self.get(url)
default_config = r.result['config'] default_config = r.result['config']
for option in default_config['ldap']: for option in default_config['ldap']:
self.assertEqual(getattr(CONF.ldap, option), self.assertEqual(getattr(CONF.ldap, option),
default_config['ldap'][option]) default_config['ldap'][option])
self.head(url, expected_status=http_client.OK) self.head(url, expected_status=http.client.OK)
def test_get_head_config_default_by_option(self): def test_get_head_config_default_by_option(self):
"""Call ``GET & HEAD /domains/config/{group}/{option}/default``.""" """Call ``GET & HEAD /domains/config/{group}/{option}/default``."""
# Create a config that overrides a few of the options so that we can # Create a config that overrides a few of the options so that we can
# check that only the defaults are returned. # check that only the defaults are returned.
PROVIDERS.domain_config_api.create_config( PROVIDERS.domain_config_api.create_config(
self.domain['id'], self.config self.domain['id'], self.config
) )
url = '/domains/config/ldap/url/default' url = '/domains/config/ldap/url/default'
r = self.get(url) r = self.get(url)
default_config = r.result['config'] default_config = r.result['config']
self.assertEqual(CONF.ldap.url, default_config['url']) self.assertEqual(CONF.ldap.url, default_config['url'])
self.head(url, expected_status=http_client.OK) self.head(url, expected_status=http.client.OK)
def test_get_head_config_default_by_invalid_group(self): def test_get_head_config_default_by_invalid_group(self):
"""Call ``GET & HEAD for /domains/config/{bad-group}/default``.""" """Call ``GET & HEAD for /domains/config/{bad-group}/default``."""
# First try a valid group, but one we don't support for domain config # First try a valid group, but one we don't support for domain config
self.get('/domains/config/resource/default', self.get('/domains/config/resource/default',
expected_status=http_client.FORBIDDEN) expected_status=http.client.FORBIDDEN)
self.head('/domains/config/resource/default', self.head('/domains/config/resource/default',
expected_status=http_client.FORBIDDEN) expected_status=http.client.FORBIDDEN)
# Now try a totally invalid group # Now try a totally invalid group
url = '/domains/config/%s/default' % uuid.uuid4().hex url = '/domains/config/%s/default' % uuid.uuid4().hex
self.get(url, expected_status=http_client.FORBIDDEN) self.get(url, expected_status=http.client.FORBIDDEN)
self.head(url, expected_status=http_client.FORBIDDEN) self.head(url, expected_status=http.client.FORBIDDEN)
def test_get_head_config_default_for_unsupported_group(self): def test_get_head_config_default_for_unsupported_group(self):
# It should not be possible to expose configuration information for # It should not be possible to expose configuration information for
# groups that the domain configuration API backlists explicitly. Doing # groups that the domain configuration API backlists explicitly. Doing
# so would be a security vulnerability because it would leak sensitive # so would be a security vulnerability because it would leak sensitive
# information over the API. # information over the API.
self.get('/domains/config/ldap/password/default', self.get('/domains/config/ldap/password/default',
expected_status=http_client.FORBIDDEN) expected_status=http.client.FORBIDDEN)
self.head('/domains/config/ldap/password/default', self.head('/domains/config/ldap/password/default',
expected_status=http_client.FORBIDDEN) expected_status=http.client.FORBIDDEN)
def test_get_head_config_default_for_invalid_option(self): def test_get_head_config_default_for_invalid_option(self):
"""Returning invalid configuration options is invalid.""" """Returning invalid configuration options is invalid."""
url = '/domains/config/ldap/%s/default' % uuid.uuid4().hex url = '/domains/config/ldap/%s/default' % uuid.uuid4().hex
self.get(url, expected_status=http_client.FORBIDDEN) self.get(url, expected_status=http.client.FORBIDDEN)
self.head(url, expected_status=http_client.FORBIDDEN) self.head(url, expected_status=http.client.FORBIDDEN)
class SecurityRequirementsTestCase(test_v3.RestfulTestCase): class SecurityRequirementsTestCase(test_v3.RestfulTestCase):
def setUp(self): def setUp(self):
super(SecurityRequirementsTestCase, self).setUp() super(SecurityRequirementsTestCase, self).setUp()
# Create a user in the default domain # Create a user in the default domain
self.non_admin_user = unit.create_user( self.non_admin_user = unit.create_user(
PROVIDERS.identity_api, PROVIDERS.identity_api,
CONF.identity.default_domain_id CONF.identity.default_domain_id
skipping to change at line 641 skipping to change at line 641
# requirement information. # requirement information.
regular_response = self.get(url, token=self._get_non_admin_token()) regular_response = self.get(url, token=self._get_non_admin_token())
self.assertEqual(regular_response.result['config'], expected_response) self.assertEqual(regular_response.result['config'], expected_response)
admin_response = self.get(url, token=self._get_admin_token()) admin_response = self.get(url, token=self._get_admin_token())
self.assertEqual(admin_response.result['config'], expected_response) self.assertEqual(admin_response.result['config'], expected_response)
# Ensure HEAD requests behave the same way # Ensure HEAD requests behave the same way
self.head( self.head(
url, url,
token=self._get_non_admin_token(), token=self._get_non_admin_token(),
expected_status=http_client.OK expected_status=http.client.OK
) )
self.head( self.head(
url, url,
token=self._get_admin_token(), token=self._get_admin_token(),
expected_status=http_client.OK expected_status=http.client.OK
) )
def test_get_security_compliance_config_for_non_default_domain_fails(self): def test_get_security_compliance_config_for_non_default_domain_fails(self):
"""Getting security compliance opts for other domains should fail. """Getting security compliance opts for other domains should fail.
Support for enforcing security compliance rules per domain currently Support for enforcing security compliance rules per domain currently
does not exist, so exposing security compliance information for any does not exist, so exposing security compliance information for any
domain other than the default domain should not be allowed. domain other than the default domain should not be allowed.
""" """
# Create a new domain that is not the default domain # Create a new domain that is not the default domain
skipping to change at line 683 skipping to change at line 683
{ {
'domain_id': domain['id'], 'domain_id': domain['id'],
'group': 'security_compliance', 'group': 'security_compliance',
} }
) )
# Make sure regular users and administrators are forbidden from doing # Make sure regular users and administrators are forbidden from doing
# this. # this.
self.get( self.get(
url, url,
expected_status=http_client.FORBIDDEN, expected_status=http.client.FORBIDDEN,
token=self._get_non_admin_token() token=self._get_non_admin_token()
) )
self.get( self.get(
url, url,
expected_status=http_client.FORBIDDEN, expected_status=http.client.FORBIDDEN,
token=self._get_admin_token() token=self._get_admin_token()
) )
# Ensure HEAD requests behave the same way # Ensure HEAD requests behave the same way
self.head( self.head(
url, url,
expected_status=http_client.FORBIDDEN, expected_status=http.client.FORBIDDEN,
token=self._get_non_admin_token() token=self._get_non_admin_token()
) )
self.head( self.head(
url, url,
expected_status=http_client.FORBIDDEN, expected_status=http.client.FORBIDDEN,
token=self._get_admin_token() token=self._get_admin_token()
) )
def test_get_non_whitelisted_security_compliance_opt_fails(self): def test_get_non_whitelisted_security_compliance_opt_fails(self):
"""We only support exposing a subset of security compliance options. """We only support exposing a subset of security compliance options.
Given that security compliance information is sensitive in nature, we Given that security compliance information is sensitive in nature, we
should make sure that only the options we want to expose are readable should make sure that only the options we want to expose are readable
via the API. via the API.
""" """
skipping to change at line 729 skipping to change at line 729
'domain_id': CONF.identity.default_domain_id, 'domain_id': CONF.identity.default_domain_id,
'group': 'security_compliance', 'group': 'security_compliance',
'option': 'lockout_failure_attempts' 'option': 'lockout_failure_attempts'
} }
) )
# Make sure regular users and administrators are unable to ask for # Make sure regular users and administrators are unable to ask for
# sensitive information. # sensitive information.
self.get( self.get(
url, url,
expected_status=http_client.FORBIDDEN, expected_status=http.client.FORBIDDEN,
token=self._get_non_admin_token() token=self._get_non_admin_token()
) )
self.get( self.get(
url, url,
expected_status=http_client.FORBIDDEN, expected_status=http.client.FORBIDDEN,
token=self._get_admin_token() token=self._get_admin_token()
) )
# Ensure HEAD requests behave the same way # Ensure HEAD requests behave the same way
self.head( self.head(
url, url,
expected_status=http_client.FORBIDDEN, expected_status=http.client.FORBIDDEN,
token=self._get_non_admin_token() token=self._get_non_admin_token()
) )
self.head( self.head(
url, url,
expected_status=http_client.FORBIDDEN, expected_status=http.client.FORBIDDEN,
token=self._get_admin_token() token=self._get_admin_token()
) )
def test_get_security_compliance_password_regex(self): def test_get_security_compliance_password_regex(self):
"""Ask for the security compliance password regular expression.""" """Ask for the security compliance password regular expression."""
password_regex = uuid.uuid4().hex password_regex = uuid.uuid4().hex
self.config_fixture.config( self.config_fixture.config(
group='security_compliance', group='security_compliance',
password_regex=password_regex password_regex=password_regex
) )
skipping to change at line 785 skipping to change at line 785
admin_response = self.get(url, token=self._get_admin_token()) admin_response = self.get(url, token=self._get_admin_token())
self.assertEqual( self.assertEqual(
admin_response.result['config'][option], admin_response.result['config'][option],
password_regex password_regex
) )
# Ensure HEAD requests behave the same way # Ensure HEAD requests behave the same way
self.head( self.head(
url, url,
token=self._get_non_admin_token(), token=self._get_non_admin_token(),
expected_status=http_client.OK expected_status=http.client.OK
) )
self.head( self.head(
url, url,
token=self._get_admin_token(), token=self._get_admin_token(),
expected_status=http_client.OK expected_status=http.client.OK
) )
def test_get_security_compliance_password_regex_description(self): def test_get_security_compliance_password_regex_description(self):
"""Ask for the security compliance password regex description.""" """Ask for the security compliance password regex description."""
password_regex_description = uuid.uuid4().hex password_regex_description = uuid.uuid4().hex
self.config_fixture.config( self.config_fixture.config(
group='security_compliance', group='security_compliance',
password_regex_description=password_regex_description password_regex_description=password_regex_description
) )
group = 'security_compliance' group = 'security_compliance'
skipping to change at line 828 skipping to change at line 828
admin_response = self.get(url, token=self._get_admin_token()) admin_response = self.get(url, token=self._get_admin_token())
self.assertEqual( self.assertEqual(
admin_response.result['config'][option], admin_response.result['config'][option],
password_regex_description password_regex_description
) )
# Ensure HEAD requests behave the same way # Ensure HEAD requests behave the same way
self.head( self.head(
url, url,
token=self._get_non_admin_token(), token=self._get_non_admin_token(),
expected_status=http_client.OK expected_status=http.client.OK
) )
self.head( self.head(
url, url,
token=self._get_admin_token(), token=self._get_admin_token(),
expected_status=http_client.OK expected_status=http.client.OK
) )
def test_get_security_compliance_password_regex_returns_none(self): def test_get_security_compliance_password_regex_returns_none(self):
"""When an option isn't set, we should explicitly return None.""" """When an option isn't set, we should explicitly return None."""
group = 'security_compliance' group = 'security_compliance'
option = 'password_regex' option = 'password_regex'
url = ( url = (
'/domains/%(domain_id)s/config/%(group)s/%(option)s' % '/domains/%(domain_id)s/config/%(group)s/%(option)s' %
{ {
'domain_id': CONF.identity.default_domain_id, 'domain_id': CONF.identity.default_domain_id,
skipping to change at line 861 skipping to change at line 861
# be None. # be None.
regular_response = self.get(url, token=self._get_non_admin_token()) regular_response = self.get(url, token=self._get_non_admin_token())
self.assertIsNone(regular_response.result['config'][option]) self.assertIsNone(regular_response.result['config'][option])
admin_response = self.get(url, token=self._get_admin_token()) admin_response = self.get(url, token=self._get_admin_token())
self.assertIsNone(admin_response.result['config'][option]) self.assertIsNone(admin_response.result['config'][option])
# Ensure HEAD requests behave the same way # Ensure HEAD requests behave the same way
self.head( self.head(
url, url,
token=self._get_non_admin_token(), token=self._get_non_admin_token(),
expected_status=http_client.OK expected_status=http.client.OK
) )
self.head( self.head(
url, url,
token=self._get_admin_token(), token=self._get_admin_token(),
expected_status=http_client.OK expected_status=http.client.OK
) )
def test_get_security_compliance_password_regex_desc_returns_none(self): def test_get_security_compliance_password_regex_desc_returns_none(self):
"""When an option isn't set, we should explicitly return None.""" """When an option isn't set, we should explicitly return None."""
group = 'security_compliance' group = 'security_compliance'
option = 'password_regex_description' option = 'password_regex_description'
url = ( url = (
'/domains/%(domain_id)s/config/%(group)s/%(option)s' % '/domains/%(domain_id)s/config/%(group)s/%(option)s' %
{ {
'domain_id': CONF.identity.default_domain_id, 'domain_id': CONF.identity.default_domain_id,
skipping to change at line 894 skipping to change at line 894
# value should be None. # value should be None.
regular_response = self.get(url, token=self._get_non_admin_token()) regular_response = self.get(url, token=self._get_non_admin_token())
self.assertIsNone(regular_response.result['config'][option]) self.assertIsNone(regular_response.result['config'][option])
admin_response = self.get(url, token=self._get_admin_token()) admin_response = self.get(url, token=self._get_admin_token())
self.assertIsNone(admin_response.result['config'][option]) self.assertIsNone(admin_response.result['config'][option])
# Ensure HEAD requests behave the same way # Ensure HEAD requests behave the same way
self.head( self.head(
url, url,
token=self._get_non_admin_token(), token=self._get_non_admin_token(),
expected_status=http_client.OK expected_status=http.client.OK
) )
self.head( self.head(
url, url,
token=self._get_admin_token(), token=self._get_admin_token(),
expected_status=http_client.OK expected_status=http.client.OK
) )
def test_get_security_compliance_config_with_user_from_other_domain(self): def test_get_security_compliance_config_with_user_from_other_domain(self):
"""Make sure users from other domains can access password requirements. """Make sure users from other domains can access password requirements.
Even though a user is in a separate domain, they should be able to see Even though a user is in a separate domain, they should be able to see
the security requirements for the deployment. This is because security the security requirements for the deployment. This is because security
compliance is not yet implemented on a per domain basis. Once that compliance is not yet implemented on a per domain basis. Once that
happens, then this should no longer be possible since a user should happens, then this should no longer be possible since a user should
only care about the security compliance requirements for the domain only care about the security compliance requirements for the domain
skipping to change at line 975 skipping to change at line 975
) )
self.assertEqual( self.assertEqual(
response.result['config'][group]['password_regex_description'], response.result['config'][group]['password_regex_description'],
password_regex_description password_regex_description
) )
# Ensure HEAD requests behave the same way # Ensure HEAD requests behave the same way
self.head( self.head(
url, url,
token=user_token, token=user_token,
expected_status=http_client.OK expected_status=http.client.OK
) )
def test_update_security_compliance_config_group_fails(self): def test_update_security_compliance_config_group_fails(self):
"""Make sure that updates to the entire security group section fail. """Make sure that updates to the entire security group section fail.
We should only allow the ability to modify a deployments security We should only allow the ability to modify a deployments security
compliance rules through configuration. Especially since it's only compliance rules through configuration. Especially since it's only
enforced on the default domain. enforced on the default domain.
""" """
new_config = { new_config = {
skipping to change at line 1004 skipping to change at line 1004
'domain_id': CONF.identity.default_domain_id, 'domain_id': CONF.identity.default_domain_id,
'group': 'security_compliance', 'group': 'security_compliance',
} }
) )
# Make sure regular users and administrators aren't allowed to modify # Make sure regular users and administrators aren't allowed to modify
# security compliance configuration through the API. # security compliance configuration through the API.
self.patch( self.patch(
url, url,
body={'config': new_config}, body={'config': new_config},
expected_status=http_client.FORBIDDEN, expected_status=http.client.FORBIDDEN,
token=self._get_non_admin_token() token=self._get_non_admin_token()
) )
self.patch( self.patch(
url, url,
body={'config': new_config}, body={'config': new_config},
expected_status=http_client.FORBIDDEN, expected_status=http.client.FORBIDDEN,
token=self._get_admin_token() token=self._get_admin_token()
) )
def test_update_security_compliance_password_regex_fails(self): def test_update_security_compliance_password_regex_fails(self):
"""Make sure any updates to security compliance options fail.""" """Make sure any updates to security compliance options fail."""
group = 'security_compliance' group = 'security_compliance'
option = 'password_regex' option = 'password_regex'
url = ( url = (
'/domains/%(domain_id)s/config/%(group)s/%(option)s' % '/domains/%(domain_id)s/config/%(group)s/%(option)s' %
{ {
skipping to change at line 1037 skipping to change at line 1037
group: { group: {
option: uuid.uuid4().hex option: uuid.uuid4().hex
} }
} }
# Make sure regular users and administrators aren't allowed to modify # Make sure regular users and administrators aren't allowed to modify
# security compliance configuration through the API. # security compliance configuration through the API.
self.patch( self.patch(
url, url,
body={'config': new_config}, body={'config': new_config},
expected_status=http_client.FORBIDDEN, expected_status=http.client.FORBIDDEN,
token=self._get_non_admin_token() token=self._get_non_admin_token()
) )
self.patch( self.patch(
url, url,
body={'config': new_config}, body={'config': new_config},
expected_status=http_client.FORBIDDEN, expected_status=http.client.FORBIDDEN,
token=self._get_admin_token() token=self._get_admin_token()
) )
def test_update_security_compliance_password_regex_description_fails(self): def test_update_security_compliance_password_regex_description_fails(self):
"""Make sure any updates to security compliance options fail.""" """Make sure any updates to security compliance options fail."""
group = 'security_compliance' group = 'security_compliance'
option = 'password_regex_description' option = 'password_regex_description'
url = ( url = (
'/domains/%(domain_id)s/config/%(group)s/%(option)s' % '/domains/%(domain_id)s/config/%(group)s/%(option)s' %
{ {
skipping to change at line 1070 skipping to change at line 1070
group: { group: {
option: uuid.uuid4().hex option: uuid.uuid4().hex
} }
} }
# Make sure regular users and administrators aren't allowed to modify # Make sure regular users and administrators aren't allowed to modify
# security compliance configuration through the API. # security compliance configuration through the API.
self.patch( self.patch(
url, url,
body={'config': new_config}, body={'config': new_config},
expected_status=http_client.FORBIDDEN, expected_status=http.client.FORBIDDEN,
token=self._get_non_admin_token() token=self._get_non_admin_token()
) )
self.patch( self.patch(
url, url,
body={'config': new_config}, body={'config': new_config},
expected_status=http_client.FORBIDDEN, expected_status=http.client.FORBIDDEN,
token=self._get_admin_token() token=self._get_admin_token()
) )
def test_update_non_whitelisted_security_compliance_option_fails(self): def test_update_non_whitelisted_security_compliance_option_fails(self):
"""Updating security compliance options through the API is not allowed. """Updating security compliance options through the API is not allowed.
Requests to update anything in the security compliance group through Requests to update anything in the security compliance group through
the API should be Forbidden. This ensures that we are covering cases the API should be Forbidden. This ensures that we are covering cases
where the option being updated isn't in the white list. where the option being updated isn't in the white list.
""" """
skipping to change at line 1108 skipping to change at line 1108
group: { group: {
option: 1 option: 1
} }
} }
# Make sure this behavior is not possible for regular users or # Make sure this behavior is not possible for regular users or
# administrators. # administrators.
self.patch( self.patch(
url, url,
body={'config': new_config}, body={'config': new_config},
expected_status=http_client.FORBIDDEN, expected_status=http.client.FORBIDDEN,
token=self._get_non_admin_token() token=self._get_non_admin_token()
) )
self.patch( self.patch(
url, url,
body={'config': new_config}, body={'config': new_config},
expected_status=http_client.FORBIDDEN, expected_status=http.client.FORBIDDEN,
token=self._get_admin_token() token=self._get_admin_token()
) )
def test_delete_security_compliance_group_fails(self): def test_delete_security_compliance_group_fails(self):
"""The security compliance group shouldn't be deleteable.""" """The security compliance group shouldn't be deleteable."""
url = ( url = (
'/domains/%(domain_id)s/config/%(group)s/' % '/domains/%(domain_id)s/config/%(group)s/' %
{ {
'domain_id': CONF.identity.default_domain_id, 'domain_id': CONF.identity.default_domain_id,
'group': 'security_compliance', 'group': 'security_compliance',
} }
) )
# Make sure regular users and administrators can't delete the security # Make sure regular users and administrators can't delete the security
# compliance configuration group. # compliance configuration group.
self.delete( self.delete(
url, url,
expected_status=http_client.FORBIDDEN, expected_status=http.client.FORBIDDEN,
token=self._get_non_admin_token() token=self._get_non_admin_token()
) )
self.delete( self.delete(
url, url,
expected_status=http_client.FORBIDDEN, expected_status=http.client.FORBIDDEN,
token=self._get_admin_token() token=self._get_admin_token()
) )
def test_delete_security_compliance_password_regex_fails(self): def test_delete_security_compliance_password_regex_fails(self):
"""The security compliance options shouldn't be deleteable.""" """The security compliance options shouldn't be deleteable."""
url = ( url = (
'/domains/%(domain_id)s/config/%(group)s/%(option)s' % '/domains/%(domain_id)s/config/%(group)s/%(option)s' %
{ {
'domain_id': CONF.identity.default_domain_id, 'domain_id': CONF.identity.default_domain_id,
'group': 'security_compliance', 'group': 'security_compliance',
'option': 'password_regex' 'option': 'password_regex'
} }
) )
# Make sure regular users and administrators can't delete the security # Make sure regular users and administrators can't delete the security
# compliance configuration group. # compliance configuration group.
self.delete( self.delete(
url, url,
expected_status=http_client.FORBIDDEN, expected_status=http.client.FORBIDDEN,
token=self._get_non_admin_token() token=self._get_non_admin_token()
) )
self.delete( self.delete(
url, url,
expected_status=http_client.FORBIDDEN, expected_status=http.client.FORBIDDEN,
token=self._get_admin_token() token=self._get_admin_token()
) )
def test_delete_security_compliance_password_regex_description_fails(self): def test_delete_security_compliance_password_regex_description_fails(self):
"""The security compliance options shouldn't be deleteable.""" """The security compliance options shouldn't be deleteable."""
url = ( url = (
'/domains/%(domain_id)s/config/%(group)s/%(option)s' % '/domains/%(domain_id)s/config/%(group)s/%(option)s' %
{ {
'domain_id': CONF.identity.default_domain_id, 'domain_id': CONF.identity.default_domain_id,
'group': 'security_compliance', 'group': 'security_compliance',
'option': 'password_regex_description' 'option': 'password_regex_description'
} }
) )
# Make sure regular users and administrators can't delete the security # Make sure regular users and administrators can't delete the security
# compliance configuration group. # compliance configuration group.
self.delete( self.delete(
url, url,
expected_status=http_client.FORBIDDEN, expected_status=http.client.FORBIDDEN,
token=self._get_non_admin_token() token=self._get_non_admin_token()
) )
self.delete( self.delete(
url, url,
expected_status=http_client.FORBIDDEN, expected_status=http.client.FORBIDDEN,
token=self._get_admin_token() token=self._get_admin_token()
) )
def test_delete_non_whitelisted_security_compliance_options_fails(self): def test_delete_non_whitelisted_security_compliance_options_fails(self):
"""The security compliance options shouldn't be deleteable.""" """The security compliance options shouldn't be deleteable."""
url = ( url = (
'/domains/%(domain_id)s/config/%(group)s/%(option)s' % '/domains/%(domain_id)s/config/%(group)s/%(option)s' %
{ {
'domain_id': CONF.identity.default_domain_id, 'domain_id': CONF.identity.default_domain_id,
'group': 'security_compliance', 'group': 'security_compliance',
'option': 'lockout_failure_attempts' 'option': 'lockout_failure_attempts'
} }
) )
# Make sure regular users and administrators can't delete the security # Make sure regular users and administrators can't delete the security
# compliance configuration group. # compliance configuration group.
self.delete( self.delete(
url, url,
expected_status=http_client.FORBIDDEN, expected_status=http.client.FORBIDDEN,
token=self._get_non_admin_token() token=self._get_non_admin_token()
) )
self.delete( self.delete(
url, url,
expected_status=http_client.FORBIDDEN, expected_status=http.client.FORBIDDEN,
token=self._get_admin_token() token=self._get_admin_token()
) )
 End of changes. 58 change blocks. 
63 lines changed or deleted 63 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)