Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
Signed-off-by: worstprgr <adam@seishin.io>
  • Loading branch information
worstprgr committed Dec 17, 2023
1 parent 3d0120c commit 1c0ad82
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 54 deletions.
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
### python_venv template
# Pycharm & venv
/.idea
/venv
/__pycache__

# Keys
*.private*
*.key*
*cred*
55 changes: 1 addition & 54 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -618,57 +618,4 @@ an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

END OF TERMS AND CONDITIONS

How to Apply These Terms to Your New Programs

If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:

<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".

You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.

The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
END OF TERMS AND CONDITIONS
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Author and E-Mail Check (AM-C)
## Description
This tool compares the Git author and e-mail address of the latest commit, against a custom white list.

If it found a match, it prints a success message to stdout.
Else, it prints an error message to stderr and terminates with an exit code 1.

This tool isn't meant for OpSec, only for an additional quality gate.

## Usage
### Basic
With the `whitelist.amc` file, you can define which authors should be verified. The syntax for an entry is:
```text
<author name> <email>
^ white space in between
```

You can also ignore single entries, by prepending '#':
```text
name lastname name@domain.com <- Not ignored
# name lastname name@domain.com <- Ignored
```

### Arguments
You can pass a custom path to the `whitelist.amc`. Just invoke the script with:
```commandline
python amc.py -p path/path/whitelist.amc
```


## CI-Integration
In GitHub, you can integrate it in your `*.yml` file with:
```yaml
- name: Author and E-Mail check
run: |
python devtools/am-c/amc.py -p whitelist.amc
```

127 changes: 127 additions & 0 deletions amc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#!/usr/bin/env python
"""
This tool compares the Git author and e-mail address of the latest commit, against a custom white list.
If it found a match, it prints a success message to stdout.
Else, it prints an error message to stderr and terminates with an exit code 1.
This tool isn't meant for OpSec, only for an additional quality gate.
Copyright (C) 2023 worstprgr <adam@seishin.io> GPG Key: key.seishin.io
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import pathlib
import subprocess
import sys
import argparse


class GitLog:
def __init__(self):
self.author_email: str = str

# Checking only the latest commit
self.git_command: list = ['git', 'log', '-1', '--pretty=format:%an %ae']

def get_author_email(self) -> None:
try:
git_response: str = subprocess.check_output(self.git_command, stderr=subprocess.STDOUT, text=True)
except subprocess.CalledProcessError:
print('[ERROR]: No Git installed or no Git repository available')
sys.exit(1)

self.author_email: str = git_response.strip().lower()


class FetchWhitelist:
def __init__(self, wl_path: pathlib.Path):
self.whitelist_file: pathlib.Path = wl_path
self.author_email: list = []
self.ignore_symbol: str = '#'

def open_parse_whitelist(self) -> None:
try:
with open(self.whitelist_file, 'r', encoding='utf8') as f:
whitelist: list = f.readlines()
except FileNotFoundError:
print(f'[ERROR]: Can not find "{self.whitelist_file}"', file=sys.stderr)
sys.exit(1)

item: str

for item in whitelist:
if item.startswith('\n') or item.startswith(' ') or item.startswith(self.ignore_symbol):
continue
user_pair = item.strip().lower()
self.author_email.append(user_pair)


class FilePaths:
def __init__(self, path: str = None):
self.whitelist_file: pathlib.Path = self.conv_path('whitelist.amc')
if path: self.whitelist_file = self.conv_path(path)

@staticmethod
def conv_path(path: str) -> pathlib.Path:
if type(path) == str: return pathlib.Path(path)
return path


class ArgHandler:
def __init__(self):
# Parser
self.path_help = 'A custom path to the whitelist file.'
self.parser = argparse.ArgumentParser()
self.parser.add_argument('-p', '--path', action='store')

# Args
self.args = self.parser.parse_args()
self.custom_path = self.args.path


class Main:
def __init__(self, whitelist_path):
# Init
self.fw = FetchWhitelist(whitelist_path)
self.gl = GitLog()
self.error: bool = True

def run_check(self):
# Run actions
self.fw.open_parse_whitelist()
self.gl.get_author_email()

# Data to compare
git_log_author_email: str = self.gl.author_email
whitelist_author_email: list[str] = self.fw.author_email

# Compare author and email address
self.cmp(git_log_author_email, whitelist_author_email)

if not self.error:
print('[OK]: Author & E-Mail address is matching with whitelist')

def cmp(self, from_git: str, from_whitelist: list) -> None or Exception:
if not (from_git in from_whitelist):
print(f'[ERROR]: "{from_git}" not found in whitelist', file=sys.stderr)
sys.exit(1)
self.error = False


if __name__ == '__main__':
ap = ArgHandler()
p = FilePaths(ap.custom_path)
m = Main(p.whitelist_file)
m.run_check()
3 changes: 3 additions & 0 deletions whitelist.amc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
yourname name@email.com
somename someone@email.com
# ignoredname ignoreme@email.com

0 comments on commit 1c0ad82

Please sign in to comment.