Skip to content

Commit

Permalink
Merge pull request #35 from robsweet/master
Browse files Browse the repository at this point in the history
Adding role filtering for use with federated AWS login
  • Loading branch information
tilfin authored Dec 25, 2017
2 parents e107fcf + 03fa105 commit f594064
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 32 deletions.
54 changes: 39 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ Click Browser button, edit your profile settings to text area in popup form and

Supports ~/.aws/config format and like ~/.aws/credentials

### Simple Configuration
The simplest configuration is for multiple **target roles** when you always intend to show the whole list. **Target roles** can be expressed with a 'role_arn' or with both 'aws_account_id' and 'role_name'. An optional 'color' parameter can also be used to specify an RGB hex value without prefix '#'.

```
[profile marketingadmin]
role_arn = arn:aws:iam::123456789012:role/marketingadmin
Expand All @@ -31,35 +34,56 @@ role_name = anotherrole
color=bbeeff
```

- Required `role_arn` or (`aws_account_id` and `role_name`)
- Optional `color` that is RGB hex value without prefix `#`
### Complex Configuration
More complex configurations involve multiple AWS accounts and/or organizations.

- A profile that has only `aws_account_id` (without a role_name) is defined as **base account**.

- **If your account is aliased, the alias will be shown in the role dropdown after 'Account:'. You MUST use that alias as the aws_account_id for the base account instead of the numerical account id or your configuration won't work as expected.**

### Multi base accounts
- A profile that has only `aws_account_id` is defined as **base account**.
- A profile that has `source_profile` is defined as **target account**.
- A **base account** is associated with **target account**s.
- A **target role** is associated with a **base account** by the **target role** specifying a 'source_profile'.

- As above, **target roles** can be expressed with a 'role_arn' or with both 'aws_account_id' and 'role_name' and can optionally pass a 'color' parameter.

```
[baseaccount1]
aws_account_id = 000000000000
[organization1]
aws_account_id = your-account-alias
[targetaccount1]
role_arn = arn:aws:iam::123456789012:role/targetaccount
source_profile = baseaccount1
[Org1-Account1-Role1]
role_arn = arn:aws:iam::123456789012:role/Role1
source_profile = organization1
[Org1-Account1-Role2]
aws_account_id = 123456789012
role_name = Role2
source_profile = organization1
[Org1-Account2-Role1]
aws_account_id = 210987654321
role_name = Role1
source_profile = organization1
[baseaccount2]
aws_account_id = your-alias-name
aws_account_id = 000000000000
[targetaccount2]
role_arn = arn:aws:iam::234567890123:role/targetaccount
[Base2-Role1]
role_arn = arn:aws:iam::234567890123:role/Role1
source_profile = baseaccount2
[AnotherRole]
role_name = SomeOtherRole
aws_account_id = account-3-alias
```

If you sign-in a base account, target accounts of the other base accounts are excluded.
If you sign-in a base account, target roles of the other base accounts are excluded.

The 'Show only matching roles' setting is for use with more sophisticated account structures where you're using AWS Organizations with multiple accounts along with AWS Federated Logins via something like Active Directory or Google GSuite. Common practice is to have a role in the master account that is allowed to assume a role of the same name in other member accounts. Checking this box means that if you're logged in to the 'Developer' role in the master account, only member accounts with a role_arn ending in 'role/Developer' will be shown. You won't see roles that your current role can't actually assume.

## Settings

- Can hide original role history (Show only roles in the configuration)
- Can hide the account_id for each profile
- Can filter to only show profiles with roles that match your role in your master account

## Appearance

Expand Down
3 changes: 2 additions & 1 deletion popup.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
resize: none;
white-space: pre;
width:470px;
height:400px;
height:350px;
}
#colorValue {
font-family: monospace;
Expand Down Expand Up @@ -63,6 +63,7 @@
<ul>
<li><label for="hidesHistoryCheckBox"><input type="checkbox" id="hidesHistoryCheckBox">Hide original role history</label></li>
<li><label for="hidesAccountIdCheckBox"><input type="checkbox" id="hidesAccountIdCheckBox">Hide account id</label></li>
<li><label for="showOnlyMatchingRolesCheckbox"><input type="checkbox" id="showOnlyMatchingRolesCheckbox">Show only matching roles</label></li>
</ul>
</section>
</body>
Expand Down
27 changes: 14 additions & 13 deletions src/content.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ function extendIAMFormList() {
csrf = '';
}

