def validate_password(password): pattern = CONF.security_compliance.password_regex if pattern: if not isinstance(password, six.string_types): detail = _("Password must be a string type") raise exception.PasswordValidationError(detail=detail) try: if not re.match(pattern, password): pattern_desc = ( CONF.security_compliance.password_regex_description) raise exception.PasswordRequirementsValidationError( detail=pattern_desc) except re.error: msg = ("Unable to validate password due to invalid regular " "expression - password_regex: ") LOG.error(msg, pattern) detail = _("Unable to validate password due to invalid " "configuration") raise exception.PasswordValidationError(detail=detail)
def update_user(self, user_id, user): # only allow password or status changes allowed = ['password', 'enabled', 'login'] for k in user: if k not in allowed: self._disallow_write() old_obj = self.user.get(user_id) if 'name' in user and old_obj.get('name') != user['name']: raise exception.Conflict(_('Cannot change user name')) if 'password' in user: # force LDAP replace old_obj['password'] = '******' LOG.info("User password update %s" % user_id) # special CC sauce to allow onboarding of new provisioned CAM users with no password and userAccountControl 514 if 'login' in user: user.pop('login') if 'ccObjectStatus' not in old_obj: # this indicates that it is indeed a freshly provisioned CAM user: enable the user user['enabled'] = True if 'enabled' in user: if user['enabled']: if 'sapObjectStatus' in old_obj and \ old_obj['sapObjectStatus'] != STATUS_ACTIVE: raise exception.Conflict(_('User is inactive.')) else: user['ccObjectStatus'] = STATUS_ACTIVE else: user['ccObjectStatus'] = STATUS_INACTIVE if self.user.enabled_mask: self.user.mask_enabled_attribute(user) elif self.user.enabled_invert and not self.user.enabled_emulation: # We need to invert the enabled value for the old model object # to prevent the LDAP update code from thinking that the enabled # values are already equal. user['enabled'] = not user['enabled'] old_obj['enabled'] = not old_obj['enabled'] if 'camObjectStatus' in user and old_obj.get('camObjectStatus') != \ user['camObjectStatus']: raise exception.ForbiddenNotSecurity( _('user.camObjectStatus is a read-only attribute')) if 'sapObjectStatus' in user and old_obj.get('sapObjectStatus') != \ user['sapObjectStatus']: raise exception.ForbiddenNotSecurity( _('user.sapObjectStatus is a read-only attribute')) try: self.user.update(user_id, user, old_obj) except ldap.UNWILLING_TO_PERFORM as e: # If the exceptions's 'info' field begins with: # 00000056 - Current passwords do not match # 0000052D - New password violates length/complexity/history msg = e[0]['desc'] LOG.error("User update %s failed: %s" % (user_id, msg)) if e[0]['info'].startswith('0000052D'): msg = '"Unable to update the password. The value provided for the new password does not meet the length, complexity, or history requirements of the domain." ' raise exception.PasswordRequirementsValidationError(msg) else: raise e return self.user.get_filtered(user_id)