Skip to content

Commit

Permalink
Temp commit
Browse files Browse the repository at this point in the history
  • Loading branch information
elibon99 committed Sep 5, 2023
1 parent ab2f4ac commit 2279a4d
Show file tree
Hide file tree
Showing 41 changed files with 2,326 additions and 313 deletions.
6 changes: 6 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"[python]": {
"editor.defaultFormatter": "ms-python.autopep8"
},
"python.formatting.provider": "none"
}
24 changes: 24 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
FROM python:3.9
FROM ubuntu:latest


RUN apt-get update
RUN apt-get install -y --no-install-recommends python3-setuptools python3-pip gcc python3-dev musl-dev libffi-dev git gnupg bash
#RUN apk add --no-cache build-base gcc python3-dev postgresql-dev musl-dev libffi-dev git gnupg bash
RUN apt-get install -y openssh-server
RUN pip3 install setuptools-rust
RUN pip3 install --upgrade pip
RUN pip3 install poetry


RUN ssh -V


WORKDIR /code

COPY . /code/

RUN poetry install

RUN poetry run pytest

144 changes: 114 additions & 30 deletions gitbark/_cli/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,50 +12,134 @@
# See the License for the specific language governing permissions and
# limitations under the License.

# from gitbark.commands.verify import verify as verify_cmd
# from gitbark.commands.install import install as install_cmd, is_installed
# from gitbark.bark_core.signatures.commands.approve_cmd import approve_cmd
# from gitbark.bark_core.signatures.commands.add_detached_signatures_cmd import add_detached_signatures_cmd
from gitbark.git_helper import get_root
from gitbark.commands.install import bootstrap_verified, is_installed, install as install_cmd
from gitbark.commands.verify import verify as verify_cmd
from gitbark.commands.install import install as install_cmd, is_installed
from gitbark.bark_core.signatures.commands.approve_cmd import approve_cmd
from gitbark.bark_core.signatures.commands.add_detached_signatures_cmd import add_detached_signatures_cmd
from gitbark.wd import WorkingDirectory
import click
from gitbark.git.commit import Commit
from gitbark.store import Store
from .util import BarkContextObject, click_callback
from gitbark.util import cmd
from gitbark.git.reference_update import ReferenceUpdate


from pygit2 import Repository

import sys
import click

from gitbark import globals

@click.group()
def cli():
globals.init()
pass
@click.pass_context
def cli(ctx):
ctx.obj = BarkContextObject()

toplevel = get_root()
repo = Repository(toplevel)
store = Store()

ctx.obj["wd"] = toplevel
ctx.obj["repo"] = repo
ctx.obj["store"] = store

project = store.get_project(toplevel)
if not project:
project = store.create_project(toplevel)
ctx.obj["project"] = project

globals.init(toplevel)

@cli.command()
def install():
install_cmd()
@click.pass_context
def install(ctx):
project = ctx.obj["project"]
store = ctx.obj["store"]

root_commit = cmd("git", "rev-list", "--max-parents=0", "branch_rules")[0]
if root_commit != project.root_commit:
click.echo(f"The bootstrap commit ({root_commit}) of the branch_rules "
"branch has not been verified!")
click.confirm(
"Do you want to trust this commit as the bootstrap commit?",
abort=True,
err=True
)
project.set_root_commit(root_commit)

report = install_cmd(project)

if report.is_repo_valid():
click.echo("Installed GitBark successfully!")
store.update_project(project)

else:
click.echo("Failed to verify repository!")
report.print_report()
click.echo("Aborting!")
exit(1)


@click_callback()
def click_parse_ref_update(ctx, param, val):
old_ref, new_ref, ref_name = val
return ReferenceUpdate(old_ref, new_ref, ref_name)

@click_callback()
def click_parse_bootstrap(ctx, param, val):
if val:
return Commit(val)
return None


@cli.command()
@click.option('-r', '--ref-update', type=(str, str, str))
@click.pass_context
@click.option('-r', '--ref-update', type=(str, str, str), callback=click_parse_ref_update)
@click.option("--all", is_flag=True, show_default=True, default=False, help="Verify all branches")
@click.option("-b", "--bootstrap", type=str, help="Verify from bootstrap")
def verify(ref_update, all, bootstrap):
if not is_installed():
print("Error: Bark is not properly installed! Run \"bark install\" first!")
sys.exit(1)
verify_cmd(all, ref_update, bootstrap)
@click.option("-b", "--bootstrap", type=str, help="Verify from bootstrap", callback=click_parse_bootstrap)
def verify(ctx, ref_update, all, bootstrap):
project = ctx.obj["project"]
if not is_installed(project):
raise Exception("Error: Bark is not installed! Run \"bark install\" first!")
store = ctx.obj["store"]

