Changeset - 2a18e52c9947
[Not reviewed]
0 3 0
Branko Majic (branko) - 6 years ago 2018-03-18 11:15:50
branko@majic.rs
GC-16: Do not overwrite existing client artifacts:

- Added functional test for the scenario.
- Implemented unit tests that ensure client artifacts are not getting
overwritten if they already exist.
- Added check that ensures the client certificate has not been issued
previously.
3 files changed with 63 insertions and 0 deletions:
0 comments (0 inline, 0 general)
functional_tests/test_client.py
Show inline comments
 
@@ -133,3 +133,36 @@ def test_client_command_issues_client_certificate(tmpdir):
 

	
 
    # He is happy to see that verification succeeds.
 
    assert error_code == 0
 

	
 

	
 
def test_client_command_does_not_overwrite_existing_artifacts(tmpdir):
 
    # John has used Gimmecert in one of his previous projects. In
 
    # particular, he has issued some TLS client certificates for
 
    # testing the TLS client authentication.
 
    tmpdir.chdir()
 
    run_command("gimmecert", "init")
 
    run_command("gimmecert", "client", "myclient")
 

	
 
    private_key = tmpdir.join(".gimmecert", "client", "myclient.key.pem").read()
 
    certificate = tmpdir.join(".gimmecert", "client", "myclient.cert.pem").read()
 

	
 
    # After some months of inactivity, John figures he needs to
 
    # perform a quick test on the project related to TLS client
 
    # certificate authentication. He goes ahead and runs a command to
 
    # issue the client certificate.
 
    tmpdir.chdir()
 
    stdout, stderr, exit_code = run_command("gimmecert", "client", "myclient")
 

	
 
    # John realizes in last moment, just as he presses ENTER, that he
 
    # had issued certificate already. He wonders if he'd need to
 
    # redeploy it again now, though. Luckily, Gimmecert detects this,
 
    # and provides him with an informative warning.
 
    assert exit_code != 0
 
    assert stderr == "Refusing to overwrite existing data. Certificate has already been issued for client myclient.\n"
 
    assert stdout == ""
 

	
 
    # John double-checks (just to be on the safe side), and can see
 
    # that both the private key and certificate have been left
 
    # unchanged.
 
    assert tmpdir.join(".gimmecert", "client", "myclient.key.pem").read() == private_key
 
    assert tmpdir.join(".gimmecert", "client", "myclient.cert.pem").read() == certificate
gimmecert/commands.py
Show inline comments
 
@@ -216,6 +216,10 @@ def client(stdout, stderr, project_directory, entity_name):
 
        print("CA hierarchy must be initialised prior to issuing client certificates. Run the gimmecert init command first.", file=stderr)
 
        return ExitCode.ERROR_NOT_INITIALISED
 

	
 
    if os.path.exists(private_key_path) or os.path.exists(certificate_path):
 
        print("Refusing to overwrite existing data. Certificate has already been issued for client %s." % entity_name, file=stderr)
 
        return ExitCode.ERROR_CERTIFICATE_ALREADY_ISSUED
 

	
 
    ca_hierarchy = gimmecert.storage.read_ca_hierarchy(os.path.join(project_directory, '.gimmecert', 'ca'))
 
    issuer_private_key, issuer_certificate = ca_hierarchy[-1]
 
    private_key = gimmecert.crypto.generate_private_key()
tests/test_commands.py
Show inline comments
 
@@ -388,3 +388,29 @@ def test_client_outputs_certificate_to_file(tmpdir):
 

	
 
    assert certificate_file_content.startswith('-----BEGIN CERTIFICATE-----')
 
    assert certificate_file_content.endswith('-----END CERTIFICATE-----\n')
 

	
 

	
 
def test_client_errors_out_if_certificate_already_issued(tmpdir):
 
    depth = 1
 

	
 
    stdout_stream = io.StringIO()
 
    stderr_stream = io.StringIO()
 

	
 
    # Previous run.
 
    gimmecert.commands.init(io.StringIO(), io.StringIO(), tmpdir.strpath, tmpdir.basename, depth)
 
    gimmecert.commands.client(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myclient')
 
    existing_private_key = tmpdir.join('.gimmecert', 'client', 'myclient.key.pem').read()
 
    certificate = tmpdir.join('.gimmecert', 'client', 'myclient.cert.pem').read()
 

	
 
    # New run.
 
    status_code = gimmecert.commands.client(stdout_stream, stderr_stream, tmpdir.strpath, 'myclient')
 

	
 
    stdout = stdout_stream.getvalue()
 
    stderr = stderr_stream.getvalue()
 

	
 
    assert status_code == gimmecert.commands.ExitCode.ERROR_CERTIFICATE_ALREADY_ISSUED
 
    assert "already been issued" in stderr
 
    assert "client myclient" in stderr
 
    assert stdout == ""
 
    assert tmpdir.join('.gimmecert', 'client', 'myclient.key.pem').read() == existing_private_key
 
    assert tmpdir.join('.gimmecert', 'client', 'myclient.cert.pem').read() == certificate
0 comments (0 inline, 0 general)