Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
Update

Update

Update

Update

Update

Update

Update

Update

Update

Update

Update

Update

Update

Update

Update

Update

Update Help, Readme Example
  • Loading branch information
Ben Goldsmith authored and Ben Goldsmith committed Oct 31, 2023
1 parent e88d803 commit 6a898b2
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 27 deletions.
29 changes: 29 additions & 0 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Python Package & Deploy to PyPI
on:
push:
branches:
- main
jobs:
deploy-to-pypi:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.10
uses: actions/setup-python@v3
with:
python-version: '3.10'
- name: Install dependencies
run: |
pip install twine
- name: Bump Version
run: |
sed -i "s/0.0.0/$(date +"%Y.%m%d.${{github.run_number}}")/g" setup.py
- name: Create Python Package
run: |
python3 setup.py sdist
- name: Upload to Twine
run: |
twine upload dist/*
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@
.vscode/
aws_google_saml.egg-info/
dist/
__pycache__/
__pycache__/
.DS_Store
aws-google-saml.rb
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ brew install python

You'll then need to configure profiles to use in your `~/.aws/config` file. An example below:

```
```conf
[profile profile-name]
region = ap-southeast-2
account = 453559030913
google_config.google_idp_id = C01g1l5do
google_config.role_name = assumed-ins-tech-lead
google_config.google_sp_id = 705835944086
account = 123456789012
google_config.google_idp_id = ABCDE1234
google_config.role_name = production-engineer
google_config.google_sp_id = 000000000000
```

Expand All @@ -34,3 +34,7 @@ Ready? Start the app with the following command
```sh
python3 google-saml-auth.py --profile profile-name
```

### Administrator Instructions

// TODO: How to setup application in Google SAML Console
55 changes: 46 additions & 9 deletions aws-google-saml/__main__.py → aws_google_saml/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import xml.etree.ElementTree as ET

import webbrowser, base64, botocore.session, boto3, configparser, os, getopt, sys
import webbrowser, base64, botocore.session, boto3, configparser, os, getopt, sys, pkgutil, datetime

boto_session = None

Expand Down Expand Up @@ -56,9 +56,12 @@ def authenticate_aws(options, saml_assertion):
.setSamlAssertion(saml_assertion)

def get_html_page_contents():
with open('authed.html') as htmlFile:
htmlContents = htmlFile.read()
return htmlContents
try:
return pkgutil.get_data(__name__, 'authed.html').decode('utf-8') # Required when packaged
except:
with open('aws_google_saml/authed.html') as htmlFile: # Used for local development
htmlContents = htmlFile.read()
return htmlContents

def HandlerWrapper(options):
class CustomHandler(BaseHTTPRequestHandler):
Expand Down Expand Up @@ -115,6 +118,8 @@ class Options:

session_name = None
session_duration = None
skip_if_already_authenticated = False

port = 35002

def setProfile(self, profile):
Expand All @@ -129,6 +134,10 @@ def setGoogleSpId(self, google_sp_id):
self.google_sp_id = google_sp_id
return self

def setSkipIfAlreadyAuthenticated(self, skip_if_already_authenticated):
self.skip_if_already_authenticated = skip_if_already_authenticated
return self

def setAwsAccountId(self, aws_account_id):
self.aws_account_id = aws_account_id
return self
Expand Down Expand Up @@ -242,17 +251,36 @@ def enrichOptionsFromAwsConfiguration(options):

return options

def isAlreadyAuthenticated(options):
credentials_parser = configparser.RawConfigParser()
credentials_parser.read(os.path.expanduser(boto_session.get_config_variable('credentials_file')))

if credentials_parser.has_section(options.profile):
if credentials_parser.has_option(options.profile, 'aws_session_expiration'):
aws_session_expiration = credentials_parser.get(options.profile, 'aws_session_expiration')
return aws_session_expiration > datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%S%z')

return False


def enrichOptionsFromArgs(cliArguments, options):
optionsList, arguments = getopt.getopt(cliArguments,"hp:",["profile=", "port="])
optionsList, arguments = getopt.getopt(cliArguments,"hp:",["help", "profile=", "port=", "skip-if-authed"])
for option, argument in optionsList:
if option == '-h':
print ('aws-google-saml.py --profile <profile_name>')
if option == '-h' or option == '--help':
print ('\nUsage: aws-google-saml.py --profile <profile_name>')
print ('\nOptions:')
print ('\t --profile <profile_name> (required)\t\t\t eg: --profile my-profile')
print ('\t --port <port_number> (optional, default 35002)\t\t eg: --port 35002')
print ('\t --skip-if-authed (optional, default false)\t\t eg: --skip-if-authed')
sys.exit()
if option == '--profile':
options.setProfile(argument)

if option == '--port':
options.setPort(argument)

if option == '--skip-if-authed':
options.setSkipIfAlreadyAuthenticated(True)

return options

Expand All @@ -267,8 +295,8 @@ def validateOptions(options):

return validationErrors

if __name__ == "__main__":

def main():
global boto_session
options = Options()
boto_session = botocore.session.Session()

Expand All @@ -284,8 +312,17 @@ def validateOptions(options):
print("Exiting due to improper usage. Use -h for help.")
sys.exit()

if options.skip_if_already_authenticated and isAlreadyAuthenticated(options):
print(f"You are already authenticated to the {options.profile} profile. Exiting early.")
sys.exit()

Thread(target=start_server, args=(options,)).start()

webbrowser.open(f"https://accounts.google.com/o/saml2/initsso?idpid={options.google_idp_id}&spid={options.google_sp_id}&forceauthn=false")

# That's it. Now we wait for the HTTP callback


if __name__ == "__main__":
main()

8 changes: 2 additions & 6 deletions authed.html → aws_google_saml/authed.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
margin-top: 100px;
position: absolute;
color: #fff;
width: 1000px;
width: 100%;
line-height: 2.5em;
}

Expand Down Expand Up @@ -120,11 +120,7 @@ <h2>You're&nbsp;Auth'ed</h2>
<h2>You're&nbsp;Auth'ed</h2>
</div>
<div id="message">
<span class="grey">into the </span>__REPLACED_PROFILE_NAME_HERE__<span
class="grey"
>
profile for the next </span
><span id="countdown">X hours XX mins XX seconds</span>
<span class="grey">into the </span>__REPLACED_PROFILE_NAME_HERE__<span class="grey"> profile for the next </span><span id="countdown">X hours XX mins XX seconds</span>
<br />
<span class="grey">you can close this window now</span>
</div>
Expand Down
33 changes: 33 additions & 0 deletions deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Deploy script to automate process of release

rm -rf dist

python3 setup.py sdist

twine upload dist/*

rm -rf venv # Just incase it wasn't cleared before

sleep 20 # need to wait for PyPi to be ready with new package

python3 -m venv venv

source venv/bin/activate

pip3 install --no-cache-dir aws-google-saml homebrew-pypi-poet

poet --formula aws-google-saml > aws-google-saml.rb

deactivate

rm -rf venv

# Replace 'virtualenv_create(libexec, "python3")' with nothing
sed -i '' 's/virtualenv_create(libexec, "python3")//g' aws-google-saml.rb

# replace 'Shiny new formula' with 'A user browser driven SAML authentication tool for AWS'
sed -i '' 's/Shiny new formula/A user browser driven SAML authentication tool for AWS/g' aws-google-saml.rb

code aws-google-saml.rb

# Copy and upload to Github
21 changes: 15 additions & 6 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,18 @@
from distutils.core import setup
setup(
name='aws-google-saml',
packages=['aws-google-saml'],
version='0.7.9',
packages=['aws_google_saml'],
version='0.0.0',
license='MIT',
description='A user-browser driven SAML authentication tool for AWS',
author='bengieeee',
url='https://github.com/bengieeee/aws-google-saml',
download_url='https://github.com/bengieeee/aws-google-saml/archive/refs/tags/0.7.1.tar.gz',
# Keywords that define your package best
keywords=['aws', 'aws-cli', 'saml', 'google', 'google-saml', 'google-saml-aws'],
install_requires=[ # I get to this in a second
'ET',
install_requires=[
'botocore',
'boto3',
'configparser',
'boto3'
],
classifiers=[
'Development Status :: 3 - Alpha',
Expand All @@ -24,4 +22,15 @@
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 3',
],
# To provide executable scripts, use entry points in preference to the
# "scripts" keyword. Entry points provide cross-platform support and allow
# pip to create the appropriate form of executable for the target platform.
entry_points={
'console_scripts': [
'aws-google-saml=aws_google_saml.__main__:main',
],
},
package_data={
'aws_google_saml': ['authed.html'],
}
)

0 comments on commit 6a898b2

Please sign in to comment.