# If GitBark is not installed, prompt the user to install

report = verify_cmd(
project,
ref_update,
bootstrap,
all,
)

report.print_report()
if report.is_repo_valid():
store.update_project(project)
else:
if ref_update:
exit_status = ref_update.exit_status
if exit_status == 1:
cmd("git", "restore", "--staged", ".")
cmd("git", "restore", ".")
exit(ref_update.exit_status)




# TODO: Add these commands dynamically
@cli.command()
@click.argument("commit")
@click.option('--gpg-sign', type=str)
@click.option('--ssh-key-path', type=str)
def approve(commit, gpg_sign, ssh_key_path):
approve_cmd(commit, gpg_sign, ssh_key_path)

@cli.command(name="add-detached-signatures")
@click.argument("commit-msg-file", type=str)
def add_detached_signatures(commit_msg_file):
add_detached_signatures_cmd(commit_msg_file)
# # TODO: Add these commands dynamically
# @cli.command()
# @click.argument("commit")
# @click.option('--gpg-sign', type=str)
# @click.option('--ssh-key-path', type=str)
# def approve(commit, gpg_sign, ssh_key_path):
# approve_cmd(commit, gpg_sign, ssh_key_path)

# @cli.command(name="add-detached-signatures")
# @click.argument("commit-msg-file", type=str)
# def add_detached_signatures(commit_msg_file):
# add_detached_signatures_cmd(commit_msg_file)



Expand Down
59 changes: 59 additions & 0 deletions gitbark/_cli/util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from collections import OrderedDict
from collections.abc import MutableMapping

import functools
import click
import sys

class BarkContextObject(MutableMapping):
def __init__(self):
self._objects = OrderedDict()

def __getitem__(self, key):
return self._objects[key]

def __setitem__(self, key, value):
self._objects[key] = value

def __delitem__(self, key):
del self._objects[key]

def __len__(self):
return len(self._objects)

def __iter__(self):
return iter(self._objects)


def click_prompt(prompt, err=True, **kwargs):
"""Replacement for click.prompt to better work when piping input to the command.
Note that we change the default of err to be True, since that's how we typically
use it.
"""
# logger.debug(f"Input requested ({prompt})")
if not sys.stdin.isatty(): # Piped from stdin, see if there is data
# logger.debug("TTY detected, reading line from stdin...")
line = sys.stdin.readline()
if line:
return line.rstrip("\n")
# logger.debug("No data available on stdin")

# No piped data, use standard prompt
# logger.debug("Using interactive prompt...")
return click.prompt(prompt, err=err, **kwargs)

def click_callback(invoke_on_missing=False):
def wrap(f):
@functools.wraps(f)
def inner(ctx, param, val):
if not invoke_on_missing and not param.required and val is None:
return None
try:
return f(ctx, param, val)
except ValueError as e:
ctx.fail(f'Invalid value for "{param.name}": {str(e)}')

return inner

return wrap
6 changes: 3 additions & 3 deletions gitbark/bark_core/signatures/commands/approve_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ def approve_cmd(commit_hash, gpg_key_id="", ssh_key_path=""):
commit_hash = git.repo.revparse_single(commit_hash).id.__str__()
commit = Commit(commit_hash)
commit_obj = commit.get_commit_object()
approve = input(f"Are you sure you want to approve commit {commit_hash} (yes/no)? ")
# approve = input(f"Are you sure you want to approve commit {commit_hash} (yes/no)? ")

key_type = KeyType.GPG if gpg_key_id else KeyType.SSH

if approve == "yes":
if True:
signature = ""
ref_name = ""
if key_type == KeyType.GPG:
Expand All @@ -53,7 +53,7 @@ def approve_cmd(commit_hash, gpg_key_id="", ssh_key_path=""):

