diff --git a/tests/commands/get_object.sh b/tests/commands/get_object.sh index 9eb12ce..c0427b9 100644 --- a/tests/commands/get_object.sh +++ b/tests/commands/get_object.sh @@ -73,6 +73,8 @@ get_object_with_user() { elif [[ $1 == "mc" ]]; then log 5 "save location: $4" get_object_error=$(send_command mc --insecure get "$MC_ALIAS/$2/$3" "$4" 2>&1) || exit_code=$? + elif [[ $1 == "rest" ]]; then + get_object_rest_with_user "$5" "$6" "$2" "$3" "$4" || exit_code=$? else log 2 "'get_object_with_user' not implemented for client '$1'" return 1 @@ -91,37 +93,24 @@ get_object_rest() { log 2 "'get_object_rest' requires bucket name, object name, output file" return 1 fi - - generate_hash_for_payload "" - - current_date_time=$(date -u +"%Y%m%dT%H%M%SZ") - aws_endpoint_url_address=${AWS_ENDPOINT_URL#*//} - header=$(echo "$AWS_ENDPOINT_URL" | awk -F: '{print $1}') - # shellcheck disable=SC2154 - canonical_request="GET -/$1/$2 - -host:$aws_endpoint_url_address -x-amz-content-sha256:UNSIGNED-PAYLOAD -x-amz-date:$current_date_time - -host;x-amz-content-sha256;x-amz-date -UNSIGNED-PAYLOAD" - - if ! generate_sts_string "$current_date_time" "$canonical_request"; then - log 2 "error generating sts string" - return 1 - fi - get_signature - # shellcheck disable=SC2154 - reply=$(send_command curl -w "%{http_code}" -ks "$header://$aws_endpoint_url_address/$1/$2" \ - -H "Authorization: AWS4-HMAC-SHA256 Credential=$AWS_ACCESS_KEY_ID/$ymd/$AWS_REGION/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=$signature" \ - -H "x-amz-content-sha256: UNSIGNED-PAYLOAD" \ - -H "x-amz-date: $current_date_time" \ - -o "$3" 2>&1) - log 5 "reply: $reply" - if [[ "$reply" != "200" ]]; then - log 2 "get object command returned error: $(cat "$3")" + if ! get_object_rest_with_user "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY" "$1" "$2" "$3"; then + log 2 "error getting REST object with root user" + return 1 + fi + return 0 +} + +get_object_rest_with_user() { + if [ $# -ne 5 ]; then + log 2 "'get_object_rest_with_user' requires username, password, bucket name, object name, output file" + return 1 + fi + if ! result=$(AWS_ACCESS_KEY_ID="$1" AWS_SECRET_ACCESS_KEY="$2" COMMAND_LOG="$COMMAND_LOG" BUCKET_NAME="$3" OBJECT_KEY="$4" OUTPUT_FILE="$5" ./tests/rest_scripts/get_object.sh 2>&1); then + log 2 "error getting object: $result" + return 1 + fi + if [ "$result" != "200" ]; then + log 2 "expected '200', was '$result' ($(cat "$3"))" return 1 fi return 0 diff --git a/tests/commands/put_object.sh b/tests/commands/put_object.sh index 4c939d6..82bc1c4 100644 --- a/tests/commands/put_object.sh +++ b/tests/commands/put_object.sh @@ -74,12 +74,69 @@ put_object_rest() { log 2 "'put_object_rest' requires local file, bucket name, key" return 1 fi - if ! result=$(COMMAND_LOG="$COMMAND_LOG" DATA_FILE="$1" BUCKET_NAME="$2" OBJECT_KEY="$3" OUTPUT_FILE="$TEST_FILE_FOLDER/result.txt" ./tests/rest_scripts/put_object.sh); then - log 2 "error sending object file: $result" - return 1 - fi - if [ "$result" != "200" ]; then - log 2 "expected response code of '200', was '$result' (output: $(cat "$TEST_FILE_FOLDER/result.txt")" + if ! put_object_rest_with_user "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY" "$1" "$2" "$3"; then + log 2 "error putting object with REST with root user" + return 1 + fi + return 0 +} + +put_object_rest_with_user() { + if [ $# -ne 5 ]; then + log 2 "'put_object_rest_with_user' requires username, password, local file, bucket name, key" + return 1 + fi + if ! put_object_rest_with_user_and_code "$1" "$2" "$3" "$4" "$5" "200"; then + log 2 "error putting object with user '$1'" + return 1 + fi + return 0 +} + +put_object_rest_with_user_and_code() { + if [ $# -ne 6 ]; then + log 2 "'put_object_rest_with_user' requires username, password, local file, bucket name, key, expected response code" + return 1 + fi + if ! result=$(AWS_ACCESS_KEY_ID="$1" AWS_SECRET_ACCESS_KEY="$2" COMMAND_LOG="$COMMAND_LOG" DATA_FILE="$3" BUCKET_NAME="$4" OBJECT_KEY="$5" OUTPUT_FILE="$TEST_FILE_FOLDER/result.txt" ./tests/rest_scripts/put_object.sh); then + log 2 "error sending object file: $result" + return 1 + fi + if [ "$result" != "$6" ]; then + log 2 "expected response code of '$6', was '$result' (output: $(cat "$TEST_FILE_FOLDER/result.txt")" + return 1 + fi + return 0 +} + +put_object_rest_with_user_code_error() { + if [ $# -ne 7 ]; then + log 2 "'put_object_rest_with_user_code_error' requires username, password, lcoal file, bucket name, key, expected code, expected error" + return 1 + fi + if ! result=$(AWS_ACCESS_KEY_ID="$1" AWS_SECRET_ACCESS_KEY="$2" COMMAND_LOG="$COMMAND_LOG" DATA_FILE="$3" BUCKET_NAME="$4" OBJECT_KEY="$5" OUTPUT_FILE="$TEST_FILE_FOLDER/result.txt" ./tests/rest_scripts/put_object.sh); then + log 2 "error sending object file: $result" + return 1 + fi + if [ "$result" != "$6" ]; then + log 2 "expected response code of '$6', was '$result' (output: $(cat "$TEST_FILE_FOLDER/result.txt")" + return 1 + fi + if ! check_xml_element "$TEST_FILE_FOLDER/result.txt" "$7" "Error" "Code"; then + log 2 "error checking for error code '$7'" + return 1 + fi + return 0 +} + +put_object_rest_user_bad_signature() { + if [ $# -ne 5 ]; then + log 2 "'put_object_rest_user_bad_signature' requires username, password, local file, bucket name, key" + return 1 + fi + export SIGNATURE="abcdefg" + if ! put_object_rest_with_user_code_error "$1" "$2" "$3" "$4" "$5" "403" "SignatureDoesNotMatch"; then + log 2 "error checking REST user bad signature error" return 1 fi return 0 diff --git a/tests/logger.sh b/tests/logger.sh index 46be296..da50f34 100644 --- a/tests/logger.sh +++ b/tests/logger.sh @@ -146,7 +146,7 @@ log_message() { echo "$now $1 $2" >&2 fi if [[ -n "$TEST_LOG_FILE" ]]; then - echo "$now $1 $2" >> "$TEST_LOG_FILE.tmp" + echo "$now ${BASH_SOURCE[2]}:${BASH_LINENO[1]} $1 $2" >> "$TEST_LOG_FILE.tmp" fi sync } diff --git a/tests/rest_scripts/put_object.sh b/tests/rest_scripts/put_object.sh index 9a6473f..27e1c95 100755 --- a/tests/rest_scripts/put_object.sh +++ b/tests/rest_scripts/put_object.sh @@ -34,6 +34,8 @@ expires="$EXPIRES" # use this parameter to check incorrect checksums # shellcheck disable=SC2153,SC2154 checksum_hash="$CHECKSUM" +# shellcheck disable=SC2153,SC2154 +fake_signature="$SIGNATURE" current_date_time=$(date -u +"%Y%m%dT%H%M%SZ") if [ "$payload" == "" ]; then @@ -83,6 +85,10 @@ build_canonical_request "${cr_data[@]}" # shellcheck disable=SC2119 create_canonical_hash_sts_and_signature +if [ "$fake_signature" != "" ]; then + signature="$fake_signature" +fi + curl_command+=(curl -ks -w "\"%{http_code}\"" -X PUT "$AWS_ENDPOINT_URL/$bucket_name/$key") curl_command+=(-H "\"Authorization: AWS4-HMAC-SHA256 Credential=$aws_access_key_id/$year_month_day/$aws_region/s3/aws4_request,SignedHeaders=$param_list,Signature=$signature\"") curl_command+=("${header_fields[@]}") diff --git a/tests/test_rest.sh b/tests/test_rest.sh index 38f185f..32a0fa6 100755 --- a/tests/test_rest.sh +++ b/tests/test_rest.sh @@ -59,7 +59,7 @@ test_file="test_file" run setup_bucket_and_file "$BUCKET_ONE_NAME" "$test_file" assert_success - run put_object "s3api" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" assert_success run list_check_objects_rest "$BUCKET_ONE_NAME" @@ -168,7 +168,7 @@ test_file="test_file" run setup_bucket_and_file "$BUCKET_ONE_NAME" "$test_file" assert_success - run put_object "s3api" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" assert_success run check_legal_hold_without_lock_enabled "$BUCKET_ONE_NAME" "$test_file" @@ -194,7 +194,7 @@ test_file="test_file" "$TEST_FILE_FOLDER/$test_file-0" "$TEST_FILE_FOLDER/$test_file-1" "$TEST_FILE_FOLDER/$test_file-2" "$TEST_FILE_FOLDER/$test_file-3" assert_success - run get_object "s3api" "$BUCKET_ONE_NAME" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy" + run get_object "rest" "$BUCKET_ONE_NAME" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy" assert_success run compare_files "$TEST_FILE_FOLDER/$test_file" "$TEST_FILE_FOLDER/$test_file-copy" @@ -225,7 +225,7 @@ test_file="test_file" run setup_bucket_and_file "$BUCKET_ONE_NAME" "$test_file" assert_success - run put_object "s3api" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" assert_success run check_attributes_invalid_param "$test_file" @@ -315,13 +315,13 @@ test_file="test_file" run setup_bucket_and_files "s3api" "$BUCKET_ONE_NAME" "$test_file" "$test_file_two" "$test_file_three" assert_success - run put_object "s3api" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" assert_success - run put_object "s3api" "$TEST_FILE_FOLDER/$test_file_two" "$BUCKET_ONE_NAME" "$test_file_two" + run put_object "rest" "$TEST_FILE_FOLDER/$test_file_two" "$BUCKET_ONE_NAME" "$test_file_two" assert_success - run put_object "s3api" "$TEST_FILE_FOLDER/$test_file_three" "$BUCKET_ONE_NAME" "$test_file_three" + run put_object "rest" "$TEST_FILE_FOLDER/$test_file_three" "$BUCKET_ONE_NAME" "$test_file_three" assert_success run list_objects_check_params_get_token "$BUCKET_ONE_NAME" "$test_file" "$test_file_two" "TRUE" @@ -341,10 +341,10 @@ test_file="test_file" run setup_bucket "s3api" "$BUCKET_ONE_NAME" "$test_file" "$test_file_two" assert_success - run put_object "s3api" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" assert_success - run put_object "s3api" "$TEST_FILE_FOLDER/$test_file_two" "$BUCKET_ONE_NAME" "$test_file_two" + run put_object "rest" "$TEST_FILE_FOLDER/$test_file_two" "$BUCKET_ONE_NAME" "$test_file_two" assert_success run list_objects_v1_check_nextmarker_empty "$BUCKET_ONE_NAME" @@ -369,7 +369,7 @@ test_file="test_file" run create_upload_part_copy_rest "$BUCKET_ONE_NAME" "$test_file" "$TEST_FILE_FOLDER/$test_file" assert_success - run download_and_compare_file "s3api" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy" + run download_and_compare_file "rest" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy" assert_success } @@ -380,7 +380,7 @@ test_file="test_file" run setup_bucket_and_file "$BUCKET_ONE_NAME" "$test_file" assert_success - run put_object "s3api" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" assert_success run get_etag_rest "$BUCKET_ONE_NAME" "$test_file" @@ -415,10 +415,10 @@ test_file="test_file" run setup_bucket_and_files "$BUCKET_ONE_NAME" "$test_file" "$test_file_two" assert_success - run put_object "s3api" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" assert_success - run put_object "s3api" "$TEST_FILE_FOLDER/$test_file_two" "$BUCKET_ONE_NAME" "$test_file_two" + run put_object "rest" "$TEST_FILE_FOLDER/$test_file_two" "$BUCKET_ONE_NAME" "$test_file_two" assert_success run verify_object_exists "$BUCKET_ONE_NAME" "$test_file" @@ -464,7 +464,7 @@ test_file="test_file" run create_test_files "$test_file" assert_success - run put_object "s3api" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" assert_success run delete_object "s3api" "$BUCKET_ONE_NAME" "$test_file" @@ -490,7 +490,7 @@ test_file="test_file" run create_test_files "$test_file" assert_success - run put_object "s3api" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" assert_success run delete_object "s3api" "$BUCKET_ONE_NAME" "$test_file" @@ -520,3 +520,34 @@ test_file="test_file" run head_bucket_rest "$BUCKET_ONE_NAME" assert_failure 1 } + +@test "REST - PutObject with user permission - admin user" { + run setup_bucket_file_and_user "$BUCKET_ONE_NAME" "$test_file" "$USERNAME_ONE" "$PASSWORD_ONE" "admin" + assert_success + username="${lines[${#lines[@]}-2]}" + password="${lines[${#lines[@]}-1]}" + log 5 "username: $username, password: $password" + + run put_object_rest_with_user "$username" "$password" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" + assert_success +} + +@test "REST - PutObject with no permission - 'user' user" { + run setup_bucket_file_and_user "$BUCKET_ONE_NAME" "$test_file" "$USERNAME_ONE" "$PASSWORD_ONE" "user" + assert_success + username="${lines[${#lines[@]}-2]}" + password="${lines[${#lines[@]}-1]}" + + run put_object_rest_with_user_and_code "$username" "$password" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" "403" + assert_success +} + +@test "REST - PutObject - user permission, bad signature" { + run setup_bucket_file_and_user "$BUCKET_ONE_NAME" "$test_file" "$USERNAME_ONE" "$PASSWORD_ONE" "admin" + assert_success + username="${lines[${#lines[@]}-2]}" + password="${lines[${#lines[@]}-1]}" + + run put_object_rest_user_bad_signature "$username" "$password" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" + assert_success +} diff --git a/tests/util/util_setup.sh b/tests/util/util_setup.sh index b7d532d..9f6b9b6 100644 --- a/tests/util/util_setup.sh +++ b/tests/util/util_setup.sh @@ -60,3 +60,20 @@ setup_bucket_and_user() { echo "$result" return 0 } + +setup_bucket_file_and_user() { + if [ $# -ne 5 ]; then + log 2 "'setup_bucket_file_and_user' requires bucket name, file, username, password, user type" + return 1 + fi + if ! setup_bucket_and_files "$1" "$2"; then + log 2 "error setting up bucket and file" + return 1 + fi + if ! result=$(setup_user_versitygw_or_direct "$3" "$4" "$5" "$1"); then + log 2 "error setting up user" + return 1 + fi + echo "$result" + return 0 +} diff --git a/tests/util/util_users.sh b/tests/util/util_users.sh index b5a4045..6940435 100644 --- a/tests/util/util_users.sh +++ b/tests/util/util_users.sh @@ -144,6 +144,37 @@ EOF return 0 } +put_user_policy_admin() { + log 6 "put_user_policy_admin" + if [[ $# -ne 2 ]]; then + log 2 "'put user policy admin' function requires username, bucket name" + return 1 + fi + + cat < "$TEST_FILE_FOLDER"/user_policy_file +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "s3:*", + "Resource": [ + "arn:aws:s3:::$1-*", + "arn:aws:s3:::$1-*/*", + "arn:aws:s3:::$2", + "arn:aws:s3:::$2/*" + ] + } + ] +} +EOF + if ! error=$(send_command aws --endpoint-url=https://iam.amazonaws.com iam put-user-policy --user-name "$1" --policy-name "UserPolicy" --policy-document "file://$TEST_FILE_FOLDER/user_policy_file" 2>&1); then + log 2 "error putting user policy: $error" + return 1 + fi + return 0 +} + put_user_policy() { log 6 "put_user_policy" if [[ $# -ne 3 ]]; then @@ -160,6 +191,16 @@ put_user_policy() { return 1 fi ;; + "admin") + if ! put_user_policy_admin "$1" "$3"; then + log 2 "error adding userplus policy" + return 1 + fi + ;; + *) + log 2 "unrecognized user type '$2' for putting policy" + return 1 + ;; esac return 0 } @@ -188,7 +229,7 @@ create_user_direct() { export secret_key # propagation delay occurs when user is added to IAM, so wait a few seconds - sleep 5 + sleep 10 return 0 }