From eca78022a212fa7b92ab893e07836adf67c46a56 Mon Sep 17 00:00:00 2001 From: Read King Date: Wed, 8 Jan 2020 11:04:48 -0600 Subject: [PATCH 1/7] Added iam-user-profile and iam-user-profile-update functions --- aliases | 2 + docs/command-reference.md | 24 ++++++++-- functions | 2 + lib/iam-functions | 93 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 117 insertions(+), 4 deletions(-) diff --git a/aliases b/aliases index d3f4e95d..ee7e87e0 100644 --- a/aliases +++ b/aliases @@ -64,6 +64,8 @@ alias hosted-zones='~/.bash-my-aws/bin/bma hosted-zones' alias iam-role-principal='~/.bash-my-aws/bin/bma iam-role-principal' alias iam-roles='~/.bash-my-aws/bin/bma iam-roles' alias iam-users='~/.bash-my-aws/bin/bma iam-users' +alias iam-user-profile='~/.bash-my-aws/bin/bma iam-user-profile' +alias iam-user-profile-update='~/.bash-my-aws/bin/bma iam-user-profile-update' alias image-deregister='~/.bash-my-aws/bin/bma image-deregister' alias images='~/.bash-my-aws/bin/bma images' alias instance-asg='~/.bash-my-aws/bin/bma instance-asg' diff --git a/docs/command-reference.md b/docs/command-reference.md index 8158f8ca..71099b5f 100644 --- a/docs/command-reference.md +++ b/docs/command-reference.md @@ -979,9 +979,27 @@ List role principal for IAM Role(s) List IAM Users $ iam-users - john.smith@example.com AROAI3QHAU3J2CDRNLQHD 2017-02-02T03:03:02Z - aws-test-user AROAJJWRGUPTRXTV52TED 2017-03-09T05:31:39Z - mary.jones@example.com AROAJFQ3WMZXESGIKW5YD 2017-03-09T05:31:39Z + john.smith@example.com AROAI3QHAU3J2CDRNLQHD 2017-02-02T03:03:02Z 2019-10-16T17:16:08Z + aws-test-user AROAJJWRGUPTRXTV52TED 2017-03-09T05:31:39Z 2019-10-16T02:12:52Z + mary.jones@example.com AROAJFQ3WMZXESGIKW5YD 2017-03-09T05:31:39Z 2019-10-16T13:51:32Z + +### iam-user-profile + +List IAM Users Profile + + USAGE: iam-user-profile user-name [user-name] + + $ iam-user-profile john.smith@example.com + john.smith@example.com 2019-10-16T17:16:08Z False + +### iam-user-profile-update + +Change password for IAM user + + USAGE: iam-user-profile-update [--password-reset-required (default) | --no-password-reset-required] --password=[|RND (default)] user-name [user-name] + + $ iam-user-profile-update --no-password-reset-required --password=RND john.smith@example.com + john.smith@example.com {LK-4q\>V9E>n`% SUCCESS ## image-commands diff --git a/functions b/functions index 7fb8738f..c95807e3 100644 --- a/functions +++ b/functions @@ -62,6 +62,8 @@ hosted-zones iam-role-principal iam-roles iam-users +iam-user-profile +iam-user-profile-update image-deregister images instance-asg diff --git a/lib/iam-functions b/lib/iam-functions index 6b14c8df..214afb94 100644 --- a/lib/iam-functions +++ b/lib/iam-functions @@ -71,7 +71,8 @@ iam-users() { --query 'Users[].[ UserName, UserId, - CreateDate + CreateDate, + PasswordLastUsed ]' \ --output text | grep -E -- "$filters" | @@ -79,3 +80,93 @@ iam-users() { column -s$'\t' -t } +iam-user-profile(){ + + # List login profile for IAM User(s) + # + # USAGE: iam-user-profile user-name [user-name] + + local user_names="$(__bma_read_inputs $@)" + [[ -z "$user_names" ]] && __bma_usage "user-name [user-name]" && return 1 + local user_name + for user_name in $user_names; do + + aws iam get-login-profile \ + --user-name "$user_name" \ + --query 'LoginProfile.[ + UserName, + CreateDate, + PasswordResetRequired + ]' \ + --output text | + LC_ALL=C sort | + column -s$'\t' -t + done +} + +iam-user-profile-update(){ + + # Change IAM User(s) password + # + # USAGE: iam-user-profile-update [--no-reset-required] --password [Pa$$w0rd | RND] user-name [user-name] + + local resetrequired="--password-reset-required" # Default require password reset + local passwd="RND" # Default to randomly generated password + + # Process options + local inputs_array=($@) + local IFS='=' # override default field separator in the scope of this function only + local regex_reset_required=^\-\-\(no\-\)*password\-reset\-required + local regex_password=^\-\-password=.* + for index in "${inputs_array[@]}" ; do + if [[ "$index" =~ $regex_reset_required ]] ; then + read reset_opt <<< "$index" # ignore anything after option + resetrequired="$reset_opt" + shift + elif [[ "$index" =~ $regex_password ]] ; then + read pass_opt pass_arg <<< "$index" # ignore anything after option + arg + passwd="${pass_arg}" + shift + fi + done + unset IFS # to prevent it from breaking things later + + # Read in usernames + local user_names="$(__bma_read_inputs $@)" + [[ -z "$user_names" ]] && __bma_usage "[--password-reset-required (default) | --no-password-reset-required] --password=[|RND (default)] user-name [user-name]" && return 1 + local user_name + + for user_name in $user_names; do + if [ "${user_name:0:1}" == "-" ]; then continue; fi + if [ "${passwd}" == "RND" ]; then + # Generate random password until it matches password policy: + # - At least one Upper Case + # - At least one Lower Case + # - At least one Digit + # - At least one Special Character + # - At least 15 characters long + until [[ ${#password} -ge 15 && "$password" == *[A-Z]* && "$password" == *[a-z]* && "$password" == *[0-9]* && "$password" == *[!@#$%^\&*\(\)_+-=\[\]\{\}\|]* ]]; do + password=`strings /dev/urandom | grep -o '[[:graph:]]' | head -n 15 | tr -d '\n'; echo` + done + else + # Otherwise use password provided on command-line + password=${passwd} + fi + + aws iam update-login-profile \ + --user-name "${user_name}" \ + --password "${password}" \ + ${resetrequired} \ + --output text + if [ $? -eq 0 ]; then + status="SUCCESS" + else + status="FAIL" + fi + echo ${user_name} ${password} ${status} | + LC_ALL=C sort | + column -s$'\t' -t + done +} + + From 8711ef7875103d8dc95d2d30ff39a10351a0b58e Mon Sep 17 00:00:00 2001 From: Read King Date: Wed, 8 Jan 2020 12:37:20 -0600 Subject: [PATCH 2/7] [iam-users] Added flag to display-password on change (default obscured) --- docs/command-reference.md | 5 ++++- lib/iam-functions | 13 ++++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/docs/command-reference.md b/docs/command-reference.md index 02d22093..5393ff8b 100644 --- a/docs/command-reference.md +++ b/docs/command-reference.md @@ -997,9 +997,12 @@ List IAM Users Profile Change password for IAM user - USAGE: iam-user-profile-update [--password-reset-required (default) | --no-password-reset-required] --password=[|RND (default)] user-name [user-name] + USAGE: iam-user-profile-update [--display-password] [--password-reset-required (default) | --no-password-reset-required] --password=[|RND (default)] user-name [user-name] $ iam-user-profile-update --no-password-reset-required --password=RND john.smith@example.com + john.smith@example.com XXXXXXXXXXXXXXX SUCCESS + + $ iam-user-profile-update --display-password --no-password-reset-required --password=RND john.smith@example.com john.smith@example.com {LK-4q\>V9E>n`% SUCCESS diff --git a/lib/iam-functions b/lib/iam-functions index 3f607660..cd5a507e 100644 --- a/lib/iam-functions +++ b/lib/iam-functions @@ -110,21 +110,27 @@ iam-user-profile-update(){ # Change IAM User(s) password # - # USAGE: iam-user-profile-update [--no-reset-required] --password [Pa$$w0rd | RND] user-name [user-name] + # USAGE: iam-user-profile-update [--display-password] [--password-reset-required (default) | --no-password-reset-required] --password=[|RND (default)] user-name [user-name] local resetrequired="--password-reset-required" # Default require password reset local passwd="RND" # Default to randomly generated password + local display_pass=FALSE # Default to obscure password display # Process options local inputs_array=($@) local IFS='=' # override default field separator in the scope of this function only local regex_reset_required=^\-\-\(no\-\)*password\-reset\-required + local regex_display=^\-\-display\-password local regex_password=^\-\-password=.* for index in "${inputs_array[@]}" ; do if [[ "$index" =~ $regex_reset_required ]] ; then read reset_opt <<< "$index" # ignore anything after option resetrequired="$reset_opt" shift + elif [[ "$index" =~ $regex_display ]] ; then + read disp_opt <<< "$index" # ignore anything after option + display_pass=TRUE + shift elif [[ "$index" =~ $regex_password ]] ; then read pass_opt pass_arg <<< "$index" # ignore anything after option + arg passwd="${pass_arg}" @@ -135,7 +141,7 @@ iam-user-profile-update(){ # Read in usernames local user_names="$(__bma_read_inputs $@)" - [[ -z "$user_names" ]] && __bma_usage "[--password-reset-required (default) | --no-password-reset-required] --password=[|RND (default)] user-name [user-name]" && return 1 + [[ -z "$user_names" ]] && __bma_usage "[--display-password] [--password-reset-required (default) | --no-password-reset-required] --password=[|RND (default)] user-name [user-name]" && return 1 local user_name for user_name in $user_names; do @@ -154,6 +160,7 @@ iam-user-profile-update(){ # Otherwise use password provided on command-line password=${passwd} fi + if [[ "${display_pass}" == "TRUE" ]]; then password_display="${password}"; else password_display=${password//[[:graph:]]/X}; fi aws iam update-login-profile \ --user-name "${user_name}" \ @@ -165,7 +172,7 @@ iam-user-profile-update(){ else status="FAIL" fi - echo ${user_name} ${password} ${status} | + echo ${user_name} ${password_display} ${status} | LC_ALL=C sort | column -s$'\t' -t done From 1cc29896b062f1b8fbb3b225e088ed8dafd46efd Mon Sep 17 00:00:00 2001 From: Read King Date: Wed, 8 Jan 2020 15:47:37 -0600 Subject: [PATCH 3/7] [iam-users] Working on getting --batch and interactive to work --- lib/iam-functions | 52 +++++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/lib/iam-functions b/lib/iam-functions index cd5a507e..0c632439 100644 --- a/lib/iam-functions +++ b/lib/iam-functions @@ -77,7 +77,7 @@ iam-users() { PasswordLastUsed ]' \ --output text | - grep -E -- "$filters" | + grep -E -- "${filters}" | LC_ALL=C sort -b -k 3 | column -s$'\t' -t } @@ -89,12 +89,12 @@ iam-user-profile(){ # USAGE: iam-user-profile user-name [user-name] local user_names="$(__bma_read_inputs $@)" - [[ -z "$user_names" ]] && __bma_usage "user-name [user-name]" && return 1 + [[ -z "${user_names}" ]] && __bma_usage "user-name [user-name]" && return 1 local user_name - for user_name in $user_names; do + for user_name in ${user_names}; do aws iam get-login-profile \ - --user-name "$user_name" \ + --user-name "${user_name}" \ --query 'LoginProfile.[ UserName, CreateDate, @@ -110,28 +110,32 @@ iam-user-profile-update(){ # Change IAM User(s) password # - # USAGE: iam-user-profile-update [--display-password] [--password-reset-required (default) | --no-password-reset-required] --password=[|RND (default)] user-name [user-name] + # USAGE: iam-user-profile-update [--batch] [--display-password] [--password-reset-required (default) | --no-password-reset-required] --password=[|RND (default)] user-name [user-name] local resetrequired="--password-reset-required" # Default require password reset local passwd="RND" # Default to randomly generated password + local batch=FALSE # Default to interactive mode local display_pass=FALSE # Default to obscure password display # Process options local inputs_array=($@) local IFS='=' # override default field separator in the scope of this function only local regex_reset_required=^\-\-\(no\-\)*password\-reset\-required + local regex_batch=^\-\-batch local regex_display=^\-\-display\-password local regex_password=^\-\-password=.* for index in "${inputs_array[@]}" ; do - if [[ "$index" =~ $regex_reset_required ]] ; then - read reset_opt <<< "$index" # ignore anything after option - resetrequired="$reset_opt" + if [[ "${index}" =~ ${regex_reset_required} ]] ; then + read reset_opt <<< "${index}" # ignore anything after option + resetrequired="${reset_opt}" + shift + elif [[ "${index}" =~ ${regex_batch} ]] ; then + batch=TRUE shift - elif [[ "$index" =~ $regex_display ]] ; then - read disp_opt <<< "$index" # ignore anything after option + elif [[ "${index}" =~ $regex_display ]] ; then display_pass=TRUE shift - elif [[ "$index" =~ $regex_password ]] ; then + elif [[ "${index}" =~ $regex_password ]] ; then read pass_opt pass_arg <<< "$index" # ignore anything after option + arg passwd="${pass_arg}" shift @@ -141,38 +145,46 @@ iam-user-profile-update(){ # Read in usernames local user_names="$(__bma_read_inputs $@)" - [[ -z "$user_names" ]] && __bma_usage "[--display-password] [--password-reset-required (default) | --no-password-reset-required] --password=[|RND (default)] user-name [user-name]" && return 1 + [[ -z "${user_names}" ]] && __bma_usage "[--batch] [--display-password] [--password-reset-required (default) | --no-password-reset-required] --password=[|RND (default)] user-name [user-name]" && return 1 local user_name - for user_name in $user_names; do + for user_name in ${user_names}; do if [ "${user_name:0:1}" == "-" ]; then continue; fi - if [ "${passwd}" == "RND" ]; then + if [[ "${passwd}" = "RND" ]] || [[ "${batch}" = "FALSE" ]]; then # Generate random password until it matches password policy: # - At least one Upper Case # - At least one Lower Case # - At least one Digit # - At least one Special Character # - At least 15 characters long - until [[ ${#password} -ge 15 && "$password" == *[A-Z]* && "$password" == *[a-z]* && "$password" == *[0-9]* && "$password" == *[!@#$%^\&*\(\)_+-=\[\]\{\}\|]* ]]; do - password=`strings /dev/urandom | grep -o '[[:graph:]]' | head -n 15 | tr -d '\n'; echo` + until [[ ${#password} -ge 15 && "${password}" == *[A-Z]* && "${password}" == *[a-z]* && "${password}" == *[0-9]* && "${password}" == *[!@#$%^\&*\(\)_+-=\[\]\{\}\|]* ]]; do + password=$(strings /dev/urandom | grep -o '[[:graph:]]' | head -n 15 | tr -d '\n'; echo) done else # Otherwise use password provided on command-line - password=${passwd} + password="${passwd}" fi if [[ "${display_pass}" == "TRUE" ]]; then password_display="${password}"; else password_display=${password//[[:graph:]]/X}; fi - aws iam update-login-profile \ + if [[ "${batch}" == "FALSE" ]]; then + echo "${user_name}: Suggested password: ${password}" + echo -n "${user_name}: Enter new password for user: "; read -r password1 + echo -n "${user_name}: Confirm new password for user: "; read -r password2 + echo -n "${user_name}: Require password reset on next sign-in? [Y/n]: "; read -r pass_reset + fi + + echo aws iam update-login-profile \ --user-name "${user_name}" \ --password "${password}" \ - ${resetrequired} \ + "${resetrequired}" \ --output text + if [ $? -eq 0 ]; then status="SUCCESS" else status="FAIL" fi - echo ${user_name} ${password_display} ${status} | + echo "${user_name}" "${password_display}" "${status}" | LC_ALL=C sort | column -s$'\t' -t done From 839713bf464d6de745c8308a63bbf99e44a099fe Mon Sep 17 00:00:00 2001 From: Read King Date: Wed, 8 Jan 2020 16:32:04 -0600 Subject: [PATCH 4/7] [iam-users] Completed interactive/batch in iam-user-profile-update --- docs/command-reference.md | 13 +++++++++--- lib/iam-functions | 43 +++++++++++++++++++++++++++------------ 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/docs/command-reference.md b/docs/command-reference.md index 5393ff8b..e4f3b854 100644 --- a/docs/command-reference.md +++ b/docs/command-reference.md @@ -997,14 +997,21 @@ List IAM Users Profile Change password for IAM user - USAGE: iam-user-profile-update [--display-password] [--password-reset-required (default) | --no-password-reset-required] --password=[|RND (default)] user-name [user-name] + USAGE: iam-user-profile-update [--batch] [--display-password] [--password-reset-required (default) | --no-password-reset-required] --password=[|RND (default)] user-name [user-name] - $ iam-user-profile-update --no-password-reset-required --password=RND john.smith@example.com + $ iam-user-profile-update --batch --no-password-reset-required --password=RND john.smith@example.com john.smith@example.com XXXXXXXXXXXXXXX SUCCESS - $ iam-user-profile-update --display-password --no-password-reset-required --password=RND john.smith@example.com + $ iam-user-profile-update --batch --display-password --no-password-reset-required --password=RND john.smith@example.com john.smith@example.com {LK-4q\>V9E>n`% SUCCESS + $ iam-users king | iam-user-profile-update + john.smith@example.com: Suggested password: ($p:#|q%5U!6~n% + john.smith@example.com: Enter new password for user: + john.smith@example.com: Confirm new password for user: + john.smith@example.com: Require password reset on next sign-in? [Y/n]: n + john.smith@example.com XXXXXXXXXXXXXXX SUCCESS + ## image-commands diff --git a/lib/iam-functions b/lib/iam-functions index 0c632439..106390d1 100644 --- a/lib/iam-functions +++ b/lib/iam-functions @@ -18,7 +18,8 @@ iam-roles() { # AWSBatchServiceRole AROAJJWRGUPTRXTV52TED 2017-03-09T05:31:39Z # ecsInstanceRole AROAJFQ3WMZXESGIKW5YD 2017-03-09T05:31:39Z - local filters=$(__bma_read_filters $@) + local filters + filters=$(__bma_read_filters "$@") aws iam list-roles \ --output text \ @@ -40,7 +41,8 @@ iam-role-principal(){ # # USAGE: iam-role-principal role-name [role-name] - local role_names="$(__bma_read_inputs $@)" + local role_names + role_names=$(__bma_read_inputs "$@") [[ -z "$role_names" ]] && __bma_usage "role-name [role-name]" && return 1 aws iam list-roles \ @@ -67,7 +69,8 @@ iam-users() { # AWSBatchServiceRole AROAJJWRGUPTRXTV52TED 2017-03-09T05:31:39Z # ecsInstanceRole AROAJFQ3WMZXESGIKW5YD 2017-03-09T05:31:39Z - local filters=$(__bma_read_filters $@) + local filters + filters=$(__bma_read_filters "$@") aws iam list-users \ --query 'Users[].[ @@ -88,7 +91,8 @@ iam-user-profile(){ # # USAGE: iam-user-profile user-name [user-name] - local user_names="$(__bma_read_inputs $@)" + local user_names + user_names=$(__bma_read_inputs "$@") [[ -z "${user_names}" ]] && __bma_usage "user-name [user-name]" && return 1 local user_name for user_name in ${user_names}; do @@ -126,7 +130,7 @@ iam-user-profile-update(){ local regex_password=^\-\-password=.* for index in "${inputs_array[@]}" ; do if [[ "${index}" =~ ${regex_reset_required} ]] ; then - read reset_opt <<< "${index}" # ignore anything after option + read -r reset_opt <<< "${index}" # ignore anything after option resetrequired="${reset_opt}" shift elif [[ "${index}" =~ ${regex_batch} ]] ; then @@ -136,7 +140,7 @@ iam-user-profile-update(){ display_pass=TRUE shift elif [[ "${index}" =~ $regex_password ]] ; then - read pass_opt pass_arg <<< "$index" # ignore anything after option + arg + read -r pass_opt pass_arg <<< "$index" # ignore anything after option + arg passwd="${pass_arg}" shift fi @@ -144,7 +148,8 @@ iam-user-profile-update(){ unset IFS # to prevent it from breaking things later # Read in usernames - local user_names="$(__bma_read_inputs $@)" + local user_names + user_names=$(__bma_read_inputs "$@") [[ -z "${user_names}" ]] && __bma_usage "[--batch] [--display-password] [--password-reset-required (default) | --no-password-reset-required] --password=[|RND (default)] user-name [user-name]" && return 1 local user_name @@ -164,18 +169,30 @@ iam-user-profile-update(){ # Otherwise use password provided on command-line password="${passwd}" fi - if [[ "${display_pass}" == "TRUE" ]]; then password_display="${password}"; else password_display=${password//[[:graph:]]/X}; fi if [[ "${batch}" == "FALSE" ]]; then echo "${user_name}: Suggested password: ${password}" - echo -n "${user_name}: Enter new password for user: "; read -r password1 - echo -n "${user_name}: Confirm new password for user: "; read -r password2 - echo -n "${user_name}: Require password reset on next sign-in? [Y/n]: "; read -r pass_reset + password1="x"; password2="y" + until [[ "${password1}" == "${password2}" ]]; do + read -srp "${user_name}: Enter new password for user: " password1 <&1; echo "" + read -srp "${user_name}: Confirm new password for user: " password2 <&1; echo "" + if [[ "${password1}" != "${password2}" ]]; then echo "Passwords do not match..."; fi + done + read -n1 -rp "${user_name}: Require password reset on next sign-in? [Y/n]: " pass_reset <&1; echo "" + password="${password1}" + pass_reset=${pass_reset,,} # tolower + if [[ "$pass_reset" =~ ^(n)$ ]]; then + resetrequired="--no-password-reset-required" + else + resetrequired="--password-reset-required" + fi fi - echo aws iam update-login-profile \ + if [[ "${display_pass}" == "TRUE" ]]; then password_display="${password}"; else password_display=${password//[[:graph:]]/X}; fi + + aws iam update-login-profile \ --user-name "${user_name}" \ - --password "${password}" \ + --password """${password}""" \ "${resetrequired}" \ --output text From 6ae24ba6de829dd42b8bc792569f345a7c24a70f Mon Sep 17 00:00:00 2001 From: Read King Date: Mon, 13 Jan 2020 12:57:57 -0600 Subject: [PATCH 5/7] [iam-users] Reverted changes based on shellcheck recommendations --- lib/iam-functions | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/lib/iam-functions b/lib/iam-functions index 106390d1..cad6c680 100644 --- a/lib/iam-functions +++ b/lib/iam-functions @@ -18,8 +18,7 @@ iam-roles() { # AWSBatchServiceRole AROAJJWRGUPTRXTV52TED 2017-03-09T05:31:39Z # ecsInstanceRole AROAJFQ3WMZXESGIKW5YD 2017-03-09T05:31:39Z - local filters - filters=$(__bma_read_filters "$@") + local filters=$(__bma_read_filters "$@") aws iam list-roles \ --output text \ @@ -41,8 +40,7 @@ iam-role-principal(){ # # USAGE: iam-role-principal role-name [role-name] - local role_names - role_names=$(__bma_read_inputs "$@") + local role_names=$(__bma_read_inputs "$@") [[ -z "$role_names" ]] && __bma_usage "role-name [role-name]" && return 1 aws iam list-roles \ @@ -69,17 +67,16 @@ iam-users() { # AWSBatchServiceRole AROAJJWRGUPTRXTV52TED 2017-03-09T05:31:39Z # ecsInstanceRole AROAJFQ3WMZXESGIKW5YD 2017-03-09T05:31:39Z - local filters - filters=$(__bma_read_filters "$@") + local filters=$(__bma_read_filters "$@") aws iam list-users \ + --output text \ --query 'Users[].[ UserName, UserId, CreateDate, PasswordLastUsed - ]' \ - --output text | + ]' | grep -E -- "${filters}" | LC_ALL=C sort -b -k 3 | column -s$'\t' -t From a54e3f097460e0f9b7c1bb6e5ea313693b00a8f8 Mon Sep 17 00:00:00 2001 From: Read King Date: Mon, 13 Jan 2020 13:02:25 -0600 Subject: [PATCH 6/7] [iam-users] More code tweaks based on shellcheck recommendations --- lib/iam-functions | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/iam-functions b/lib/iam-functions index cad6c680..db8d7b39 100644 --- a/lib/iam-functions +++ b/lib/iam-functions @@ -18,7 +18,7 @@ iam-roles() { # AWSBatchServiceRole AROAJJWRGUPTRXTV52TED 2017-03-09T05:31:39Z # ecsInstanceRole AROAJFQ3WMZXESGIKW5YD 2017-03-09T05:31:39Z - local filters=$(__bma_read_filters "$@") + local filters=$(__bma_read_filters $@) aws iam list-roles \ --output text \ @@ -40,7 +40,7 @@ iam-role-principal(){ # # USAGE: iam-role-principal role-name [role-name] - local role_names=$(__bma_read_inputs "$@") + local role_names="$(__bma_read_inputs $@)" [[ -z "$role_names" ]] && __bma_usage "role-name [role-name]" && return 1 aws iam list-roles \ @@ -67,7 +67,7 @@ iam-users() { # AWSBatchServiceRole AROAJJWRGUPTRXTV52TED 2017-03-09T05:31:39Z # ecsInstanceRole AROAJFQ3WMZXESGIKW5YD 2017-03-09T05:31:39Z - local filters=$(__bma_read_filters "$@") + local filters=$(__bma_read_filters $@) aws iam list-users \ --output text \ From 871e0daac826e0178f681e11aba77991b3ae5749 Mon Sep 17 00:00:00 2001 From: Read King Date: Mon, 13 Jan 2020 17:12:31 -0600 Subject: [PATCH 7/7] [iam-users] More fixes to bring in line with upstream skim-input --- lib/iam-functions | 49 ++++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/lib/iam-functions b/lib/iam-functions index 5200bf78..857da58e 100644 --- a/lib/iam-functions +++ b/lib/iam-functions @@ -68,16 +68,18 @@ iam-users() { # AWSBatchServiceRole AROAJJWRGUPTRXTV52TED 2017-03-09T05:31:39Z # ecsInstanceRole AROAJFQ3WMZXESGIKW5YD 2017-03-09T05:31:39Z + local user_names=$(skim-stdin) local filters=$(__bma_read_filters $@) aws iam list-users \ --output text \ - --query 'Users[].[ + --query " + Users[${user_names:+?contains(['${user_names// /"','"}'], UserName)}].[ UserName, UserId, CreateDate, PasswordLastUsed - ]' | + ]" | grep -E -- "${filters}" | LC_ALL=C sort -b -k 3 | column -s$'\t' -t @@ -89,20 +91,21 @@ iam-user-profile(){ # # USAGE: iam-user-profile user-name [user-name] - local user_names - user_names=$(__bma_read_inputs "$@") + local user_names="$@ $(skim-stdin)" [[ -z "${user_names}" ]] && __bma_usage "user-name [user-name]" && return 1 + local user_name for user_name in ${user_names}; do aws iam get-login-profile \ + --output text \ --user-name "${user_name}" \ - --query 'LoginProfile.[ - UserName, - CreateDate, - PasswordResetRequired - ]' \ - --output text | + --query " + LoginProfile.[ + UserName, + CreateDate, + PasswordResetRequired + ]" | LC_ALL=C sort | column -s$'\t' -t done @@ -122,10 +125,12 @@ iam-user-profile-update(){ # Process options local inputs_array=($@) local IFS='=' # override default field separator in the scope of this function only + # regex for searching options local regex_reset_required=^\-\-\(no\-\)*password\-reset\-required local regex_batch=^\-\-batch local regex_display=^\-\-display\-password local regex_password=^\-\-password=.* + for index in "${inputs_array[@]}" ; do if [[ "${index}" =~ ${regex_reset_required} ]] ; then read -r reset_opt <<< "${index}" # ignore anything after option @@ -146,11 +151,10 @@ iam-user-profile-update(){ unset IFS # to prevent it from breaking things later # Read in usernames - local user_names - user_names=$(__bma_read_inputs "$@") + local user_names="$@ $(skim-stdin)" [[ -z "${user_names}" ]] && __bma_usage "[--batch] [--display-password] [--password-reset-required (default) | --no-password-reset-required] --password=[|RND (default)] user-name [user-name]" && return 1 - local user_name + local user_name for user_name in ${user_names}; do if [ "${user_name:0:1}" == "-" ]; then continue; fi if [[ "${passwd}" = "RND" ]] || [[ "${batch}" = "FALSE" ]]; then @@ -179,6 +183,8 @@ iam-user-profile-update(){ read -n1 -rp "${user_name}: Require password reset on next sign-in? [Y/n]: " pass_reset <&1; echo "" password="${password1}" pass_reset=${pass_reset,,} # tolower + + # Set password reset required flag as needed if [[ "$pass_reset" =~ ^(n)$ ]]; then resetrequired="--no-password-reset-required" else @@ -186,19 +192,26 @@ iam-user-profile-update(){ fi fi - if [[ "${display_pass}" == "TRUE" ]]; then password_display="${password}"; else password_display=${password//[[:graph:]]/X}; fi + # Conceal password display dy default, reveal if desired + if [[ "${display_pass}" == "TRUE" ]]; then + password_display="${password}" + else + password_display=${password//[[:graph:]]/X} + fi + # Execute the password change aws iam update-login-profile \ + --output text \ --user-name "${user_name}" \ --password """${password}""" \ - "${resetrequired}" \ - --output text + "${resetrequired}" if [ $? -eq 0 ]; then - status="SUCCESS" + status='SUCCESS' else - status="FAIL" + status='FAIL' fi + echo "${user_name}" "${password_display}" "${status}" | LC_ALL=C sort | column -s$'\t' -t