blob_hash = create_signature_blob(signature)
git.update_ref(ref_name, blob_hash)
git.push_ref(f'{ref_name}:{ref_name}')
# git.push_ref(f'{ref_name}:{ref_name}')
else:
print("Aborting approval")
return
Expand Down
10 changes: 5 additions & 5 deletions gitbark/bark_core/signatures/require_approval.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ class Rule(Rule):
def validate(self, commit: Commit, validator: Commit = None, cache: Cache = None) -> bool:
allowed_keys = self.args["allowed_keys"]
threshold = self.args["threshold"]
passes_rule, violation = require_approval(commit, validator, allowed_keys, threshold, cache)
allowed_pubkeys = self.commit.get_trusted_public_keys(allowed_keys)
passes_rule, violation = require_approval(commit, validator, threshold, allowed_pubkeys, cache)
self.add_violation(violation)
return passes_rule


def require_approval(commit: Commit, validator: Commit, allowed_keys, threshold, cache:Cache):
def require_approval(commit: Commit, validator: Commit, threshold, allowed_pubkeys, cache:Cache):
"""
Verifies that the parent from the merged branch contains a threshold of approvals. These approvals are detached signatures
included in the merge commit message.
Expand All @@ -41,16 +42,15 @@ def require_approval(commit: Commit, validator: Commit, allowed_keys, threshold,
if len(parents) <= 1:
# Require approval can only be applied on pull requests
violation = f"Commit does not originate from a pull request"
return False, violation
return True, violation

require_approval = parents[1:]
violation = ""


detached_signatures = get_detached_signatures(commit)

pubkey_blobs = validator.get_trusted_public_keys(allowed_keys)
pgpy_pubkeys = generate_pgpy_pubkeys(pubkey_blobs)
pgpy_pubkeys = generate_pgpy_pubkeys(allowed_pubkeys)

## Need to check that each invalid parent has been signed by threshold of developers and that the signature is included in the commit

Expand Down
40 changes: 19 additions & 21 deletions gitbark/bark_core/signatures/require_signature.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@
class Rule(Rule):
def validate(self, commit: Commit, validator: Commit = None, cache:Cache=None) -> bool:
allowed_keys = self.args["allowed_keys"]
passes_rule, violation = require_signature(commit, validator, allowed_keys)
pubkey_blobs = self.commit.get_trusted_public_keys(allowed_keys)
passes_rule, violation = require_signature(commit, pubkey_blobs)
self.add_violation(violation)
return passes_rule

def require_signature(commit:Commit, validator:Commit, allowed_keys):
def require_signature(commit:Commit, allowed_pubkeys):
signature_blob, commit_object = commit.get_signature()
violation = ""

Expand All @@ -40,24 +41,21 @@ def require_signature(commit:Commit, validator:Commit, allowed_keys):
violation = f"Commit was not signed"
return False, violation

pubkey_blobs = validator.get_trusted_public_keys(allowed_keys)
if len(pubkey_blobs) == 0:
if len(allowed_pubkeys) == 0:
# No pubkeys specified
violation = "No public keys registered"
return False, violation

if validate_signature(pubkey_blobs, signature_blob, commit_object):
if validate_signature(allowed_pubkeys, signature_blob, commit_object):
return True,None
else:
violation = "Commit was signed by untrusted key"
return False, violation

def validate_signature(allowed_pubkeys, signature, commit_object):
if is_pgp_signature(signature):
for pubkey in allowed_pubkeys:
if validate_gpg_signature(pubkey, signature, commit_object):
return True
return False
return validate_gpg_signature(allowed_pubkeys, signature, commit_object)

if is_ssh_signature(signature):
return validate_ssh_signature(allowed_pubkeys, signature, commit_object)
return False
Expand All @@ -75,18 +73,18 @@ def is_ssh_signature(signature):
return False


def validate_gpg_signature(pubkey, signature, commit_object):
pgpy_signature = pgpy.PGPSignature().from_blob(signature)
pgpy_pubkey = pgpy.PGPKey()
pgpy_pubkey.parse(pubkey)
try:
valid = pgpy_pubkey.verify(commit_object, pgpy_signature)
if valid:
return True
else:
return False
except:
return False
def validate_gpg_signature(allowed_pubkeys, signature, commit_object):
for pubkey in allowed_pubkeys:
pgpy_signature = pgpy.PGPSignature().from_blob(signature)
pgpy_pubkey = pgpy.PGPKey()
pgpy_pubkey.parse(pubkey)
try:
valid = pgpy_pubkey.verify(commit_object, pgpy_signature)
if valid:
return True
except:
pass
return False

def validate_ssh_signature(pubkeys, signature, commit_object):
signer_identities = []
Expand Down
Loading

0 comments on commit 2279a4d

Please sign in to comment.