diff --git a/tests/commands/create_multipart_upload.sh b/tests/commands/create_multipart_upload.sh index 60ab176d..65a7a416 100644 --- a/tests/commands/create_multipart_upload.sh +++ b/tests/commands/create_multipart_upload.sh @@ -54,6 +54,7 @@ create_multipart_upload_with_user() { return 1 fi upload_id="${upload_id//\"/}" + echo "$upload_id" return 0 } diff --git a/tests/commands/get_bucket_policy.sh b/tests/commands/get_bucket_policy.sh index fc122bc6..ec12b239 100644 --- a/tests/commands/get_bucket_policy.sh +++ b/tests/commands/get_bucket_policy.sh @@ -97,32 +97,48 @@ get_bucket_policy_s3cmd() { policy_brackets=false # NOTE: versitygw sends policies back in multiple lines here, direct in single line while IFS= read -r line; do - if [[ $policy_brackets == false ]]; then - policy_line=$(echo "$line" | grep 'Policy: ') - if [[ $policy_line != "" ]]; then - if [[ $policy_line != *'{'* ]]; then - break - fi - if [[ $policy_line == *'}'* ]]; then - log 5 "policy on single line" - bucket_policy=${policy_line//Policy:/} - break - else - policy_brackets=true - bucket_policy+="{" - fi - fi - else - bucket_policy+=$line - if [[ $line == "" ]]; then - break - fi + if check_and_load_policy_info; then + break fi done <<< "$info" log 5 "bucket policy: $bucket_policy" return 0 } +# return 0 for no policy, single-line policy, or loading complete, 1 for still searching or loading +check_and_load_policy_info() { + if [[ $policy_brackets == false ]]; then + if search_for_first_policy_line_or_full_policy; then + return 0 + fi + else + bucket_policy+=$line + if [[ $line == "}" ]]; then + return 0 + fi + fi + return 1 +} + +# return 0 for empty or single-line policy, 1 for other cases +search_for_first_policy_line_or_full_policy() { + policy_line=$(echo "$line" | grep 'Policy: ') + if [[ $policy_line != "" ]]; then + if [[ $policy_line != *'{'* ]]; then + return 0 + fi + if [[ $policy_line == *'}'* ]]; then + log 5 "policy on single line" + bucket_policy=${policy_line//Policy:/} + return 0 + else + policy_brackets=true + bucket_policy+="{" + fi + fi + return 1 +} + get_bucket_policy_mc() { record_command "get-bucket-policy" "client:mc" if [[ $# -ne 1 ]]; then diff --git a/tests/commands/head_bucket.sh b/tests/commands/head_bucket.sh index c231483e..829a4433 100644 --- a/tests/commands/head_bucket.sh +++ b/tests/commands/head_bucket.sh @@ -36,14 +36,15 @@ head_bucket() { elif [[ $1 == 'mc' ]]; then bucket_info=$(send_command mc --insecure stat "$MC_ALIAS"/"$2" 2>&1) || exit_code=$? else - fail "invalid command type $1" + log 2 "invalid command type $1" fi if [ $exit_code -ne 0 ]; then + log 2 "error getting bucket info: $bucket_info" if [[ "$bucket_info" == *"404"* ]] || [[ "$bucket_info" == *"does not exist"* ]]; then return 1 fi - log 2 "error getting bucket info: $bucket_info" return 2 fi + echo "$bucket_info" return 0 } diff --git a/tests/env.sh b/tests/env.sh index 6f78eb04..df378b44 100644 --- a/tests/env.sh +++ b/tests/env.sh @@ -63,13 +63,7 @@ check_universal_vars() { source_config_file fi if [ -n "$COMMAND_LOG" ]; then - if [ -e "$COMMAND_LOG" ]; then - if ! error=$(rm "$COMMAND_LOG"); then - log 3 "error removing command log: $error" - return 1 - fi - fi - echo "******** $(date +"%Y-%m-%d %H:%M:%S") $BATS_TEST_NAME COMMANDS ********" >> "$COMMAND_LOG" + init_command_log fi if [ "$GITHUB_ACTIONS" != "true" ] && [ -r "$SECRETS_FILE" ]; then @@ -80,6 +74,10 @@ check_universal_vars() { fi if [[ -n "$LOG_LEVEL" ]]; then + if [[ $LOG_LEVEL -lt 2 ]]; then + log 1 "log level must be 2 or greater" + exit 1 + fi export LOG_LEVEL_INT=$LOG_LEVEL fi @@ -139,6 +137,22 @@ check_universal_vars() { export AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_REGION AWS_PROFILE AWS_ENDPOINT_URL } +delete_command_log() { + if [ -e "$COMMAND_LOG" ]; then + if ! error=$(rm "$COMMAND_LOG"); then + log 2 "error removing command log: $error" + return 1 + fi + fi +} + +init_command_log() { + if ! delete_command_log; then + exit 1 + fi + echo "******** $(date +"%Y-%m-%d %H:%M:%S") $BATS_TEST_NAME COMMANDS ********" >> "$COMMAND_LOG" +} + check_versity_vars() { if [ -z "$LOCAL_FOLDER" ]; then log 1 "LOCAL_FOLDER missing" diff --git a/tests/logger.sh b/tests/logger.sh index 72f29321..e20df9be 100644 --- a/tests/logger.sh +++ b/tests/logger.sh @@ -129,8 +129,10 @@ log_message() { return 1 fi now="$(date "+%Y-%m-%d %H:%M:%S")" - echo "$now $1 $2" + if [[ ( "$1" == "CRIT" ) || ( "$1" == "ERROR" ) ]]; then + echo "$now $1 $2" >&2 + fi if [[ -n "$TEST_LOG_FILE" ]]; then - echo "$now $1 $2" >> "$TEST_LOG_FILE" + echo "$now $1 $2" >> "$TEST_LOG_FILE.tmp" fi } diff --git a/tests/rest_scripts/put_bucket_policy.sh b/tests/rest_scripts/put_bucket_policy.sh new file mode 100755 index 00000000..b2ab4fd1 --- /dev/null +++ b/tests/rest_scripts/put_bucket_policy.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +# Copyright 2024 Versity Software +# This file is licensed under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http:#www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +source ./tests/rest_scripts/rest.sh + +# Fields + +# shellcheck disable=SC2153 +bucket_name="$BUCKET_NAME" +# shellcheck disable=SC2153 +policy_file="$POLICY_FILE" + +payload="$(cat "$policy_file")" + +payload_hash="$(echo -n "$payload" | sha256sum | awk '{print $1}')" +current_date_time=$(date -u +"%Y%m%dT%H%M%SZ") + +canonical_request="PUT +/$bucket_name +policy= +host:$host +x-amz-content-sha256:$payload_hash +x-amz-date:$current_date_time + +host;x-amz-content-sha256;x-amz-date +$payload_hash" + +create_canonical_hash_sts_and_signature + +curl_command+=(curl -ks -w "\"%{http_code}\"" -X PUT "$AWS_ENDPOINT_URL/$bucket_name?policy=" +-H "\"Authorization: AWS4-HMAC-SHA256 Credential=$aws_access_key_id/$year_month_day/$aws_region/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=$signature\"" +-H "\"x-amz-content-sha256: $payload_hash\"" +-H "\"x-amz-date: $current_date_time\"" +-d "\"${payload//\"/\\\"}\"" +-o "$OUTPUT_FILE") + +# shellcheck disable=SC2154 +eval "${curl_command[*]}" 2>&1 \ No newline at end of file diff --git a/tests/setup.sh b/tests/setup.sh index 4bccb727..a256d76b 100644 --- a/tests/setup.sh +++ b/tests/setup.sh @@ -27,6 +27,13 @@ source ./tests/versity.sh setup() { base_setup + if [ -n "$TEST_LOG_FILE" ]; then + if ! error=$(touch "$TEST_LOG_FILE.tmp" 2>&1); then + log 2 "error creating log file: $error" + exit 1 + fi + fi + log 4 "Running test $BATS_TEST_NAME" if [[ $LOG_LEVEL -ge 5 ]] || [[ -n "$TIME_LOG" ]]; then start_time=$(date +%s) @@ -48,19 +55,18 @@ setup() { export AWS_PROFILE } -# fail a test -# param: error message -#fail() { -# log 1 "$1" -# exit 1 -#} +delete_temp_log_if_exists() { + if [ -e "$TEST_LOG_FILE.tmp" ]; then + if ! error=$(rm "$TEST_LOG_FILE.tmp" 2>&1); then + log 2 "error deleting temp log: $error" + return 1 + fi + fi + return 0 +} # bats teardown function teardown() { - if [[ ( "$BATS_TEST_COMPLETED" -ne 1 ) && ( -e "$COMMAND_LOG" ) ]]; then - cat "$COMMAND_LOG" - echo "**********************************************************************************" - fi # shellcheck disable=SC2154 if ! bucket_cleanup_if_bucket_exists "s3api" "$BUCKET_ONE_NAME"; then log 3 "error deleting bucket $BUCKET_ONE_NAME or contents" @@ -68,12 +74,40 @@ teardown() { if ! bucket_cleanup_if_bucket_exists "s3api" "$BUCKET_TWO_NAME"; then log 3 "error deleting bucket $BUCKET_TWO_NAME or contents" fi + if user_exists "$USERNAME_ONE" && ! delete_user "$USERNAME_ONE"; then + log 3 "error deleting user $USERNAME_ONE" + fi + if user_exists "$USERNAME_TWO" && ! delete_user "$USERNAME_TWO"; then + log 3 "error deleting user $USERNAME_TWO" + fi if [ "$REMOVE_TEST_FILE_FOLDER" == "true" ]; then log 6 "removing test file folder" if ! error=$(rm -rf "${TEST_FILE_FOLDER:?}" 2>&1); then log 3 "unable to remove test file folder: $error" fi fi + if [[ "$BATS_TEST_COMPLETED" -ne 1 ]]; then + if [[ -e "$COMMAND_LOG" ]]; then + cat "$COMMAND_LOG" + echo "**********************************************************************************" + fi + if [[ -e "$TEST_LOG_FILE.tmp" ]]; then + echo "********************************** LOG *******************************************" + cat "$TEST_LOG_FILE.tmp" + echo "**********************************************************************************" + fi + fi + if ! delete_command_log; then + log 3 "error deleting command log" + fi + if [ -e "$TEST_LOG_FILE.tmp" ]; then + if ! error=$(cat "$TEST_LOG_FILE.tmp" >> "$TEST_LOG_FILE" 2>&1); then + log 2 "error appending temp log to main log: $error" + fi + if ! delete_temp_log_if_exists; then + log 2 "error deleting temp log" + fi + fi stop_versity if [[ $LOG_LEVEL -ge 5 ]] || [[ -n "$TIME_LOG" ]]; then end_time=$(date +%s) diff --git a/tests/test_common.sh b/tests/test_common.sh index b5ce1cc3..b03d7f0e 100644 --- a/tests/test_common.sh +++ b/tests/test_common.sh @@ -382,12 +382,7 @@ test_common_get_put_delete_bucket_policy() { assert_success effect="Allow" - #principal="*" - if [[ $DIRECT == "true" ]]; then - principal="{\"AWS\": \"arn:aws:iam::$DIRECT_AWS_USER_ID:user/s3user\"}" - else - principal="\"*\"" - fi + principal="*" action="s3:GetObject" resource="arn:aws:s3:::$BUCKET_ONE_NAME/*" diff --git a/tests/test_common_acl.sh b/tests/test_common_acl.sh index 40741822..cb5ea145 100644 --- a/tests/test_common_acl.sh +++ b/tests/test_common_acl.sh @@ -44,9 +44,6 @@ test_put_bucket_acl_s3cmd() { } test_common_put_bucket_acl() { - if [[ $RECREATE_BUCKETS == "false" ]]; then - skip "https://github.com/versity/versitygw/issues/716" - fi assert [ $# -eq 1 ] run setup_bucket "$1" "$BUCKET_ONE_NAME" diff --git a/tests/test_rest.sh b/tests/test_rest.sh index d2640280..a27e9e29 100755 --- a/tests/test_rest.sh +++ b/tests/test_rest.sh @@ -42,6 +42,8 @@ source ./tests/util/util_tags.sh source ./tests/util/util_time.sh source ./tests/util/util_versioning.sh +export RUN_USERS=true + @test "test_rest_list_objects" { run setup_bucket "s3api" "$BUCKET_ONE_NAME" assert_success @@ -422,4 +424,22 @@ source ./tests/util/util_versioning.sh run get_and_check_no_policy_error "$BUCKET_ONE_NAME" assert_success +} + +@test "REST - put policy" { + run setup_bucket "s3api" "$BUCKET_ONE_NAME" + assert_success + + run setup_user_versitygw_or_direct "$USERNAME_ONE" "$PASSWORD_ONE" "user" "$BUCKET_ONE_NAME" + assert_success + log 5 "username: ${lines[0]}" + log 5 "password: ${lines[1]}" + + sleep 5 + + run setup_policy_with_single_statement "$TEST_FILE_FOLDER/policy_file.txt" "2012-10-17" "Allow" "$USERNAME_ONE" "s3:PutBucketTagging" "arn:aws:s3:::$BUCKET_ONE_NAME" + assert_success + + run put_and_check_policy_rest "$BUCKET_ONE_NAME" "$TEST_FILE_FOLDER/policy_file.txt" "Allow" "$USERNAME_ONE" "s3:PutBucketTagging" "arn:aws:s3:::$BUCKET_ONE_NAME" + assert_success } \ No newline at end of file diff --git a/tests/test_s3api_bucket.sh b/tests/test_s3api_bucket.sh index d0768697..0dfb5560 100755 --- a/tests/test_s3api_bucket.sh +++ b/tests/test_s3api_bucket.sh @@ -18,6 +18,7 @@ source ./tests/setup.sh source ./tests/util/util.sh source ./tests/util/util_create_bucket.sh source ./tests/util/util_file.sh +source ./tests/util/util_head_bucket.sh source ./tests/util/util_lock_config.sh source ./tests/util/util_tags.sh source ./tests/util/util_users.sh @@ -101,13 +102,11 @@ export RUN_USERS=true } @test "test_head_bucket_doesnt_exist" { - run setup_bucket "s3api" "$BUCKET_ONE_NAME" + if [ "$RECREATE_BUCKETS" == "false" ]; then + skip "skip test for static buckets" + fi + run bucket_info_without_bucket assert_success - - head_bucket "s3api" "$BUCKET_ONE_NAME"a || local info_result=$? - [[ $info_result -eq 1 ]] || fail "bucket info for non-existent bucket returned" - [[ $bucket_info == *"404"* ]] || fail "404 not returned for non-existent bucket info" - bucket_cleanup "s3api" "$BUCKET_ONE_NAME" } @test "test_head_bucket_invalid_name" { diff --git a/tests/test_s3api_multipart.sh b/tests/test_s3api_multipart.sh index 67d776b9..c5020235 100755 --- a/tests/test_s3api_multipart.sh +++ b/tests/test_s3api_multipart.sh @@ -119,7 +119,7 @@ source ./tests/commands/list_multipart_uploads.sh run get_and_check_legal_hold "s3api" "$BUCKET_ONE_NAME" "$bucket_file" "OFF" assert_success - run download_and_compare_file "s3api" "$TEST_FILE_FOLDER/$bucket_file" "$BUCKET_ONE_NAME" "$bucket_file" "$TEST_FILE_FOLDER/$bucket_file-copy" || fail "error getting object" + run download_and_compare_file "s3api" "$TEST_FILE_FOLDER/$bucket_file" "$BUCKET_ONE_NAME" "$bucket_file" "$TEST_FILE_FOLDER/$bucket_file-copy" assert_success } diff --git a/tests/test_s3api_object.sh b/tests/test_s3api_object.sh index 74db6516..4a180956 100755 --- a/tests/test_s3api_object.sh +++ b/tests/test_s3api_object.sh @@ -55,7 +55,8 @@ export RUN_USERS=true } @test "test_copy_object_empty" { - copy_object_empty || fail "copy objects with no parameters test failure" + run copy_object_empty + assert_success } # delete-object - tested with bucket cleanup before or after tests @@ -160,8 +161,6 @@ export RUN_USERS=true run get_and_check_object_lock_config "$bucket_name" "$enabled" "$governance" "$days" assert_success "error getting and checking object lock config" - - bucket_cleanup "s3api" "$bucket_name" } @test "test_put_object_metadata" { @@ -176,17 +175,14 @@ export RUN_USERS=true assert_success object="$TEST_FILE_FOLDER"/"$object_one" - put_object_with_metadata "s3api" "$object" "$BUCKET_ONE_NAME" "$object_one" "$test_key" "$test_value" || fail "failed to add object to bucket" - object_exists "s3api" "$BUCKET_ONE_NAME" "$object_one" || fail "object not found after being added to bucket" + run put_object_with_metadata "s3api" "$object" "$BUCKET_ONE_NAME" "$object_one" "$test_key" "$test_value" + assert_success - get_object_metadata "s3api" "$BUCKET_ONE_NAME" "$object_one" || fail "error getting object metadata" - key=$(echo "$metadata" | jq -r 'keys[]' 2>&1) || fail "error getting key from metadata: $key" - value=$(echo "$metadata" | jq -r '.[]' 2>&1) || fail "error getting value from metadata: $value" - [[ $key == "$test_key" ]] || fail "keys doesn't match (expected $key, actual \"$test_key\")" - [[ $value == "$test_value" ]] || fail "values doesn't match (expected $value, actual \"$test_value\")" + run object_exists "s3api" "$BUCKET_ONE_NAME" "$object_one" + assert_success - bucket_cleanup "s3api" "$BUCKET_ONE_NAME" - delete_test_files "$object_one" + run get_object_metadata_and_check_keys "$BUCKET_ONE_NAME" "$object_one" "$test_key" "$test_value" + assert_success } @test "test_retention_bypass" { diff --git a/tests/test_s3api_policy_multipart.sh b/tests/test_s3api_policy_multipart.sh index c66ebce1..72252596 100644 --- a/tests/test_s3api_policy_multipart.sh +++ b/tests/test_s3api_policy_multipart.sh @@ -17,10 +17,6 @@ test_s3api_policy_abort_multipart_upload() { policy_file="policy_file" test_file="test_file" - username=$USERNAME_ONE - - run create_test_file "$policy_file" - assert_success run create_large_file "$test_file" assert_success @@ -28,43 +24,42 @@ test_s3api_policy_abort_multipart_upload() { run setup_bucket "s3api" "$BUCKET_ONE_NAME" assert_success - if [[ $DIRECT == "true" ]]; then - setup_user_direct "$username" "user" "$BUCKET_ONE_NAME" || fail "error setting up direct user $username" - principal="{\"AWS\": \"arn:aws:iam::$DIRECT_AWS_USER_ID:user/$username\"}" - # shellcheck disable=SC2154 - username=$key_id - # shellcheck disable=SC2154 - password=$secret_key - else - password=$PASSWORD_ONE - setup_user "$username" "$password" "user" || fail "error setting up user $username" - principal="\"$username\"" - fi - - setup_policy_with_double_statement "$TEST_FILE_FOLDER/$policy_file" "2012-10-17" \ - "Allow" "$principal" "s3:PutObject" "arn:aws:s3:::$BUCKET_ONE_NAME/*" \ - "Deny" "$principal" "s3:AbortMultipartUpload" "arn:aws:s3:::$BUCKET_ONE_NAME/*" - put_bucket_policy "s3api" "$BUCKET_ONE_NAME" "$TEST_FILE_FOLDER/$policy_file" || fail "error putting first policy" - - create_multipart_upload_with_user "$BUCKET_ONE_NAME" "$test_file" "$username" "$password" || fail "error creating multipart upload" + run setup_user_versitygw_or_direct "$USERNAME_ONE" "$PASSWORD_ONE" "user" "$BUCKET_ONE_NAME" + assert_success # shellcheck disable=SC2154 - if abort_multipart_upload_with_user "$BUCKET_ONE_NAME" "$test_file" "$upload_id" "$username" "$password"; then - fail "abort multipart upload succeeded despite lack of permissions" - fi + username=${lines[0]} + password=${lines[1]} + + run setup_policy_with_double_statement "$TEST_FILE_FOLDER/$policy_file" "2012-10-17" \ + "Allow" "$USERNAME_ONE" "s3:PutObject" "arn:aws:s3:::$BUCKET_ONE_NAME/*" \ + "Deny" "$USERNAME_ONE" "s3:AbortMultipartUpload" "arn:aws:s3:::$BUCKET_ONE_NAME/*" + assert_success # shellcheck disable=SC2154 - [[ "$abort_multipart_upload_error" == *"AccessDenied"* ]] || fail "unexpected abort error: $abort_multipart_upload_error" - setup_policy_with_single_statement "$TEST_FILE_FOLDER/$policy_file" "2012-10-17" "Allow" "$principal" "s3:AbortMultipartUpload" "arn:aws:s3:::$BUCKET_ONE_NAME/*" + run put_bucket_policy "s3api" "$BUCKET_ONE_NAME" "$TEST_FILE_FOLDER/$policy_file" + assert_success + + run create_multipart_upload_with_user "$BUCKET_ONE_NAME" "$test_file" "$username" "$password" + assert_success + # shellcheck disable=SC2154 + upload_id="$output" + + run check_abort_access_denied "$BUCKET_ONE_NAME" "$test_file" "$upload_id" "$username" "$password" + assert_success + + run setup_policy_with_single_statement "$TEST_FILE_FOLDER/$policy_file" "2012-10-17" "Allow" "$USERNAME_ONE" "s3:AbortMultipartUpload" "arn:aws:s3:::$BUCKET_ONE_NAME/*" + assert_success + + run put_bucket_policy "s3api" "$BUCKET_ONE_NAME" "$TEST_FILE_FOLDER/$policy_file" + assert_success - put_bucket_policy "s3api" "$BUCKET_ONE_NAME" "$TEST_FILE_FOLDER/$policy_file" || fail "error putting policy" - abort_multipart_upload_with_user "$BUCKET_ONE_NAME" "$test_file" "$upload_id" "$username" "$password" || fail "error aborting multipart upload despite permissions" + run abort_multipart_upload_with_user "$BUCKET_ONE_NAME" "$test_file" "$upload_id" "$username" "$password" + assert_success } test_s3api_policy_list_multipart_uploads() { policy_file="policy_file" test_file="test_file" - username=$USERNAME_ONE - password=$PASSWORD_ONE run create_test_file "$policy_file" assert_success @@ -73,35 +68,33 @@ test_s3api_policy_list_multipart_uploads() { assert_success effect="Allow" - principal="$username" + principal="$USERNAME_ONE" action="s3:ListBucketMultipartUploads" resource="arn:aws:s3:::$BUCKET_ONE_NAME" - setup_user "$username" "$password" "user" || fail "error creating user" + + run setup_user_versitygw_or_direct "$USERNAME_ONE" "$PASSWORD_ONE" "user" "$BUCKET_ONE_NAME" + assert_success + username=${lines[0]} + password=${lines[1]} run setup_bucket "s3api" "$BUCKET_ONE_NAME" assert_success - get_bucket_policy "s3api" "$BUCKET_ONE_NAME" || fail "error getting bucket policy" - # shellcheck disable=SC2154 - log 5 "BUCKET POLICY: $bucket_policy" - get_bucket_acl "s3api" "$BUCKET_ONE_NAME" || fail "error getting bucket ACL" - # shellcheck disable=SC2154 - log 5 "ACL: $acl" run setup_policy_with_single_statement "$TEST_FILE_FOLDER/$policy_file" "dummy" "$effect" "$principal" "$action" "$resource" - assert_success "failed to set up policy" + assert_success + run create_multipart_upload "$BUCKET_ONE_NAME" "$test_file" - assert_success "failed to create multipart upload" - if list_multipart_uploads_with_user "$BUCKET_ONE_NAME" "$username" "$password"; then - fail "able to list multipart uploads despite lack of permissions" - fi - # shellcheck disable=SC2154 - [[ "$list_multipart_uploads_error" == *"Access Denied"* ]] || fail "invalid list multipart uploads error: $list_multipart_uploads_error" - put_bucket_policy "s3api" "$BUCKET_ONE_NAME" "$TEST_FILE_FOLDER/$policy_file" || fail "error putting policy" - list_multipart_uploads_with_user "$BUCKET_ONE_NAME" "$username" "$password" || fail "error listing multipart uploads" - # shellcheck disable=SC2154 - log 5 "$uploads" - upload_key=$(echo "$uploads" | grep -v "InsecureRequestWarning" | jq -r ".Uploads[0].Key" 2>&1) || fail "error parsing upload key from uploads message: $upload_key" - [[ $upload_key == "$test_file" ]] || fail "upload key doesn't match file marked as being uploaded" + assert_success + + run list_multipart_uploads_with_user "$BUCKET_ONE_NAME" "$username" "$password" + assert_failure + assert_output -p "Access Denied" + + run put_bucket_policy "s3api" "$BUCKET_ONE_NAME" "$TEST_FILE_FOLDER/$policy_file" + assert_success + + run list_check_multipart_upload_key "$BUCKET_ONE_NAME" "$username" "$password" "$test_file" + assert_success } test_s3api_policy_list_upload_parts() { diff --git a/tests/test_s3api_policy_object.sh b/tests/test_s3api_policy_object.sh index 4c8d039b..eebd7cec 100644 --- a/tests/test_s3api_policy_object.sh +++ b/tests/test_s3api_policy_object.sh @@ -14,6 +14,8 @@ # specific language governing permissions and limitations # under the License. +source ./tests/util/util_delete_object.sh + test_s3api_policy_allow_deny() { policy_file="policy_file" test_file="test_file" @@ -59,23 +61,30 @@ test_s3api_policy_delete() { action="s3:DeleteObject" resource="arn:aws:s3:::$BUCKET_ONE_NAME/$test_file_two" - setup_user "$username" "$password" "user" || fail "error creating user" + run setup_user "$username" "$password" "user" + assert_success run setup_bucket "s3api" "$BUCKET_ONE_NAME" assert_success - setup_policy_with_single_statement "$TEST_FILE_FOLDER/$policy_file" "dummy" "$effect" "$principal" "$action" "$resource" || fail "failed to set up policy" + run setup_policy_with_single_statement "$TEST_FILE_FOLDER/$policy_file" "dummy" "$effect" "$principal" "$action" "$resource" + assert_success + log 5 "Policy: $(cat "$TEST_FILE_FOLDER/$policy_file")" - put_bucket_policy "s3api" "$BUCKET_ONE_NAME" "$TEST_FILE_FOLDER/$policy_file" || fail "error putting policy" + run put_bucket_policy "s3api" "$BUCKET_ONE_NAME" "$TEST_FILE_FOLDER/$policy_file" + assert_success - put_object "s3api" "$TEST_FILE_FOLDER/$test_file_one" "$BUCKET_ONE_NAME" "$test_file_one" || fail "error copying object one" - put_object "s3api" "$TEST_FILE_FOLDER/$test_file_two" "$BUCKET_ONE_NAME" "$test_file_two" || fail "error copying object two" - if delete_object_with_user "s3api" "$BUCKET_ONE_NAME" "$test_file_one" "$username" "$password"; then - fail "able to delete object despite lack of permissions" - fi - # shellcheck disable=SC2154 - [[ "$delete_object_error" == *"Access Denied"* ]] || fail "invalid delete object error: $delete_object_error" - delete_object_with_user "s3api" "$BUCKET_ONE_NAME" "$test_file_two" "$username" "$password" || fail "error deleting object despite permissions" + run put_object "s3api" "$TEST_FILE_FOLDER/$test_file_one" "$BUCKET_ONE_NAME" "$test_file_one" + assert_success + + run put_object "s3api" "$TEST_FILE_FOLDER/$test_file_two" "$BUCKET_ONE_NAME" "$test_file_two" + assert_success + + run block_delete_object_without_permission "$BUCKET_ONE_NAME" "$test_file_one" "$username" "$password" + assert_success + + run delete_object_with_user "s3api" "$BUCKET_ONE_NAME" "$test_file_two" "$username" "$password" + assert_success } test_s3api_policy_deny() { @@ -88,20 +97,28 @@ test_s3api_policy_deny() { run create_test_files "$test_file_one" "$test_file_two" "$policy_file" assert_success - setup_user "$username" "$password" "user" || fail "error creating user" + run setup_user "$username" "$password" "user" + assert_success run setup_bucket "s3api" "$BUCKET_ONE_NAME" assert_success - setup_policy_with_double_statement "$TEST_FILE_FOLDER/$policy_file" "dummy" \ + run setup_policy_with_double_statement "$TEST_FILE_FOLDER/$policy_file" "dummy" \ "Deny" "$username" "s3:GetObject" "arn:aws:s3:::$BUCKET_ONE_NAME/$test_file_two" \ "Allow" "$username" "s3:GetObject" "arn:aws:s3:::$BUCKET_ONE_NAME/*" + assert_success log 5 "Policy: $(cat "$TEST_FILE_FOLDER/$policy_file")" - put_bucket_policy "s3api" "$BUCKET_ONE_NAME" "$TEST_FILE_FOLDER/$policy_file" || fail "error putting policy" - put_object "s3api" "$TEST_FILE_FOLDER/$test_file_one" "$BUCKET_ONE_NAME" "$test_file_one" || fail "error copying object one" - put_object "s3api" "$TEST_FILE_FOLDER/$test_file_one" "$BUCKET_ONE_NAME" "$test_file_two" || fail "error copying object two" - get_object_with_user "s3api" "$BUCKET_ONE_NAME" "$test_file_one" "$TEST_FILE_FOLDER/$test_file_one-copy" "$username" "$password" || fail "error getting object" + run put_bucket_policy "s3api" "$BUCKET_ONE_NAME" "$TEST_FILE_FOLDER/$policy_file" + assert_success + + run put_object "s3api" "$TEST_FILE_FOLDER/$test_file_one" "$BUCKET_ONE_NAME" "$test_file_one" + assert_success + run put_object "s3api" "$TEST_FILE_FOLDER/$test_file_one" "$BUCKET_ONE_NAME" "$test_file_two" + assert_success + + run get_object_with_user "s3api" "$BUCKET_ONE_NAME" "$test_file_one" "$TEST_FILE_FOLDER/$test_file_one-copy" "$username" "$password" + assert_success run verify_user_cant_get_object "s3api" "$BUCKET_ONE_NAME" "$test_file_two" "$TEST_FILE_FOLDER/$test_file_two-copy" "$username" "$password" assert_success @@ -202,16 +219,23 @@ test_s3api_policy_get_object_specific_file() { action="s3:GetObject" resource="arn:aws:s3:::$BUCKET_ONE_NAME/test_file" - setup_user "$username" "$password" "user" || fail "error creating user" + run setup_user "$username" "$password" "user" + assert_success run setup_bucket "s3api" "$BUCKET_ONE_NAME" assert_success - setup_policy_with_single_statement "$TEST_FILE_FOLDER/$policy_file" "dummy" "$effect" "$principal" "$action" "$resource" || fail "failed to set up policy" - put_bucket_policy "s3api" "$BUCKET_ONE_NAME" "$TEST_FILE_FOLDER/$policy_file" || fail "error putting policy" + run setup_policy_with_single_statement "$TEST_FILE_FOLDER/$policy_file" "dummy" "$effect" "$principal" "$action" "$resource" + assert_success + + run put_bucket_policy "s3api" "$BUCKET_ONE_NAME" "$TEST_FILE_FOLDER/$policy_file" + assert_success + + run put_object "s3api" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" + assert_success - put_object "s3api" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" || fail "error copying object" - put_object "s3api" "$TEST_FILE_FOLDER/$test_file_two" "$BUCKET_ONE_NAME" "$test_file_two" || fail "error copying object" + run put_object "s3api" "$TEST_FILE_FOLDER/$test_file_two" "$BUCKET_ONE_NAME" "$test_file_two" + assert_success run download_and_compare_file_with_user "s3api" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy" "$username" "$password" assert_success @@ -286,8 +310,6 @@ test_s3api_policy_put_wildcard() { policy_file="policy_file" test_folder="test_folder" test_file="test_file" - username=$USERNAME_ONE - password=$PASSWORD_ONE run create_test_folder "$test_folder" assert_success @@ -295,28 +317,39 @@ test_s3api_policy_put_wildcard() { run create_test_files "$test_folder/$test_file" "$policy_file" assert_success + run setup_user_versitygw_or_direct "$USERNAME_ONE" "$PASSWORD_ONE" "user" "$BUCKET_ONE_NAME" + assert_success + # shellcheck disable=SC2154 + username=${lines[0]} + password=${lines[1]} + effect="Allow" principal="$username" action="s3:PutObject" resource="arn:aws:s3:::$BUCKET_ONE_NAME/$test_folder/*" - setup_user "$username" "$password" "user" || fail "error creating user" + run setup_bucket "s3api" "$BUCKET_ONE_NAME" + assert_success - setup_bucket "s3api" "$BUCKET_ONE_NAME" - log 5 "Policy: $(cat "$TEST_FILE_FOLDER/$policy_file")" - setup_policy_with_single_statement "$TEST_FILE_FOLDER/$policy_file" "dummy" "$effect" "$principal" "$action" "$resource" || fail "failed to set up policy" - put_bucket_policy "s3api" "$BUCKET_ONE_NAME" "$TEST_FILE_FOLDER/$policy_file" || fail "error putting policy" - if put_object_with_user "s3api" "$TEST_FILE_FOLDER/$test_folder/$test_file" "$BUCKET_ONE_NAME" "$test_file" "$username" "$password"; then - fail "able to put object despite not being allowed" - fi + run setup_policy_with_single_statement "$TEST_FILE_FOLDER/$policy_file" "dummy" "$effect" "$principal" "$action" "$resource" + assert_success + + run put_bucket_policy "s3api" "$BUCKET_ONE_NAME" "$TEST_FILE_FOLDER/$policy_file" + assert_success + + run put_object_with_user "s3api" "$TEST_FILE_FOLDER/$test_folder/$test_file" "$BUCKET_ONE_NAME" "$test_file" "$username" "$password" + assert_failure # shellcheck disable=SC2154 - [[ "$put_object_error" == *"Access Denied"* ]] || fail "invalid put object error: $put_object_error" - put_object_with_user "s3api" "$TEST_FILE_FOLDER/$test_folder/$test_file" "$BUCKET_ONE_NAME" "$test_folder/$test_file" "$username" "$password" || fail "error putting file despite policy permissions" + assert_output -p "Access Denied" + + run put_object_with_user "s3api" "$TEST_FILE_FOLDER/$test_folder/$test_file" "$BUCKET_ONE_NAME" "$test_folder/$test_file" "$username" "$password" + assert_success run verify_user_cant_get_object "s3api" "$BUCKET_ONE_NAME" "$test_folder/$test_file" "$test_folder/$test_file-copy" "$username" "$password" assert_success - download_and_compare_file "s3api" "$TEST_FILE_FOLDER/$test_folder/$test_file" "$BUCKET_ONE_NAME" "$test_folder/$test_file" "$TEST_FILE_FOLDER/$test_file-copy" || fail "files don't match" + run download_and_compare_file "s3api" "$TEST_FILE_FOLDER/$test_folder/$test_file" "$BUCKET_ONE_NAME" "$test_folder/$test_file" "$TEST_FILE_FOLDER/$test_file-copy" + assert_success } test_s3api_policy_two_principals() { @@ -324,29 +357,29 @@ test_s3api_policy_two_principals() { test_file="test_file" run create_test_files "$test_file" "$policy_file" - assert_success "error creating test files" + assert_success run setup_bucket "s3api" "$BUCKET_ONE_NAME" - assert_success "error setting up bucket $BUCKET_ONE_NAME" + assert_success run setup_user "$USERNAME_ONE" "$PASSWORD_ONE" "user" - assert_success "error setting up user $USERNAME_ONE" + assert_success run setup_user "$USERNAME_TWO" "$PASSWORD_TWO" "user" - assert_success "error setting up user $USERNAME_TWO" + assert_success run put_object "s3api" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" - assert_success "error adding object to bucket" + assert_success run get_object_with_user "s3api" "$BUCKET_ONE_NAME" "$test_file" "$TEST_FILE_FOLDER/copy_one" "$USERNAME_ONE" "$PASSWORD_ONE" - assert_failure "able to get object with user $USERNAME_ONE despite lack of permission" + assert_failure run get_object_with_user "s3api" "$BUCKET_ONE_NAME" "$test_file" "$TEST_FILE_FOLDER/copy_two" "$USERNAME_TWO" "$PASSWORD_TWO" - assert_failure "able to get object with user $USERNAME_TWO despite lack of permission" + assert_failure - run setup_policy_with_single_statement "$TEST_FILE_FOLDER/$policy_file" "dummy" "Allow" "[\"$USERNAME_ONE\", \"$USERNAME_TWO\"]" "s3:GetObject" "arn:aws:s3:::$BUCKET_ONE_NAME/*" - assert_success "error setting up policy" + run setup_policy_with_single_statement "$TEST_FILE_FOLDER/$policy_file" "dummy" "Allow" "$USERNAME_ONE,$USERNAME_TWO" "s3:GetObject" "arn:aws:s3:::$BUCKET_ONE_NAME/*" + assert_success run put_bucket_policy "s3api" "$BUCKET_ONE_NAME" "$TEST_FILE_FOLDER/$policy_file" - assert_success "error putting policy" + assert_success run get_object_with_user "s3api" "$BUCKET_ONE_NAME" "$test_file" "$TEST_FILE_FOLDER/copy_one" "$USERNAME_ONE" "$PASSWORD_ONE" - assert_success "error getting object with user $USERNAME_ONE" + assert_success run get_object_with_user "s3api" "$BUCKET_ONE_NAME" "$test_file" "$TEST_FILE_FOLDER/copy_two" "$USERNAME_TWO" "$PASSWORD_TWO" - assert_success "error getting object with user $USERNAME_TWO" + assert_success } diff --git a/tests/test_s3api_root_inner.sh b/tests/test_s3api_root_inner.sh index 52bcaba4..672ce8c0 100755 --- a/tests/test_s3api_root_inner.sh +++ b/tests/test_s3api_root_inner.sh @@ -119,10 +119,6 @@ test_get_object_attributes_s3api_root() { } test_get_put_object_legal_hold_s3api_root() { - if [[ $RECREATE_BUCKETS == "false" ]]; then - skip "https://github.com/versity/versitygw/issues/716" - fi - bucket_file="bucket_file" username=$USERNAME_ONE password=$PASSWORD_ONE @@ -141,9 +137,8 @@ test_get_put_object_legal_hold_s3api_root() { echo "fdkljafajkfs" > "$TEST_FILE_FOLDER/$bucket_file" run put_object_with_user "s3api" "$TEST_FILE_FOLDER/$bucket_file" "$BUCKET_ONE_NAME" "$bucket_file" "$username" "$password" - assert_failure 1 - # shellcheck disable=SC2154 - #[[ $put_object_error == *"Object is WORM protected and cannot be overwritten"* ]] || fail "unexpected error message: $put_object_error" + assert_failure + assert_output --partial "Object is WORM protected and cannot be overwritten" run delete_object_with_user "s3api" "$BUCKET_ONE_NAME" "$bucket_file" "$username" "$password" assert_failure 1 @@ -162,10 +157,6 @@ test_get_put_object_retention_s3api_root() { username=$USERNAME_ONE secret_key=$PASSWORD_ONE - if [[ $RECREATE_BUCKETS == "false" ]]; then - skip "https://github.com/versity/versitygw/issues/716" - fi - run legal_hold_retention_setup "$username" "$secret_key" "$bucket_file" assert_success @@ -187,20 +178,17 @@ test_get_put_object_retention_s3api_root() { echo "fdkljafajkfs" > "$TEST_FILE_FOLDER/$bucket_file" run put_object_with_user "s3api" "$TEST_FILE_FOLDER/$bucket_file" "$BUCKET_ONE_NAME" "$bucket_file" "$username" "$secret_key" - assert_failure 1 + assert_failure # shellcheck disable=SC2154 assert_output --partial "Object is WORM protected and cannot be overwritten" run delete_object_with_user "s3api" "$BUCKET_ONE_NAME" "$bucket_file" "$username" "$secret_key" - assert_failure 1 + assert_failure # shellcheck disable=SC2154 assert_output --partial "Object is WORM protected and cannot be overwritten" } test_retention_bypass_s3api_root() { - if [[ $RECREATE_BUCKETS == "false" ]]; then - skip "https://github.com/versity/versitygw/issues/716" - fi bucket_file="bucket_file" username=$USERNAME_ONE secret_key=$PASSWORD_ONE diff --git a/tests/test_s3cmd.sh b/tests/test_s3cmd.sh index 0a6f32df..6ac5596d 100755 --- a/tests/test_s3cmd.sh +++ b/tests/test_s3cmd.sh @@ -47,12 +47,9 @@ export RUN_USERS=true return fi - create_bucket_invalid_name "s3cmd" || local create_result=$? - [[ $create_result -eq 0 ]] || fail "Invalid name test failed" - - [[ "$bucket_create_error" == *"just the bucket name"* ]] || fail "unexpected error: $bucket_create_error" - - bucket_cleanup "s3cmd" "$BUCKET_ONE_NAME" + run create_bucket_invalid_name "s3cmd" + assert_success + assert_output -p "just the bucket name" } # delete-bucket - test_create_delete_bucket @@ -93,6 +90,7 @@ export RUN_USERS=true } @test "test_put_bucket_acl" { + skip "https://github.com/versity/versitygw/issues/963" test_put_bucket_acl_s3cmd } @@ -113,19 +111,18 @@ export RUN_USERS=true run setup_bucket "s3cmd" "$BUCKET_ONE_NAME" assert_success - head_bucket "s3cmd" "$BUCKET_ONE_NAME" - [[ $bucket_info == *"s3://$BUCKET_ONE_NAME"* ]] || fail "failure to retrieve correct bucket info: $bucket_info" - bucket_cleanup "s3cmd" "$BUCKET_ONE_NAME" + run head_bucket "s3cmd" "$BUCKET_ONE_NAME" + assert_success + assert_output -p "s3://$BUCKET_ONE_NAME" } @test "test_get_bucket_info_doesnt_exist_s3cmd" { run setup_bucket "s3cmd" "$BUCKET_ONE_NAME" assert_success - head_bucket "s3cmd" "$BUCKET_ONE_NAME"a || local info_result=$? - [[ $info_result -eq 1 ]] || fail "bucket info for non-existent bucket returned" - [[ $bucket_info == *"404"* ]] || fail "404 not returned for non-existent bucket info" - bucket_cleanup "s3cmd" "$BUCKET_ONE_NAME" + run head_bucket "s3cmd" "$BUCKET_ONE_NAME"a + assert_failure 1 + assert_output -p "404" } @test "test_ls_directory_object" { diff --git a/tests/test_user_aws.sh b/tests/test_user_aws.sh index bad8824a..81a24add 100755 --- a/tests/test_user_aws.sh +++ b/tests/test_user_aws.sh @@ -44,11 +44,12 @@ export RUN_USERS=true } @test "test_user_get_object" { - username="$USERNAME_ONE" - password="$USERNAME_ONE" test_file="test_file" - setup_user "$username" "$password" "user" || fail "error creating user if nonexistent" + run setup_user_versitygw_or_direct "$USERNAME_ONE" "$PASSWORD_ONE" "user" "$BUCKET_ONE_NAME" + assert_success + username=${lines[0]} + password=${lines[1]} run create_test_file "$test_file" assert_success @@ -56,20 +57,26 @@ export RUN_USERS=true run setup_bucket "s3api" "$BUCKET_ONE_NAME" assert_success - if get_object_with_user "s3api" "$BUCKET_ONE_NAME" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy" "$username" "$password"; then - fail "able to get object despite not being bucket owner" - fi - change_bucket_owner "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY" "$BUCKET_ONE_NAME" "$username" || fail "error changing bucket ownership" - put_object "s3api" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" || fail "failed to add object to bucket" - get_object_with_user "s3api" "$BUCKET_ONE_NAME" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy" "$username" "$password" || fail "error getting object" + run get_object_with_user "s3api" "$BUCKET_ONE_NAME" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy" "$username" "$password" + assert_failure + + run change_bucket_owner "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY" "$BUCKET_ONE_NAME" "$username" + assert_success + + run put_object "s3api" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" + assert_success + + run get_object_with_user "s3api" "$BUCKET_ONE_NAME" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy" "$username" "$password" + assert_success } @test "test_userplus_get_object" { - username="$USERNAME_ONE" - password="$PASSWORD_ONE" test_file="test_file" - setup_user "$username" "$password" "admin" || fail "error creating user if nonexistent" + run setup_user_versitygw_or_direct "$USERNAME_ONE" "$PASSWORD_ONE" "userplus" "$BUCKET_ONE_NAME" + assert_success + username=${lines[0]} + password=${lines[1]} run create_test_file "$test_file" assert_success @@ -77,20 +84,26 @@ export RUN_USERS=true run setup_bucket "s3api" "$BUCKET_ONE_NAME" assert_success - if get_object_with_user "s3api" "$BUCKET_ONE_NAME" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy" "$username" "$password"; then - fail "able to get object despite not being bucket owner" - fi - change_bucket_owner "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY" "$BUCKET_ONE_NAME" "$username" || fail "error changing bucket ownership" - put_object "s3api" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" || fail "failed to add object to bucket" - get_object_with_user "s3api" "$BUCKET_ONE_NAME" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy" "$username" "$password" || fail "error getting object" + run get_object_with_user "s3api" "$BUCKET_ONE_NAME" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy" "$username" "$password" + assert_failure + + run change_bucket_owner "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY" "$BUCKET_ONE_NAME" "$username" + assert_success + + run put_object "s3api" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" + assert_success + + run get_object_with_user "s3api" "$BUCKET_ONE_NAME" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy" "$username" "$password" + assert_success } @test "test_user_delete_object" { - username="$USERNAME_ONE" - password="$PASSWORD_ONE" test_file="test_file" - setup_user "$username" "$password" "user" || fail "error creating user if nonexistent" + run setup_user_versitygw_or_direct "$USERNAME_ONE" "$PASSWORD_ONE" "user" "$BUCKET_ONE_NAME" + assert_success + username=${lines[0]} + password=${lines[1]} run create_test_file "$test_file" assert_success @@ -98,23 +111,29 @@ export RUN_USERS=true run setup_bucket "s3api" "$BUCKET_ONE_NAME" assert_success - if get_object_with_user "s3api" "$BUCKET_ONE_NAME" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy" "$username" "$password"; then - fail "able to get object despite not being bucket owner" - fi - change_bucket_owner "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY" "$BUCKET_ONE_NAME" "$username" || fail "error changing bucket ownership" - put_object "s3api" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" || fail "failed to add object to bucket" - delete_object_with_user "s3api" "$BUCKET_ONE_NAME" "$test_file" "$username" "$password" || fail "error deleting object" + run put_object "s3api" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" + assert_success + + run delete_object_with_user "s3api" "$BUCKET_ONE_NAME" "$test_file" "$username" "$password" + assert_failure + + run change_bucket_owner "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY" "$BUCKET_ONE_NAME" "$username" + assert_success + + run delete_object_with_user "s3api" "$BUCKET_ONE_NAME" "$test_file" "$username" "$password" + assert_success } @test "test_admin_put_get_object" { if [ "$RECREATE_BUCKETS" == "false" ]; then skip "https://github.com/versity/versitygw/issues/888" fi - username="$USERNAME_ONE" - password="$PASSWORD_ONE" test_file="test_file" - setup_user "$username" "$password" "admin" || fail "error creating user if nonexistent" + run setup_user_versitygw_or_direct "$USERNAME_ONE" "$PASSWORD_ONE" "admin" "$BUCKET_ONE_NAME" + assert_success + username=${lines[0]} + password=${lines[1]} run create_test_file "$test_file" assert_success @@ -122,30 +141,30 @@ export RUN_USERS=true run setup_bucket "s3api" "$BUCKET_ONE_NAME" assert_success - put_object_with_user "s3api" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" "$username" "$password" || fail "failed to add object to bucket" - get_object_with_user "s3api" "$BUCKET_ONE_NAME" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy" "$username" "$password" || fail "error getting object" - compare_files "$TEST_FILE_FOLDER/$test_file" "$TEST_FILE_FOLDER/$test_file-copy" || fail "files don't match" - list_object_versions "$BUCKET_ONE_NAME" - log 5 "versions: $versions" + run put_object_with_user "s3api" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file" "$username" "$password" + assert_success + + run get_object_with_user "s3api" "$BUCKET_ONE_NAME" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy" "$username" "$password" + assert_success + + run compare_files "$TEST_FILE_FOLDER/$test_file" "$TEST_FILE_FOLDER/$test_file-copy" + assert_success + run delete_object_with_user "s3api" "$BUCKET_ONE_NAME" "$test_file" "$username" "$password" assert_success - list_object_versions "$BUCKET_ONE_NAME" - log 5 "versions: $versions" - if get_object "s3api" "$BUCKET_ONE_NAME" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy"; then - fail "file not successfully deleted" - fi - # shellcheck disable=SC2154 - [[ "$get_object_error" == *"NoSuchKey"* ]] || fail "unexpected error message: $get_object_error" - bucket_cleanup "s3api" "$BUCKET_ONE_NAME" - delete_test_files "$test_file" "$test_file-copy" + + run get_object "s3api" "$BUCKET_ONE_NAME" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy" + assert_failure + assert_output -p "NoSuchKey" } @test "test_user_create_multipart_upload" { - username="$USERNAME_ONE" - password="$PASSWORD_ONE" test_file="test_file" - setup_user "$username" "$password" "user" || fail "error creating user if nonexistent" + run setup_user_versitygw_or_direct "$USERNAME_TWO" "$PASSWORD_TWO" "user" "$BUCKET_ONE_NAME" + assert_success + username=${lines[0]} + password=${lines[1]} run create_large_file "$test_file" assert_success @@ -153,6 +172,12 @@ export RUN_USERS=true run setup_bucket "s3api" "$BUCKET_ONE_NAME" assert_success - change_bucket_owner "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY" "$BUCKET_ONE_NAME" "$username" || fail "error changing bucket ownership" - create_multipart_upload_with_user "$BUCKET_ONE_NAME" "dummy" "$username" "$password" || fail "unable to create multipart upload" + run create_multipart_upload_with_user "$BUCKET_ONE_NAME" "dummy" "$username" "$password" + assert_failure + + run change_bucket_owner "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY" "$BUCKET_ONE_NAME" "$username" + assert_success + + run create_multipart_upload_with_user "$BUCKET_ONE_NAME" "dummy" "$username" "$password" + assert_success } diff --git a/tests/util/util_create_bucket.sh b/tests/util/util_create_bucket.sh index 7bd87b37..ac82dc31 100644 --- a/tests/util/util_create_bucket.sh +++ b/tests/util/util_create_bucket.sh @@ -39,7 +39,7 @@ create_bucket_invalid_name() { log 2 "error: bucket should have not been created but was" return 1 fi - export bucket_create_error + echo "$bucket_create_error" } create_and_check_bucket_invalid_name() { diff --git a/tests/util/util_delete_object.sh b/tests/util/util_delete_object.sh new file mode 100644 index 00000000..2948eb56 --- /dev/null +++ b/tests/util/util_delete_object.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +block_delete_object_without_permission() { + if [ $# -ne 4 ]; then + log 2 "'attempt_delete_object_without_permission' requires bucket, file, username, password" + return 1 + fi + if delete_object_with_user "s3api" "$1" "$2" "$3" "$4"; then + log 2 "able to delete object despite lack of permissions" + return 1 + fi + # shellcheck disable=SC2154 + if [[ "$delete_object_error" != *"Access Denied"* ]]; then + log 2 "invalid delete object error: $delete_object_error" + return 1 + fi + return 0 +} \ No newline at end of file diff --git a/tests/util/util_get_object_attributes.sh b/tests/util/util_get_object_attributes.sh index 2490b0c4..1910e402 100644 --- a/tests/util/util_get_object_attributes.sh +++ b/tests/util/util_get_object_attributes.sh @@ -41,4 +41,33 @@ get_and_check_object_size() { return 1 fi return 0 -} \ No newline at end of file +} + +get_object_metadata_and_check_keys() { + if [ $# -ne 4 ]; then + log 2 "'get_object_metadata_and_check_keys' requires bucket, key, expected metadata key, value" + return 1 + fi + if ! get_object_metadata "s3api" "$1" "$2"; then + log 2 "error getting object metadata" + return 1 + fi + # shellcheck disable=SC2154 + if ! key=$(echo "$metadata" | jq -r 'keys[]' 2>&1); then + log 2 "error getting key from metadata: $key" + return 1 + fi + if ! value=$(echo "$metadata" | jq -r '.[]' 2>&1); then + log 2 "error getting value from metadata: $value" + return 1 + fi + if [[ $key != "$3" ]]; then + log 2 "keys doesn't match (expected '$3', actual '$key')" + return 1 + fi + if [[ $value != "$4" ]]; then + log 2 "values doesn't match (expected '$4', actual '$value')" + return 1 + fi + return 0 +} diff --git a/tests/util/util_head_bucket.sh b/tests/util/util_head_bucket.sh index 0e280e46..c6ee28d3 100644 --- a/tests/util/util_head_bucket.sh +++ b/tests/util/util_head_bucket.sh @@ -15,4 +15,16 @@ bucket_info_contains_bucket() { return 1 fi return 0 +} + +bucket_info_without_bucket() { + if head_bucket "s3api" "$BUCKET_ONE_NAME"; then + log 2 "able to get bucket info for non-existent bucket" + return 1 + fi + if [[ $bucket_info != *"404"* ]]; then + log 2 "404 not returned for non-existent bucket info" + return 1 + fi + return 0 } \ No newline at end of file diff --git a/tests/util/util_multipart.sh b/tests/util/util_multipart.sh index 19cc3380..dcf87fd6 100644 --- a/tests/util/util_multipart.sh +++ b/tests/util/util_multipart.sh @@ -679,3 +679,42 @@ run_and_verify_multipart_upload_with_valid_range() { fi return 0 } + +check_abort_access_denied() { + if [ $# -ne 5 ]; then + log 2 "'check_abort_access_denied' requires bucket, file, username, password" + return 1 + fi + if abort_multipart_upload_with_user "$1" "$2" "$3" "$4" "$5"; then + log 2 "abort multipart upload succeeded despite lack of permissions" + return 1 + fi + # shellcheck disable=SC2154 + if [[ "$abort_multipart_upload_error" != *"AccessDenied"* ]]; then + log 2 "unexpected abort error: $abort_multipart_upload_error" + return 1 + fi + return 0 +} + +list_check_multipart_upload_key() { + if [ $# -ne 4 ]; then + log 2 "'list_check_multipart_upload_key' requires bucket, username, password, expected key" + return 1 + fi + if ! list_multipart_uploads_with_user "$1" "$2" "$3"; then + log 2 "error listing multipart uploads with user" + return 1 + fi + # shellcheck disable=SC2154 + log 5 "$uploads" + if ! upload_key=$(echo "$uploads" | grep -v "InsecureRequestWarning" | jq -r ".Uploads[0].Key" 2>&1); then + log 2 "error parsing upload key from uploads message: $upload_key" + return 1 + fi + if [[ "$4" != "$upload_key" ]]; then + log 2 "upload key doesn't match file marked as being uploaded (expected: '$4', actual: '$upload_key')" + return 1 + fi + return 0 +} diff --git a/tests/util/util_policy.sh b/tests/util/util_policy.sh index 7d9d834c..af1130a3 100644 --- a/tests/util/util_policy.sh +++ b/tests/util/util_policy.sh @@ -45,16 +45,33 @@ check_for_empty_policy() { get_modified_principal() { log 6 "get_modified_principal" if [ $# -ne 1 ]; then - log 2 "'get_modified_principal' requires principal" - return 1 - fi - local first_char="${1:0:1}" - if [ "$first_char" != '{' ] && [ "$first_char" != '[' ] && [ "$first_char" != '"' ]; then - # shellcheck disable=SC2089 - modified_principal="\"$1\"" - else - modified_principal=$1 + log 2 "'get_modified_principal' requires principal string" + return 1 + fi + IFS=',' read -r -a principals <<< "$1" + modified_principal="" + if [ "${#principals[@]}" -gt 1 ]; then + modified_principal="[" + fi + for ((idx=0; idx<${#principals[@]}; idx++)); do + if [ "$DIRECT" == "true" ]; then + if [ "${principals[$idx]}" == "*" ]; then + modified_principal+="{\"AWS\": \"arn:aws:iam::$DIRECT_AWS_USER_ID:user/$DIRECT_S3_ROOT_ACCOUNT_NAME\"}" + else + modified_principal+="{\"AWS\": \"arn:aws:iam::$DIRECT_AWS_USER_ID:user/${principals[$idx]}\"}" + fi + else + # shellcheck disable=SC2089 + modified_principal+="\"${principals[$idx]}\"" + fi + if [[ ( "${#principals[@]}" -gt 1 ) && ( $idx -lt ${#principals[@]}-1 ) ]]; then + modified_principal+="," + fi + done + if [ "${#principals[@]}" -gt 1 ]; then + modified_principal+="]" fi + log 5 "modified principal: $modified_principal" } get_modified_action() { @@ -89,19 +106,17 @@ setup_policy_with_single_statement() { log 2 "error getting modified action" return 1 fi - bash -c "cat < $1 -{ - \"Version\": \"$2\", - \"Statement\": [ + printf '{ + "Version": "%s", + "Statement": [ { - \"Effect\": \"$3\", - \"Principal\": $modified_principal, - \"Action\": $modified_action, - \"Resource\": \"$6\" + "Effect": "%s", + "Principal": %s, + "Action": %s, + "Resource": "%s" } ] -} -EOF" +}' "$2" "$3" "$modified_principal" "$modified_action" "$6" > "$1" # shellcheck disable=SC2154 #assert_success "failed to set up policy: $output" log 5 "policy data: $(cat "$1")" @@ -160,7 +175,20 @@ get_and_check_policy() { # shellcheck disable=SC2154 log 5 "POLICY: $bucket_policy" - if ! statement=$(echo "$bucket_policy" | jq -r '.Statement[0]' 2>&1); then + if ! check_policy "$bucket_policy" "$3" "$4" "$5" "$6"; then + log 2 "error checking policy" + return 1 + fi + return 0 +} + +check_policy() { + if [ $# -ne 5 ]; then + log 2 "'check_policy' requires policy, expected effect, policy, action, resource" + return 1 + fi + log 5 "policy: $1" + if ! statement=$(echo -n "$1" | jq -r '.Statement[0]' 2>&1); then log 2 "error getting statement value: $statement" return 1 fi @@ -168,8 +196,8 @@ get_and_check_policy() { log 2 "error getting effect: $returned_effect" return 1 fi - if [[ "$3" != "$returned_effect" ]]; then - log 2 "effect mismatch ($3, $returned_effect)" + if [[ "$2" != "$returned_effect" ]]; then + log 2 "effect mismatch (expected '$2', actual '$returned_effect')" return 1 fi if ! returned_principal=$(echo "$statement" | jq -r '.Principal' 2>&1); then @@ -177,13 +205,13 @@ get_and_check_policy() { return 1 fi if [[ -n $DIRECT ]] && arn=$(echo "$returned_principal" | jq -r '.AWS' 2>&1); then - if [[ $arn != "arn:aws:iam::$DIRECT_AWS_USER_ID:user/s3user" ]]; then - log 2 "arn mismatch" + if [[ $arn != "$3" ]]; then + log 2 "arn mismatch (expected '$3', actual '$arn')" return 1 fi else - if [[ "$4" != "\"$returned_principal\"" ]]; then - log 2 "principal mismatch ($4, $returned_principal)" + if [[ "$3" != "$returned_principal" ]]; then + log 2 "principal mismatch (expected '$3', actual '$returned_principal')" return 1 fi fi @@ -191,19 +219,19 @@ get_and_check_policy() { log 2 "error getting action: $returned_action" return 1 fi - if [[ "$5" != "$returned_action" ]]; then - log 2 "action mismatch ($5, $returned_action)" + if [[ "$4" != "$returned_action" ]]; then + log 2 "action mismatch (expected '$4', actual '$returned_action')" return 1 fi if ! returned_resource=$(echo "$statement" | jq -r '.Resource' 2>&1); then log 2 "error getting resource: $returned_resource" return 1 fi - if [[ "$6" != "$returned_resource" ]]; then - log 2 "resource mismatch ($6, $returned_resource)" + if [[ "$5" != "$returned_resource" ]]; then + log 2 "resource mismatch (expected '$5', actual '$returned_resource')" return 1 fi - return 0 + return 0 } put_and_check_for_malformed_policy() { @@ -250,7 +278,7 @@ get_and_check_no_policy_error() { get_and_compare_policy_with_file() { if [ $# -ne 4 ]; then - log 2 "'get_and_compare_policies' reuires bucket, username, password, filename" + log 2 "'get_and_compare_policies' requires bucket, username, password, filename" return 1 fi if ! get_bucket_policy_with_user "$1" "$2" "$3"; then @@ -258,7 +286,7 @@ get_and_compare_policy_with_file() { return 1 fi # shellcheck disable=SC2154 - echo "$bucket_policy" > "$4-copy" + echo -n "$bucket_policy" > "$4-copy" log 5 "ORIG: $(cat "$4")" log 5 "COPY: $(cat "$4-copy")" if ! compare_files "$4" "$4-copy"; then @@ -267,3 +295,39 @@ get_and_compare_policy_with_file() { fi return 0 } + +put_and_check_policy_rest() { + if [ $# -ne 6 ]; then + log 2 "'put_policy_rest' requires bucket name, policy file, effect, principal, action, resource" + return 1 + fi + if ! result=$(COMMAND_LOG="$COMMAND_LOG" BUCKET_NAME="$1" POLICY_FILE="$2" OUTPUT_FILE="$TEST_FILE_FOLDER/result.txt" ./tests/rest_scripts/put_bucket_policy.sh); then + log 2 "error putting policy: $result" + return 1 + fi + log 5 "response code: $result" + if [[ ( "$result" != "204" ) && ( "$result" != "200" ) ]]; then + log 2 "unexpected response code, expected '200' or '204', actual '$result' (reply: $(cat "$TEST_FILE_FOLDER/result.txt"))" + return 1 + fi + log 5 "response: $(cat "$TEST_FILE_FOLDER/result.txt")" + if ! result=$(COMMAND_LOG="$COMMAND_LOG" BUCKET_NAME="$1" OUTPUT_FILE="$TEST_FILE_FOLDER/policy.txt" ./tests/rest_scripts/get_bucket_policy.sh); then + log 2 "error attempting to get bucket policy response: $result" + return 1 + fi + if [ "$result" != "200" ]; then + log 2 "unexpected response code, expected '200', actual '$result' (reply: $(cat "$TEST_FILE_FOLDER/policy.txt"))" + return 1 + fi + log 5 "policy: $(cat "$TEST_FILE_FOLDER/policy.txt")" + if [ "$DIRECT" == "true" ]; then + principal="arn:aws:iam::$DIRECT_AWS_USER_ID:user/$4" + else + principal="$4" + fi + if ! check_policy "$(cat "$TEST_FILE_FOLDER/policy.txt")" "$3" "$principal" "$5" "$6"; then + log 2 "policies not equal" + return 1 + fi + return 0 +} diff --git a/tests/util/util_users.sh b/tests/util/util_users.sh index b9331d43..5f3734ac 100644 --- a/tests/util/util_users.sh +++ b/tests/util/util_users.sh @@ -53,6 +53,30 @@ setup_user_direct() { return 0 } +setup_user_versitygw_or_direct() { + if [ $# -ne 4 ]; then + # NOTE: bucket name is required for direct + log 2 "'setup_user_versitygw_or_direct' requires username, password, role, bucket name" + return 1 + fi + if [ "$DIRECT" != "true" ]; then + if ! setup_user "$1" "$2" "$3"; then + log 2 "error setting up versitygw user" + return 1 + fi + echo "$1" + echo "$2" + else + if ! setup_user_direct "$1" "$3" "$4"; then + log 2 "error setting up direct user" + return 1 + fi + echo "$key_id" + echo "$secret_key" + fi + return 0 +} + create_user_versitygw() { log 6 "create_user_versitygw" if [[ $# -ne 3 ]]; then @@ -117,7 +141,7 @@ put_user_policy_userplus() { ] } EOF - if ! error=$(send_command aws iam put-user-policy --user-name "$1" --policy-name "UserPolicy" --policy-document "file://$TEST_FILE_FOLDER/user_policy_file" 2>&1); then + 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 @@ -154,7 +178,7 @@ create_user_direct() { log 2 "create user direct command requires desired username, role, bucket name" return 1 fi - if ! error=$(send_command aws iam create-user --user-name "$1" 2>&1); then + if ! error=$(send_command aws --endpoint-url=https://iam.amazonaws.com iam create-user --user-name "$1" 2>&1); then log 2 "error creating new user: $error" return 1 fi @@ -162,7 +186,7 @@ create_user_direct() { log 2 "error attaching user policy" return 1 fi - if ! keys=$(send_command aws iam create-access-key --user-name "$1" 2>&1); then + if ! keys=$(send_command aws --endpoint-url=https://iam.amazonaws.com iam create-access-key --user-name "$1" 2>&1); then log 2 "error creating keys for new user: $keys" return 1 fi @@ -193,7 +217,7 @@ create_user_with_user() { list_users_direct() { log 6 "list_users_direct" # AWS_ENDPOINT_URL of s3.amazonaws.com doesn't work here - if ! users=$(send_command aws --profile="$AWS_PROFILE" iam list-users 2>&1); then + if ! users=$(send_command aws --profile="$AWS_PROFILE" --endpoint-url=https://iam.amazonaws.com iam list-users 2>&1); then log 2 "error listing users via direct s3 call: $users" return 1 fi @@ -266,17 +290,17 @@ delete_user_direct() { log 2 "delete user direct command requires username" return 1 fi - if ! policies=$(send_command aws iam list-user-policies --user-name "$1" --query 'PolicyNames' --output text 2>&1); then + if ! policies=$(send_command aws --endpoint-url=https://iam.amazonaws.com iam list-user-policies --user-name "$1" --query 'PolicyNames' --output text 2>&1); then log 2 "error getting user policies: $error" return 1 fi for policy_name in $policies; do - if ! user_policy_delete_error=$(send_command aws iam delete-user-policy --user-name "$1" --policy-name "$policy_name" 2>&1); then + if ! user_policy_delete_error=$(send_command aws --endpoint-url=https://iam.amazonaws.com iam delete-user-policy --user-name "$1" --policy-name "$policy_name" 2>&1); then log 2 "error deleting user policy: $user_policy_delete_error" return 1 fi done - if ! keys=$(send_command aws iam list-access-keys --user-name "$1" 2>&1); then + if ! keys=$(send_command aws --endpoint-url=https://iam.amazonaws.com iam list-access-keys --user-name "$1" 2>&1); then log 2 "error getting keys: $keys" return 1 fi @@ -285,12 +309,12 @@ delete_user_direct() { return 1 fi if [[ $key != "null" ]]; then - if ! error=$(send_command aws iam delete-access-key --user-name "$1" --access-key-id "$key" 2>&1); then + if ! error=$(send_command aws --endpoint-url=https://iam.amazonaws.com iam delete-access-key --user-name "$1" --access-key-id "$key" 2>&1); then log 2 "error deleting access key: $error" return 1 fi fi - if ! error=$(send_command aws --profile="$AWS_PROFILE" iam delete-user --user-name "$1" 2>&1); then + if ! error=$(send_command aws --endpoint-url=https://iam.amazonaws.com --profile="$AWS_PROFILE" iam delete-user --user-name "$1" 2>&1); then log 2 "error deleting user: $error" return 1 fi