diff --git a/pegleg/engine/generators/passphrase_generator.py b/pegleg/engine/generators/passphrase_generator.py index 55d947f3..4ca511a0 100644 --- a/pegleg/engine/generators/passphrase_generator.py +++ b/pegleg/engine/generators/passphrase_generator.py @@ -81,21 +81,28 @@ class PassphraseGenerator(BaseGenerator): passphrase_type = self._catalog.get_passphrase_type(p_name) prompt = self._catalog.is_passphrase_prompt(p_name) if interactive or prompt: - passphrase = self.get_interactive_pass(p_name) + auto_allowed = not (prompt and not regenerable) # nosec if passphrase_type == 'uuid': # nosec - validated = uuidutils.is_uuid_like(passphrase) - while passphrase and not validated: - click.echo('Passphrase {} is not a valid uuid.') - passphrase = self.get_interactive_pass(p_name) - validated = uuidutils.is_uuid_like(passphrase) + passphrase = self._prompt_user_passphrase_and_validate( + p_name, + 'UUID', + self.validate_uuid, + auto_allowed=auto_allowed) elif passphrase_type == 'base64': # nosec - validated = self.is_base64_like(passphrase) - while passphrase and not validated: - click.echo('Passphrase {} is not base64 like.') - passphrase = self.get_interactive_pass(p_name) - validated = self.is_base64_like(passphrase) + passphrase = self._prompt_user_passphrase_and_validate( + p_name, + 'passphrase (b64)', + self.validate_base64, + auto_allowed=auto_allowed) + + elif passphrase_type == 'passphrase': + passphrase = self._prompt_user_passphrase_and_validate( + p_name, + 'passphrase', + self.validate_passphrase, + auto_allowed=auto_allowed) if not passphrase: if passphrase_type == 'uuid': # nosec @@ -128,23 +135,69 @@ class PassphraseGenerator(BaseGenerator): else: files.write(docs, save_path) - def get_interactive_pass(self, p_name): - passphrase = getpass( - prompt="Input passphrase/UUID for {}. Leave blank to " - "auto-generate:\n".format(p_name)) + def _prompt_user_passphrase_and_validate( + self, p_name, p_type, validation_func, auto_allowed=True): + passphrase = self.get_interactive_pass( + p_name, p_type, auto_allowed=auto_allowed) + validated = self.validate_auto( + passphrase, auto_allowed) and validation_func(passphrase) + while not validated: + passphrase = self.get_interactive_pass( + p_name, p_type, auto_allowed=auto_allowed) + validated = self.validate_auto( + passphrase, auto_allowed) and validation_func(passphrase) return passphrase - def is_base64_like(self, passphrase): + @staticmethod + def get_interactive_pass(p_name, p_type, auto_allowed=True): + if auto_allowed: + prompt = ('Input {} for {}. Leave blank to ' + 'auto-generate:\n').format(p_type, p_name) + else: + prompt = 'Input {} for {}:\n'.format(p_type, p_name) + prompt.format(p_name) + passphrase = getpass(prompt=prompt) + return passphrase + + @staticmethod + def validate_base64(passphrase): pattern = re.compile( "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+" "/]{3}=|[A-Za-z0-9+/]{2}==)$") if not passphrase or len(passphrase) < 1: + click.echo( + 'Passphrase "{}" is not base64 like.'.format(passphrase)) return False elif pattern.match(passphrase): return True else: + click.echo( + 'Passphrase "{}" is not base64 like.'.format(passphrase)) return False + @staticmethod + def validate_uuid(passphrase): + if uuidutils.is_uuid_like(passphrase): + return True + else: + click.echo('Passphrase "{}" is not UUID like.'.format(passphrase)) + return False + + @staticmethod + def validate_passphrase(passphrase): + """Passphrase type is not currently validated""" + return True + + @staticmethod + def validate_auto(passphrase, auto_allowed): + if not passphrase and not auto_allowed: + click.echo( + 'Documents cannot have autogenerated passphrases when prompt ' + 'is true and regenerable is false.') + return False + else: + return True + @property def kind_path(self): return KIND_PATH