Move to password validation schema
This change moves the user api change password value check to JSON schema, rather than manually checking for empty/invalid values. After this, more of the password validation can be moved up to schema from code. Change-Id: I15b1df51af53d56293a7b1b2a06fda7f4e5d45eb
This commit is contained in:
parent
d53ed61468
commit
dec8c717c9
|
@ -199,26 +199,13 @@ class UserChangePasswordResource(ks_flask.ResourceBase):
|
|||
@ks_flask.unenforced_api
|
||||
def post(self, user_id):
|
||||
user_data = self.request_body_json.get('user', {})
|
||||
original_password = user_data.get('original_password')
|
||||
new_password = user_data.get('password')
|
||||
|
||||
# TODO(morgan): Convert this to JSON Schema validation
|
||||
if original_password is None:
|
||||
raise ks_exception.ValidationError(
|
||||
target='user',
|
||||
attribute='original_password')
|
||||
|
||||
# TODO(morgan): Convert this to JSON Schema validation
|
||||
if new_password is None:
|
||||
raise ks_exception.ValidationError(
|
||||
target='user',
|
||||
attribute='password')
|
||||
validation.lazy_validate(schema.password_change, user_data)
|
||||
|
||||
try:
|
||||
PROVIDERS.identity_api.change_password(
|
||||
user_id=user_id,
|
||||
original_password=original_password,
|
||||
new_password=new_password,
|
||||
original_password=user_data['original_password'],
|
||||
new_password=user_data['password'],
|
||||
initiator=self.audit_initiator)
|
||||
except AssertionError as e:
|
||||
raise ks_exception.Unauthorized(
|
||||
|
|
|
@ -12,9 +12,13 @@
|
|||
|
||||
from keystone.common import validation
|
||||
from keystone.common.validation import parameter_types
|
||||
import keystone.conf
|
||||
from keystone.identity.backends import resource_options as ro
|
||||
|
||||
|
||||
CONF = keystone.conf.CONF
|
||||
|
||||
|
||||
_identity_name = {
|
||||
'type': 'string',
|
||||
'minLength': 1,
|
||||
|
@ -77,3 +81,27 @@ group_update = {
|
|||
'minProperties': 1,
|
||||
'additionalProperties': True
|
||||
}
|
||||
|
||||
_password_change_properties = {
|
||||
'original_password': {
|
||||
'type': 'string'
|
||||
},
|
||||
'password': {
|
||||
'type': 'string'
|
||||
}
|
||||
}
|
||||
if getattr(CONF, 'strict_password_check', None):
|
||||
_password_change_properties['password']['maxLength'] = \
|
||||
CONF.identity.max_password_length
|
||||
|
||||
if getattr(CONF, 'security_compliance', None):
|
||||
if getattr(CONF.security_compliance, 'password_regex', None):
|
||||
_password_change_properties['password']['pattern'] = \
|
||||
CONF.security_compliance.password_regex
|
||||
|
||||
password_change = {
|
||||
'type': 'object',
|
||||
'properties': _password_change_properties,
|
||||
'required': ['original_password', 'password'],
|
||||
'additionalProperties': False
|
||||
}
|
||||
|
|
|
@ -2185,6 +2185,49 @@ class GroupValidationTestCase(unit.BaseTestCase):
|
|||
request_to_validate)
|
||||
|
||||
|
||||
class ChangePasswordValidationTestCase(unit.BaseTestCase):
|
||||
"""Test for Change Password API validation."""
|
||||
|
||||
def setUp(self):
|
||||
super(ChangePasswordValidationTestCase, self).setUp()
|
||||
|
||||
self.original_password = uuid.uuid4().hex
|
||||
self.password = uuid.uuid4().hex
|
||||
|
||||
change = identity_schema.password_change
|
||||
self.change_password_validator = validators.SchemaValidator(change)
|
||||
|
||||
def test_validate_password_change_request_succeeds(self):
|
||||
"""Test that validating a password change request succeeds."""
|
||||
request_to_validate = {'original_password': self.original_password,
|
||||
'password': self.password}
|
||||
self.change_password_validator.validate(request_to_validate)
|
||||
|
||||
def test_validate_password_change_fails_without_all_fields(self):
|
||||
"""Test that validating a password change fails without all values."""
|
||||
request_to_validate = {'original_password': self.original_password}
|
||||
self.assertRaises(exception.SchemaValidationError,
|
||||
self.change_password_validator.validate,
|
||||
request_to_validate)
|
||||
request_to_validate = {'password': self.password}
|
||||
self.assertRaises(exception.SchemaValidationError,
|
||||
self.change_password_validator.validate,
|
||||
request_to_validate)
|
||||
|
||||
def test_validate_password_change_fails_with_invalid_values(self):
|
||||
"""Test that validating a password change fails with bad values."""
|
||||
request_to_validate = {'original_password': None,
|
||||
'password': None}
|
||||
self.assertRaises(exception.SchemaValidationError,
|
||||
self.change_password_validator.validate,
|
||||
request_to_validate)
|
||||
request_to_validate = {'original_password': 42,
|
||||
'password': True}
|
||||
self.assertRaises(exception.SchemaValidationError,
|
||||
self.change_password_validator.validate,
|
||||
request_to_validate)
|
||||
|
||||
|
||||
class IdentityProviderValidationTestCase(unit.BaseTestCase):
|
||||
"""Test for V3 Identity Provider API validation."""
|
||||
|
||||
|
|
Loading…
Reference in New Issue