go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/auth_service/internal/permissions/permissions_test.go (about)

     1  // Copyright 2023 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  package permissions
    15  
    16  import (
    17  	"fmt"
    18  	"testing"
    19  
    20  	"go.chromium.org/luci/common/data/stringset"
    21  	realmsconf "go.chromium.org/luci/common/proto/realms"
    22  	"go.chromium.org/luci/config"
    23  	protocol "go.chromium.org/luci/server/auth/service/protocol"
    24  
    25  	"go.chromium.org/luci/auth_service/api/configspb"
    26  
    27  	. "github.com/smartystreets/goconvey/convey"
    28  )
    29  
    30  func TestPermissionsDBGeneration(t *testing.T) {
    31  	t.Parallel()
    32  	Convey("testing permissionsDB generation", t, func() {
    33  		attrs := []string{"attr-A", "attr-B"}
    34  		cfg := &configspb.PermissionsConfig{
    35  			Role: []*configspb.PermissionsConfig_Role{
    36  				{
    37  					Name: "role/test.reader",
    38  					Permissions: []*protocol.Permission{
    39  						{
    40  							Name: "test.config.get",
    41  						},
    42  					},
    43  				},
    44  				{
    45  					Name: "role/test.writer",
    46  					Permissions: []*protocol.Permission{
    47  						{
    48  							Name: "test.config.create",
    49  						},
    50  					},
    51  				},
    52  				{
    53  					Name: "role/supertest.writer",
    54  					Permissions: []*protocol.Permission{
    55  						{
    56  							Name: "test.superconfig.create",
    57  						},
    58  					},
    59  					Includes: []string{
    60  						"role/test.writer",
    61  					},
    62  				},
    63  			},
    64  			Attribute: attrs,
    65  		}
    66  		expectedDB := &PermissionsDB{
    67  			Rev: fmt.Sprintf("permissionsDB:%d", 123),
    68  			Permissions: map[string]*protocol.Permission{
    69  				"test.config.get":         {Name: "test.config.get"},
    70  				"test.config.create":      {Name: "test.config.create"},
    71  				"test.superconfig.create": {Name: "test.superconfig.create"},
    72  			},
    73  			Roles: map[string]*Role{
    74  				"role/test.reader": {
    75  					Name: "role/test.reader",
    76  					Permissions: stringset.NewFromSlice(
    77  						"test.config.get",
    78  					),
    79  				},
    80  				"role/test.writer": {
    81  					Name: "role/test.writer",
    82  					Permissions: stringset.NewFromSlice(
    83  						"test.config.create",
    84  					),
    85  				},
    86  				"role/supertest.writer": {
    87  					Name: "role/supertest.writer",
    88  					Permissions: stringset.NewFromSlice(
    89  						"test.superconfig.create",
    90  						"test.config.create",
    91  					),
    92  				},
    93  			},
    94  			attributes: stringset.NewFromSlice(attrs...),
    95  			ImplicitRootBindings: func(projID string) []*realmsconf.Binding {
    96  				return []*realmsconf.Binding{
    97  					{
    98  						Role:       "role/luci.internal.system",
    99  						Principals: []string{fmt.Sprintf("project:%s", projID)},
   100  					},
   101  					{
   102  						Role:       "role/luci.internal.buildbucket.reader",
   103  						Principals: []string{"group:buildbucket-internal-readers"},
   104  					},
   105  					{
   106  						Role:       "role/luci.internal.resultdb.reader",
   107  						Principals: []string{"group:resultdb-internal-readers"},
   108  					},
   109  					{
   110  						Role:       "role/luci.internal.resultdb.invocationSubmittedSetter",
   111  						Principals: []string{"group:resultdb-internal-invocation-submitters"},
   112  					},
   113  				}
   114  			},
   115  		}
   116  
   117  		Convey("succeeds without permissions config", func() {
   118  			db := NewPermissionsDB(nil, nil)
   119  			So(db.Rev, ShouldEqual, "config-without-metadata")
   120  			So(db.Permissions, ShouldBeEmpty)
   121  			So(db.Roles, ShouldBeEmpty)
   122  			So(db.attributes, ShouldBeEmpty)
   123  		})
   124  
   125  		Convey("succeeds without metadata", func() {
   126  			db := NewPermissionsDB(cfg, nil)
   127  			So(db.Rev, ShouldEqual, "config-without-metadata")
   128  			So(db.Permissions, ShouldResemble, expectedDB.Permissions)
   129  			So(db.Roles, ShouldResemble, expectedDB.Roles)
   130  			So(setsAreEqual(db.attributes, expectedDB.attributes), ShouldBeTrue)
   131  		})
   132  
   133  		Convey("has metadata info", func() {
   134  			db := NewPermissionsDB(cfg, &config.Meta{
   135  				Path:     "permissions.cfg",
   136  				Revision: "123",
   137  			})
   138  			So(db.Rev, ShouldEqual, "permissions.cfg:123")
   139  			So(db.Permissions, ShouldResemble, expectedDB.Permissions)
   140  			So(db.Roles, ShouldResemble, expectedDB.Roles)
   141  			So(setsAreEqual(db.attributes, expectedDB.attributes), ShouldBeTrue)
   142  		})
   143  	})
   144  }
   145  
   146  func setsAreEqual(a, b stringset.Set) bool {
   147  	return a.Contains(b) && b.Contains(a)
   148  }