Add CLI generation of salt
Salts and Passphrases are both strings used in cryptography. This patch: 1. Adds CLI generation of salt 2. Adds unit test for CLI generation of salt 3. Updates passphrase.py code to be more generic as it is used to generate both a passphrase and a salt 4. Update name of passphrase.py to be more generic 5. Update all references to, and tests of passphrase.py 6. Add documentation for CLI generation of salt Co-Authored-By: chittibabu <cg329x@att.com> Change-Id: I71858d63a2846290d22be96686ccfea3ba8aa6c0
This commit is contained in:
parent
4b00a4340c
commit
671b77f6a7
@ -846,3 +846,34 @@ Example with length specified:
|
||||
::
|
||||
|
||||
./pegleg.sh generate passphrase -l <length>
|
||||
|
||||
Salt
|
||||
----
|
||||
|
||||
Generate a salt and print to ``stdout``.
|
||||
|
||||
**-l / --length** (Optional).
|
||||
|
||||
Length of salt to generate. By default length is 24.
|
||||
Minimum length is 24. No maximum length.
|
||||
|
||||
Usage:
|
||||
|
||||
::
|
||||
|
||||
./pegleg.sh generate salt -l <length>
|
||||
|
||||
Examples
|
||||
^^^^^^^^
|
||||
|
||||
Example without length specified:
|
||||
|
||||
::
|
||||
|
||||
./pegleg.sh generate salt
|
||||
|
||||
Example with length specified:
|
||||
|
||||
::
|
||||
|
||||
./pegleg.sh generate salt -l <length>
|
@ -549,4 +549,19 @@ def generate():
|
||||
'Length is >= 24, default length is 24, no maximum length')
|
||||
def generate_passphrase(length):
|
||||
click.echo("Generated Passhprase: {}".format(
|
||||
engine.secrets.generate_passphrase(length)))
|
||||
engine.secrets.generate_crypto_string(length)))
|
||||
|
||||
|
||||
@generate.command(
|
||||
'salt',
|
||||
help='Command to generate a salt and print out to stdout')
|
||||
@click.option(
|
||||
'-l',
|
||||
'--length',
|
||||
'length',
|
||||
default=24,
|
||||
help='Generate a salt of the given length. '
|
||||
'Length is >= 24, default length is 24, no maximum length')
|
||||
def generate_salt(length):
|
||||
click.echo("Generated Salt: {}".format(
|
||||
engine.secrets.generate_crypto_string(length)))
|
||||
|
@ -18,8 +18,8 @@ import logging
|
||||
from pegleg.engine.catalogs import passphrase_catalog
|
||||
from pegleg.engine.catalogs.passphrase_catalog import PassphraseCatalog
|
||||
from pegleg.engine.generators.base_generator import BaseGenerator
|
||||
from pegleg.engine.util.cryptostring import CryptoString
|
||||
from pegleg.engine.util import files
|
||||
from pegleg.engine.util.passphrase import Passphrase
|
||||
from pegleg.engine.util.pegleg_secret_management import PeglegSecretManagement
|
||||
|
||||
__all__ = ['PassphraseGenerator']
|
||||
@ -49,7 +49,7 @@ class PassphraseGenerator(BaseGenerator):
|
||||
sitename, save_location, author)
|
||||
self._catalog = PassphraseCatalog(
|
||||
self._sitename, documents=self._documents)
|
||||
self._pass_util = Passphrase()
|
||||
self._pass_util = CryptoString()
|
||||
|
||||
def generate(self, interactive=False):
|
||||
"""
|
||||
@ -67,7 +67,7 @@ class PassphraseGenerator(BaseGenerator):
|
||||
prompt="Input passphrase for {}. Leave blank to "
|
||||
"auto-generate:\n".format(p_name))
|
||||
if not passphrase:
|
||||
passphrase = self._pass_util.get_pass(
|
||||
passphrase = self._pass_util.get_crypto_string(
|
||||
self._catalog.get_length(p_name))
|
||||
docs = list()
|
||||
storage_policy = self._catalog.get_storage_policy(p_name)
|
||||
|
@ -16,9 +16,9 @@ import logging
|
||||
import os
|
||||
|
||||
from pegleg.engine.generators.passphrase_generator import PassphraseGenerator
|
||||
from pegleg.engine.util.cryptostring import CryptoString
|
||||
from pegleg.engine.util import definition
|
||||
from pegleg.engine.util import files
|
||||
from pegleg.engine.util.passphrase import Passphrase
|
||||
from pegleg.engine.util.pegleg_secret_management import PeglegSecretManagement
|
||||
|
||||
__all__ = ('encrypt', 'decrypt', 'generate_passphrases')
|
||||
@ -132,12 +132,12 @@ def generate_passphrases(site_name, save_location, author, interactive=False):
|
||||
interactive=interactive)
|
||||
|
||||
|
||||
def generate_passphrase(length):
|
||||
def generate_crypto_string(length):
|
||||
"""
|
||||
Create a passphrase.
|
||||
Create a cryptographic string.
|
||||
|
||||
:param int length: Length of passphrase.
|
||||
:param int length: Length of cryptographic string.
|
||||
:rtype: string
|
||||
"""
|
||||
|
||||
return Passphrase().get_pass(length)
|
||||
return CryptoString().get_crypto_string(length)
|
||||
|
@ -17,17 +17,21 @@ from random import SystemRandom
|
||||
from rstr import Rstr
|
||||
import string
|
||||
|
||||
__all__ = ['Passphrase']
|
||||
__all__ = ['CryptoString']
|
||||
|
||||
|
||||
class Passphrase(object):
|
||||
class CryptoString(object):
|
||||
|
||||
def __init__(self):
|
||||
self._pool = string.ascii_letters + string.digits + string.punctuation
|
||||
self._rs = Rstr(SystemRandom())
|
||||
|
||||
def get_pass(self, pass_len=24):
|
||||
"""Create and return a random password, of the ``pass_len`` length."""
|
||||
if pass_len < 24:
|
||||
pass_len = 24
|
||||
return self._rs.rstr(self._pool, pass_len)
|
||||
def get_crypto_string(self, len=24):
|
||||
"""
|
||||
Create and return a random cryptographic string,
|
||||
of the ``len`` length.
|
||||
"""
|
||||
|
||||
if len < 24:
|
||||
len = 24
|
||||
return self._rs.rstr(self._pool, len)
|
@ -19,7 +19,7 @@ import mock
|
||||
import string
|
||||
import yaml
|
||||
|
||||
from pegleg.engine.util.passphrase import Passphrase
|
||||
from pegleg.engine.util.cryptostring import CryptoString
|
||||
from pegleg.engine.generators.passphrase_generator import PassphraseGenerator
|
||||
from pegleg.engine.util import encryption
|
||||
from pegleg.engine import util
|
||||
@ -99,30 +99,30 @@ TEST_SITE_DEFINITION = {
|
||||
TEST_SITE_DOCUMENTS = [TEST_SITE_DEFINITION, TEST_PASSPHRASES_CATALOG]
|
||||
|
||||
|
||||
def test_passphrase_default_len():
|
||||
p_util = Passphrase()
|
||||
passphrase = p_util.get_pass()
|
||||
assert len(passphrase) == 24
|
||||
def test_cryptostring_default_len():
|
||||
s_util = CryptoString()
|
||||
s = s_util.get_crypto_string()
|
||||
assert len(s) == 24
|
||||
alphabet = set(string.punctuation + string.ascii_letters + string.digits)
|
||||
assert any(c in alphabet for c in passphrase)
|
||||
assert any(c in alphabet for c in s)
|
||||
|
||||
|
||||
def test_passphrase_short_len():
|
||||
p_util = Passphrase()
|
||||
p = p_util.get_pass(0)
|
||||
assert len(p) == 24
|
||||
p = p_util.get_pass(23)
|
||||
assert len(p) == 24
|
||||
p = p_util.get_pass(-1)
|
||||
assert len(p) == 24
|
||||
def test_cryptostring_short_len():
|
||||
s_util = CryptoString()
|
||||
s = s_util.get_crypto_string(0)
|
||||
assert len(s) == 24
|
||||
s = s_util.get_crypto_string(23)
|
||||
assert len(s) == 24
|
||||
s = s_util.get_crypto_string(-1)
|
||||
assert len(s) == 24
|
||||
|
||||
|
||||
def test_passphrase_long_len():
|
||||
p_util = Passphrase()
|
||||
p = p_util.get_pass(25)
|
||||
assert len(p) == 25
|
||||
p = p_util.get_pass(128)
|
||||
assert len(p) == 128
|
||||
def test_cryptostring_long_len():
|
||||
s_util = CryptoString()
|
||||
s = s_util.get_crypto_string(25)
|
||||
assert len(s) == 25
|
||||
s = s_util.get_crypto_string(128)
|
||||
assert len(s) == 128
|
||||
|
||||
|
||||
@mock.patch.object(
|
@ -389,6 +389,11 @@ class TestGenerateActions(BaseCLIActionTest):
|
||||
|
||||
assert result.exit_code == 0, result.output
|
||||
|
||||
def test_generate_salt(self):
|
||||
result = self.runner.invoke(cli.generate, ['salt'])
|
||||
|
||||
assert result.exit_code == 0, result.output
|
||||
|
||||
|
||||
class TestRepoCliActions(BaseCLIActionTest):
|
||||
"""Tests repo-level CLI actions."""
|
||||
|
Loading…
Reference in New Issue
Block a user