go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/server/auth/state_test.go (about)

     1  // Copyright 2015 The LUCI Authors.
     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 auth
    16  
    17  import (
    18  	"context"
    19  	"net"
    20  	"testing"
    21  
    22  	"go.chromium.org/luci/auth/identity"
    23  
    24  	"go.chromium.org/luci/server/auth/service/protocol"
    25  	"go.chromium.org/luci/server/auth/signing"
    26  	"go.chromium.org/luci/server/auth/signing/signingtest"
    27  
    28  	. "github.com/smartystreets/goconvey/convey"
    29  )
    30  
    31  func TestState(t *testing.T) {
    32  	t.Parallel()
    33  
    34  	Convey("Check empty ctx", t, func() {
    35  		ctx := context.Background()
    36  		So(GetState(ctx), ShouldBeNil)
    37  		So(CurrentUser(ctx).Identity, ShouldEqual, identity.AnonymousIdentity)
    38  		So(CurrentIdentity(ctx), ShouldEqual, identity.AnonymousIdentity)
    39  
    40  		res, err := IsMember(ctx, "group")
    41  		So(res, ShouldBeFalse)
    42  		So(err, ShouldEqual, ErrNotConfigured)
    43  
    44  		res, err = IsAllowedIP(ctx, "bots")
    45  		So(res, ShouldBeFalse)
    46  		So(err, ShouldEqual, ErrNotConfigured)
    47  	})
    48  
    49  	Convey("Check non-empty ctx", t, func() {
    50  		s := state{
    51  			db: &fakeDB{
    52  				groups: map[string][]identity.Identity{
    53  					"group": {"user:abc@example.com"},
    54  				},
    55  			},
    56  			user:      &User{Identity: "user:abc@example.com"},
    57  			peerIdent: "user:abc@example.com",
    58  			peerIP:    net.IP{1, 2, 3, 4},
    59  		}
    60  		ctx := context.WithValue(context.Background(), stateContextKey(0), &s)
    61  		So(GetState(ctx), ShouldNotBeNil)
    62  		So(GetState(ctx).Method(), ShouldBeNil)
    63  		So(GetState(ctx).PeerIdentity(), ShouldEqual, identity.Identity("user:abc@example.com"))
    64  		So(GetState(ctx).PeerIP().String(), ShouldEqual, "1.2.3.4")
    65  		So(CurrentUser(ctx).Identity, ShouldEqual, identity.Identity("user:abc@example.com"))
    66  		So(CurrentIdentity(ctx), ShouldEqual, identity.Identity("user:abc@example.com"))
    67  
    68  		res, err := IsMember(ctx, "group")
    69  		So(err, ShouldBeNil)
    70  		So(res, ShouldBeTrue)
    71  
    72  		res, err = IsAllowedIP(ctx, "bots")
    73  		So(err, ShouldBeNil)
    74  		So(res, ShouldBeTrue) // fakeDB contains the list "bots" with member "1.2.3.4"
    75  	})
    76  
    77  	Convey("Check background ctx", t, func() {
    78  		ctx := injectTestDB(context.Background(), &fakeDB{
    79  			authServiceURL: "https://example.com/auth_service",
    80  		})
    81  		url, err := GetState(ctx).DB().GetAuthServiceURL(ctx)
    82  		So(err, ShouldBeNil)
    83  		So(url, ShouldEqual, "https://example.com/auth_service")
    84  	})
    85  
    86  	Convey("ShouldEnforceRealmACL", t, func() {
    87  		ctx := ModifyConfig(context.Background(), func(cfg Config) Config {
    88  			cfg.Signer = signingtest.NewSigner(&signing.ServiceInfo{
    89  				AppID: "my-app-id",
    90  			})
    91  			return cfg
    92  		})
    93  
    94  		ctx = WithState(ctx, &state{
    95  			db: &fakeDB{
    96  				realmData: map[string]*protocol.RealmData{
    97  					"proj:empty": {},
    98  					"proj:yes":   {EnforceInService: []string{"zzz", "my-app-id"}},
    99  					"proj:no":    {EnforceInService: []string{"zzz", "xxx"}},
   100  				},
   101  			},
   102  		})
   103  
   104  		// No data.
   105  		yes, err := ShouldEnforceRealmACL(ctx, "proj:unknown")
   106  		So(err, ShouldBeNil)
   107  		So(yes, ShouldBeFalse)
   108  
   109  		// Empty data.
   110  		yes, err = ShouldEnforceRealmACL(ctx, "proj:empty")
   111  		So(err, ShouldBeNil)
   112  		So(yes, ShouldBeFalse)
   113  
   114  		// In the set.
   115  		yes, err = ShouldEnforceRealmACL(ctx, "proj:yes")
   116  		So(err, ShouldBeNil)
   117  		So(yes, ShouldBeTrue)
   118  
   119  		// Not in the set.
   120  		yes, err = ShouldEnforceRealmACL(ctx, "proj:no")
   121  		So(err, ShouldBeNil)
   122  		So(yes, ShouldBeFalse)
   123  	})
   124  }