Skip to content

Commit

Permalink
Add basic auth generator function (#873)
Browse files Browse the repository at this point in the history
* Add generator function for basic auth

* Add testing for basic auth generator function

* Add documentation for basicauth generator function

* Fix lint and tests
  • Loading branch information
MatteoVoges authored Nov 19, 2022
1 parent 6148111 commit 1e2afe5
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/secrets.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ When referencing your secret in the inventory during compile, you can use the fo
- `ed25519` - Generates a ed25519 private key (PKCS#8).
- `publickey` - Derives the public key from a revealed private key i.e. `||reveal:path/to/encrypted_private_key|publickey`
- `rsapublic` - Derives an RSA public key from a revealed private key i.e. `||reveal:path/to/encrypted_private_key|rsapublic` (deprecated, use `publickey` instead)
- `basicauth` - Generates a base64 encoded pair of `username:password`, i.e. `||basicauth:username:password`

*Note*: The first operator here `||` is more similar to a logical OR. If the secret file doesn't exist, kapitan will generate it and apply the functions after the `||`. If the secret file already exists, no functions will run.

Expand Down
23 changes: 22 additions & 1 deletion kapitan/refs/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def get_func_lookup():
"publickey": public_key,
"reveal": reveal,
"loweralphanum": loweralphanum,
"basicauth": basicauth,
}


Expand Down Expand Up @@ -155,8 +156,8 @@ def loweralphanum(ctx, nchars="8"):
def random(ctx, type="str", nchars="", special_chars=string.punctuation):
"""
generates a text string, containing nchars of given type
"""

pool_lookup = {
"str": string.ascii_letters + string.digits + "-_",
"int": string.digits,
Expand Down Expand Up @@ -206,3 +207,23 @@ def random(ctx, type="str", nchars="", special_chars=string.punctuation):

# set ctx.data to generated string
ctx.data = generated_str


def basicauth(ctx, username="", password=""):
# check if parameters are specified
if not username:
# use random pet name as username
username = "".join(secrets.choice(string.ascii_lowercase) for i in range(8))

if not password:
# generate random password
pool = string.ascii_letters + string.digits
password = "".join(secrets.choice(pool) for i in range(8))
# generate basic-auth token (base64-encoded)
token = username + ":" + password
token_bytes = token.encode()
token_bytes_b64 = base64.b64encode(token_bytes)
token_b64 = token_bytes_b64.decode()

# set generated token to ctx.data
ctx.data = token_b64
19 changes: 19 additions & 0 deletions tests/test_refs.py
Original file line number Diff line number Diff line change
Expand Up @@ -550,3 +550,22 @@ def test_ref_function_special(self):
self.assertEqual(len(revealed), 32)
intersection = set(string.punctuation).intersection(revealed)
self.assertTrue(intersection.issubset(set(allowed_special_chars)))

def test_ref_function_basicauth(self):
"write basicauth to secret, confirm ref file exists, reveal and check"
tag = "?{plain:ref/basicauth||basicauth}"
REF_CONTROLLER[tag] = RefParams()
self.assertTrue(os.path.isfile(os.path.join(REFS_HOME, "ref/basicauth")))

file_with_tags = tempfile.mktemp()
with open(file_with_tags, "w") as fp:
fp.write("?{plain:ref/basicauth}")
revealed = REVEALER.reveal_raw_file(file_with_tags)
self.assertEqual(len(revealed), 24) # default length of basicauth is 17

# Test with parameters username=user123 and password=mysecretpassword
tag = "?{plain:ref/basicauth||basicauth:user123:mysecretpassword}"
REF_CONTROLLER[tag] = RefParams()
REVEALER._reveal_tag_without_subvar.cache_clear()
revealed = REVEALER.reveal_raw_file(file_with_tags)
self.assertEqual(revealed, "dXNlcjEyMzpteXNlY3JldHBhc3N3b3Jk")

0 comments on commit 1e2afe5

Please sign in to comment.