chrome.storage.sync.get(['profiles', 'hidesHistory', 'hidesAccountId'], function(data) {
chrome.storage.sync.get(['profiles', 'hidesHistory', 'hidesAccountId','showOnlyMatchingRoles'], function(data) {
var hidesHistory = data.hidesHistory || false;
var hidesAccountId = data.hidesAccountId || false;
if (data.profiles) {
loadProfiles(new Profile(data.profiles), list, csrf, hidesHistory, hidesAccountId);
var showOnlyMatchingRoles = data.showOnlyMatchingRoles || false;
if (data.profiles) {
loadProfiles(new Profile(data.profiles, showOnlyMatchingRoles), list, csrf, hidesHistory, hidesAccountId);
attachColorLine(data.profiles);
}
}
});
}

Expand Down Expand Up @@ -73,15 +74,15 @@ function loadProfiles(profile, list, csrf, hidesHistory, hidesAccountId) {
var color = item.color || 'aaaaaa';
list.insertAdjacentHTML('beforeend', Sanitizer.escapeHTML`<li>
<form action="https://signin.aws.amazon.com/switchrole" method="POST" target="_top">
<input type="hidden" name="action" value="switchFromBasis">
<input type="hidden" name="src" value="nav">
<input type="hidden" name="roleName" value="${item.role_name}">
<input type="hidden" name="account" value="${item.aws_account_id}">
<input type="hidden" name="mfaNeeded" value="0">
<input type="hidden" name="color" value="${color}">
<input type="hidden" name="csrf" value="${csrf}">
<input type="hidden" name="redirect_uri" value="https%3A%2F%2Fconsole.aws.amazon.com%2Fs3%2Fhome">
<label for="awsc-recent-role-switch-0" class="awsc-role-color" style="background-color: #${color};">&nbsp;</label>
<input type="hidden" name="action" value="switchFromBasis">
<input type="hidden" name="src" value="nav">
<input type="hidden" name="roleName" value="${item.role_name}">
<input type="hidden" name="account" value="${item.aws_account_id}">
<input type="hidden" name="mfaNeeded" value="0">
<input type="hidden" name="color" value="${color}">
<input type="hidden" name="csrf" value="${csrf}">
<input type="hidden" name="redirect_uri" value="https%3A%2F%2Fconsole.aws.amazon.com%2Fs3%2Fhome">
<label for="awsc-recent-role-switch-0" class="awsc-role-color" style="background-color: #${color};">&nbsp;</label>
<input type="submit" class="awsc-role-submit awsc-role-display-name" name="displayName" value="${name}"
title="${item.role_name}@${item.aws_account_id}" style="white-space:pre"></form>
</li>`);
Expand Down
14 changes: 12 additions & 2 deletions src/lib/profile.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function Profile(items) {
function Profile(items, showOnlyMatchingRoles) {
function getAccountId(elId) {
var el = document.getElementById(elId);
if (!el) return null;
Expand All @@ -12,7 +12,13 @@ function Profile(items) {
}
}

function getAssumedRole(elId) {
var el = document.getElementById(elId);
return ( !el ? null : el.textContent.split("/")[0] );
}

var baseAccountId = getAccountId('awsc-login-display-name-account');
var baseRole = getAssumedRole('awsc-login-display-name-user');
var srcProfileMap = {};
var destProfiles = [];
var destProfileMap = {};
Expand All @@ -36,7 +42,11 @@ function Profile(items) {
var baseProfile = srcProfileMap[baseAccountId];
if (baseProfile) {
var name = baseProfile.profile;
result = result.concat(destProfileMap[name] || []);
var profiles = destProfileMap[name] || [];
if (showOnlyMatchingRoles) {
profiles = profiles.filter(function(el) { return (el.role_name == baseRole); })
}
result = result.concat(profiles);
delete destProfileMap[name];
}
return result;
Expand Down
9 changes: 8 additions & 1 deletion src/popup.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

window.onload = function() {
var colorPicker = new ColorPicker(document);

Expand Down Expand Up @@ -50,9 +51,15 @@ window.onload = function() {
chrome.storage.sync.set({ hidesAccountId: this.checked }, function() {});
}

chrome.storage.sync.get(['rawtext', 'hidesHistory', 'hidesAccountId'], function(data) {
var showOnlyMatchingRolesCheckbox = document.querySelector('#showOnlyMatchingRolesCheckbox');
showOnlyMatchingRolesCheckbox.onchange = function() {
chrome.storage.sync.set({ showOnlyMatchingRoles: this.checked }, function() {});
}

chrome.storage.sync.get(['rawtext', 'hidesHistory', 'hidesAccountId','showOnlyMatchingRoles'], function(data) {
textArea.value = data.rawtext || localStorage['rawdata'] || '';
hidesHistoryCheckBox.checked = data.hidesHistory || false;
hidesAccountIdCheckBox.checked = data.hidesAccountId || false;
showOnlyMatchingRolesCheckbox.checked = data.showOnlyMatchingRoles || false;
});
}

0 comments on commit f594064

Please sign in to comment.