...

Source file src/cloud.google.com/go/auth/credentials/downscope/integration_test.go

Documentation: cloud.google.com/go/auth/credentials/downscope

     1  // Copyright 2023 Google LLC
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package downscope_test
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  	"io"
    21  	"os"
    22  	"testing"
    23  	"time"
    24  
    25  	"cloud.google.com/go/auth"
    26  	"cloud.google.com/go/auth/credentials"
    27  	"cloud.google.com/go/auth/credentials/downscope"
    28  	"cloud.google.com/go/auth/internal/credsfile"
    29  	"cloud.google.com/go/auth/internal/testutil"
    30  	"cloud.google.com/go/auth/internal/testutil/testgcs"
    31  )
    32  
    33  const (
    34  	rootTokenScope = "https://www.googleapis.com/auth/cloud-platform"
    35  	object1        = "cab-first-c45wknuy.txt"
    36  	object2        = "cab-second-c45wknuy.txt"
    37  	bucket         = "dulcet-port-762"
    38  )
    39  
    40  func TestDownscopedToken(t *testing.T) {
    41  	testutil.IntegrationTestCheck(t)
    42  	creds, err := credentials.DetectDefault(&credentials.DetectOptions{
    43  		CredentialsFile: os.Getenv(credsfile.GoogleAppCredsEnvVar),
    44  		Scopes:          []string{rootTokenScope},
    45  	})
    46  	if err != nil {
    47  		t.Fatalf("DefaultCredentials() = %v", err)
    48  	}
    49  
    50  	var downscopeTests = []struct {
    51  		name        string
    52  		rule        downscope.AccessBoundaryRule
    53  		objectName  string
    54  		expectError bool
    55  	}{
    56  		{
    57  			name: "successfulDownscopedRead",
    58  			rule: downscope.AccessBoundaryRule{
    59  				AvailableResource:    "//storage.googleapis.com/projects/_/buckets/" + bucket,
    60  				AvailablePermissions: []string{"inRole:roles/storage.objectViewer"},
    61  				Condition: &downscope.AvailabilityCondition{
    62  					Expression: "resource.name.startsWith('projects/_/buckets/" + bucket + "/objects/" + object1 + "')",
    63  				},
    64  			},
    65  			objectName:  object1,
    66  			expectError: false,
    67  		},
    68  		{
    69  			name: "readWithoutPermission",
    70  			rule: downscope.AccessBoundaryRule{
    71  				AvailableResource:    "//storage.googleapis.com/projects/_/buckets/" + bucket,
    72  				AvailablePermissions: []string{"inRole:roles/storage.objectViewer"},
    73  				Condition: &downscope.AvailabilityCondition{
    74  					Expression: "resource.name.startsWith('projects/_/buckets/" + bucket + "/objects/" + object1 + "')",
    75  				},
    76  			},
    77  			objectName:  object2,
    78  			expectError: true,
    79  		},
    80  	}
    81  
    82  	for _, tt := range downscopeTests {
    83  		t.Run(tt.name, func(t *testing.T) {
    84  			err := testDownscopedToken(t, tt.rule, tt.objectName, creds)
    85  			if !tt.expectError && err != nil {
    86  				t.Errorf("test case %v should have succeeded, but instead returned %v", tt.name, err)
    87  			} else if tt.expectError && err == nil {
    88  				t.Errorf(" test case %v should have returned an error, but instead returned nil", tt.name)
    89  			}
    90  		})
    91  	}
    92  }
    93  
    94  func testDownscopedToken(t *testing.T, rule downscope.AccessBoundaryRule, objectName string, creds *auth.Credentials) error {
    95  	t.Helper()
    96  	ctx := context.Background()
    97  	creds, err := downscope.NewCredentials(&downscope.Options{Credentials: creds, Rules: []downscope.AccessBoundaryRule{rule}})
    98  	if err != nil {
    99  		return fmt.Errorf("downscope.NewCredentials() = %v", err)
   100  	}
   101  
   102  	ctx, cancel := context.WithTimeout(ctx, time.Second*30)
   103  	defer cancel()
   104  	client := testgcs.NewClient(creds)
   105  	resp, err := client.DownloadObject(ctx, bucket, objectName)
   106  	if err != nil {
   107  		return err
   108  	}
   109  	defer resp.Body.Close()
   110  	_, err = io.ReadAll(resp.Body)
   111  	if err != nil {
   112  		return err
   113  	}
   114  	return nil
   115  }
   116  

View as plain text