Skip to content

Commit eeab9d2

Browse files
committed
add code
1 parent 1c6a66d commit eeab9d2

File tree

10 files changed

+727
-1
lines changed

10 files changed

+727
-1
lines changed

.gitignore

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
# IDE
12
.vscode
3+
4+
# misc
25
.DS_Store
6+
7+
# test
38
.coverage
9+
10+
# python
11+
*.pyc
12+
*.egg-info
13+
__pycache__
14+
15+
# poetry
16+
dist

README.md

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,67 @@
1-
# AWS coco
1+
# AWS coco (console container)
22

33
This tool allows you to manage AWS Console Sessions with Firefox Containers
44

5+
## Quickstart
6+
7+
Ensure you've met the [requirements](#requirements).
8+
9+
```bash
10+
$ pip install aws_coco
11+
```
12+
13+
Usage
14+
15+
```bash
16+
$ coco -c green -i fingerprint
17+
```
18+
19+
You should now have a new browser tab with your aws session!
20+
21+
Continue reading for a more in-depth walkthrough of the setup.
22+
523
## Requirements
624

725
- [Firefox](https://www.mozilla.org/en-US/firefox/new/)
26+
- [Firefox Multi-Account Containers](https://addons.mozilla.org/en-US/firefox/addon/multi-account-containers/)
827
- [Open URL in Container Extension](https://addons.mozilla.org/en-US/firefox/addon/open-url-in-container/)
928
- [Python >= 3.7](http://python.org/)
1029

1130
If you don't wish to install the extension through the marketplace, the source for the extension can be found [here](https://github.com/honsiorovskyi/open-url-in-container).
31+
32+
## Installation
33+
34+
```bash
35+
$ pip install aws_coco
36+
```
37+
38+
## Usage
39+
40+
```bash
41+
$ coco
42+
```
43+
44+
## Development
45+
46+
```bash
47+
$ git clone https://github.com/wulfmann/aws-coco.git
48+
$ git clone git@github.com:wulfmann/aws-coco.git
49+
```
50+
51+
Install Dependencies
52+
53+
```bash
54+
$ poetry install
55+
```
56+
57+
Run the command
58+
59+
```bash
60+
$ poetry run coco -c green -i fingerprint
61+
```
62+
63+
Run tests
64+
65+
```bash
66+
$ poetry run pytest
67+
```

aws_coco/__init__.py

Whitespace-only changes.

aws_coco/lib/__init__.py

Whitespace-only changes.

aws_coco/lib/aws.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import sys
2+
import json
3+
import urllib
4+
5+
import requests
6+
7+
from aws_coco.lib.utils import dict_to_querystring
8+
9+
10+
def create_signin_token(session):
11+
credentials = session.get_credentials()
12+
13+
if not credentials.token:
14+
print(
15+
f"coco does not work without a session token. make sure you are running this from within a temporary session"
16+
)
17+
sys.exit(1)
18+
19+
session_parameters = {
20+
"sessionId": credentials.access_key,
21+
"sessionKey": credentials.secret_key,
22+
"sessionToken": credentials.token,
23+
}
24+
25+
response = requests.get(
26+
"https://signin.aws.amazon.com/federation",
27+
params={"Action": "getSigninToken", "Session": json.dumps(session_parameters)},
28+
)
29+
30+
return response.json().get("SigninToken")
31+
32+
33+
def create_console_url(session, destination=None):
34+
if destination is None:
35+
destination = "https://console.aws.amazon.com/"
36+
37+
signin_token = create_signin_token(session)
38+
39+
base = "https://signin.aws.amazon.com/federation"
40+
qs = dict_to_querystring(
41+
{
42+
"Action": "login",
43+
"Issuer": "aws-coco",
44+
"Destination": urllib.parse.quote_plus(destination),
45+
"SigninToken": signin_token,
46+
}
47+
)
48+
49+
return f"{base}?{qs}"

aws_coco/lib/firefox.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import urllib
2+
3+
# https://github.com/mozilla/multi-account-containers/blob/00a1ce9dca2c4f54c9622515a7a86b56442eb9f2/src/js/popup.js#L1302
4+
colors = ["blue", "turquoise", "green", "yellow", "orange", "red", "pink", "purple"]
5+
6+
# https://github.com/mozilla/multi-account-containers/blob/00a1ce9dca2c4f54c9622515a7a86b56442eb9f2/src/js/popup.js#L1316
7+
icons = [
8+
"fingerprint",
9+
"briefcase",
10+
"dollar",
11+
"cart",
12+
"vacation",
13+
"gift",
14+
"food",
15+
"fruit",
16+
"pet",
17+
"tree",
18+
"chill",
19+
"circle",
20+
"fence",
21+
]
22+
23+
24+
def format_for_container(url, name, color, icon):
25+
return f"ext+container:name={name}&color={color}&icon={icon}&url={urllib.parse.quote_plus(url)}"

aws_coco/lib/utils.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import argparse
2+
3+
4+
class NegateAction(argparse.Action):
5+
def __call__(self, parser, ns, values, option):
6+
setattr(ns, self.dest, option[2:4] != "no")
7+
8+
9+
def dict_to_querystring(params):
10+
qs = []
11+
for key in params:
12+
qs.append(f"{key}={params[key]}")
13+
return "&".join(qs)

aws_coco/main.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import argparse
2+
import webbrowser
3+
4+
import boto3
5+
6+
from aws_coco.lib.firefox import colors
7+
from aws_coco.lib.firefox import icons
8+
from aws_coco.lib.firefox import format_for_container
9+
from aws_coco.lib.aws import create_console_url
10+
from aws_coco.lib.utils import NegateAction
11+
12+
13+
def construct_parser():
14+
parser = argparse.ArgumentParser(
15+
description="A utility for managing AWS Console Sessions"
16+
)
17+
18+
parser.add_argument("--profile", "-p", help="The AWS profile to use", default=None)
19+
20+
parser.add_argument(
21+
"--container",
22+
"--no-container",
23+
dest="container",
24+
action=NegateAction,
25+
help="Open URL in Firefox container",
26+
default=True,
27+
nargs=0,
28+
)
29+
30+
parser.add_argument(
31+
"--open",
32+
"--no-open",
33+
dest="open",
34+
action=NegateAction,
35+
help="Open URL automatically",
36+
default=True,
37+
nargs=0,
38+
)
39+
40+
parser.add_argument("--name", "-n", help="The container tab name")
41+
parser.add_argument("--color", "-c", choices=colors, help="The container tab color")
42+
parser.add_argument("--icon", "-i", choices=icons, help="The container tab icon")
43+
parser.add_argument(
44+
"--destination",
45+
"-d",
46+
choices=icons,
47+
help="The destination URL in the AWS console",
48+
default=None,
49+
)
50+
51+
return parser
52+
53+
54+
def validate_args(args):
55+
if args.container:
56+
if not args.color:
57+
raise Exception(f"--color is required if --container is passed")
58+
if not args.icon:
59+
raise Exception(f"--icon is required if --container is passed")
60+
61+
62+
def main(args):
63+
validate_args(args)
64+
65+
session = boto3.session.Session(profile_name=args.profile)
66+
url = create_console_url(session, args.destination)
67+
68+
if args.container:
69+
firefox = webbrowser.get("firefox")
70+
71+
if firefox is None:
72+
raise Exception(f"firefox is required if --container is passed")
73+
74+
container_name = args.profile
75+
if args.name:
76+
container_name = args.name
77+
78+
url = format_for_container(url, container_name, args.color, args.icon)
79+
80+
if args.open:
81+
firefox.open_new_tab(url)
82+
else:
83+
print(url)
84+
else:
85+
if args.open:
86+
webbrowser.open_new(url)
87+
else:
88+
print(url)
89+
90+
91+
def run():
92+
parser = construct_parser()
93+
args = parser.parse_args()
94+
main(args)

0 commit comments

Comments
 (0)