@@ -1444,78 +1444,264 @@ func TestACL_filterNodeDump(t *testing.T) {
14441444 },
14451445 },
14461446 },
1447+ ImportedDump : structs.NodeDump {
1448+ {
1449+ // The node and service names are intentionally the same to ensure that
1450+ // local permissions for the same names do not allow reading imports.
1451+ Node : "node1" ,
1452+ PeerName : "cluster-02" ,
1453+ Services : []* structs.NodeService {
1454+ {
1455+ ID : "foo" ,
1456+ Service : "foo" ,
1457+ PeerName : "cluster-02" ,
1458+ },
1459+ },
1460+ Checks : []* structs.HealthCheck {
1461+ {
1462+ Node : "node1" ,
1463+ CheckID : "check1" ,
1464+ ServiceName : "foo" ,
1465+ PeerName : "cluster-02" ,
1466+ },
1467+ },
1468+ },
1469+ },
14471470 }
14481471 }
1472+ type testCase struct {
1473+ authzFn func () acl.Authorizer
1474+ expect * structs.IndexedNodeDump
1475+ }
14491476
1450- t .Run ("allowed" , func (t * testing.T ) {
1477+ run := func (t * testing.T , tc testCase ) {
1478+ authz := tc .authzFn ()
14511479
1452- policy , err := acl .NewPolicyFromSource (`
1480+ list := makeList ()
1481+ New (authz , logger ).Filter (list )
1482+
1483+ require .Equal (t , tc .expect , list )
1484+ }
1485+
1486+ tt := map [string ]testCase {
1487+ "denied" : {
1488+ authzFn : func () acl.Authorizer {
1489+ return acl .DenyAll ()
1490+ },
1491+ expect : & structs.IndexedNodeDump {
1492+ Dump : structs.NodeDump {},
1493+ ImportedDump : structs.NodeDump {},
1494+ QueryMeta : structs.QueryMeta {ResultsFilteredByACLs : true },
1495+ },
1496+ },
1497+ "can read local service but not the node" : {
1498+ authzFn : func () acl.Authorizer {
1499+ policy , err := acl .NewPolicyFromSource (`
14531500 service "foo" {
14541501 policy = "read"
14551502 }
1503+ ` , acl .SyntaxLegacy , nil , nil )
1504+ require .NoError (t , err )
1505+
1506+ authz , err := acl .NewPolicyAuthorizerWithDefaults (acl .DenyAll (), []* acl.Policy {policy }, nil )
1507+ require .NoError (t , err )
1508+
1509+ return authz
1510+ },
1511+ expect : & structs.IndexedNodeDump {
1512+ Dump : structs.NodeDump {},
1513+ ImportedDump : structs.NodeDump {},
1514+ QueryMeta : structs.QueryMeta {ResultsFilteredByACLs : true },
1515+ },
1516+ },
1517+ "can read the local node but not the service" : {
1518+ authzFn : func () acl.Authorizer {
1519+ policy , err := acl .NewPolicyFromSource (`
14561520 node "node1" {
14571521 policy = "read"
14581522 }
14591523 ` , acl .SyntaxLegacy , nil , nil )
1460- require .NoError (t , err )
1461-
1462- authz , err := acl .NewPolicyAuthorizerWithDefaults (acl .DenyAll (), []* acl.Policy {policy }, nil )
1463- require .NoError (t , err )
1464-
1465- list := makeList ()
1466- New (authz , logger ).Filter (list )
1467-
1468- require .Len (t , list .Dump , 1 )
1469- require .False (t , list .QueryMeta .ResultsFilteredByACLs , "ResultsFilteredByACLs should be false" )
1470- })
1524+ require .NoError (t , err )
14711525
1472- t .Run ("allowed to read the service, but not the node" , func (t * testing.T ) {
1526+ authz , err := acl .NewPolicyAuthorizerWithDefaults (acl .DenyAll (), []* acl.Policy {policy }, nil )
1527+ require .NoError (t , err )
14731528
1474- policy , err := acl .NewPolicyFromSource (`
1529+ return authz
1530+ },
1531+ expect : & structs.IndexedNodeDump {
1532+ Dump : structs.NodeDump {
1533+ {
1534+ Node : "node1" ,
1535+ Services : []* structs.NodeService {},
1536+ Checks : structs.HealthChecks {},
1537+ },
1538+ },
1539+ ImportedDump : structs.NodeDump {},
1540+ QueryMeta : structs.QueryMeta {ResultsFilteredByACLs : true },
1541+ },
1542+ },
1543+ "can read local data" : {
1544+ authzFn : func () acl.Authorizer {
1545+ policy , err := acl .NewPolicyFromSource (`
14751546 service "foo" {
14761547 policy = "read"
14771548 }
1549+ node "node1" {
1550+ policy = "read"
1551+ }
14781552 ` , acl .SyntaxLegacy , nil , nil )
1479- require .NoError (t , err )
1480-
1481- authz , err := acl .NewPolicyAuthorizerWithDefaults (acl .DenyAll (), []* acl.Policy {policy }, nil )
1482- require .NoError (t , err )
1553+ require .NoError (t , err )
14831554
1484- list := makeList ( )
1485- New ( authz , logger ). Filter ( list )
1555+ authz , err := acl . NewPolicyAuthorizerWithDefaults ( acl . DenyAll (), [] * acl. Policy { policy }, nil )
1556+ require . NoError ( t , err )
14861557
1487- require .Empty (t , list .Dump )
1488- require .True (t , list .QueryMeta .ResultsFilteredByACLs , "ResultsFilteredByACLs should be true" )
1489- })
1558+ return authz
1559+ },
1560+ expect : & structs.IndexedNodeDump {
1561+ Dump : structs.NodeDump {
1562+ {
1563+ Node : "node1" ,
1564+ Services : []* structs.NodeService {
1565+ {
1566+ ID : "foo" ,
1567+ Service : "foo" ,
1568+ },
1569+ },
1570+ Checks : []* structs.HealthCheck {
1571+ {
1572+ Node : "node1" ,
1573+ CheckID : "check1" ,
1574+ ServiceName : "foo" ,
1575+ },
1576+ },
1577+ },
1578+ },
1579+ ImportedDump : structs.NodeDump {},
1580+ QueryMeta : structs.QueryMeta {ResultsFilteredByACLs : true },
1581+ },
1582+ },
1583+ "can read imported service but not the node" : {
1584+ authzFn : func () acl.Authorizer {
1585+ // Wildcard service read also grants read to imported services.
1586+ policy , err := acl .NewPolicyFromSource (`
1587+ service "" {
1588+ policy = "read"
1589+ }
1590+ ` , acl .SyntaxLegacy , nil , nil )
1591+ require .NoError (t , err )
14901592
1491- t .Run ("allowed to read the node, but not the service" , func (t * testing.T ) {
1593+ authz , err := acl .NewPolicyAuthorizerWithDefaults (acl .DenyAll (), []* acl.Policy {policy }, nil )
1594+ require .NoError (t , err )
14921595
1493- policy , err := acl .NewPolicyFromSource (`
1494- node "node1" {
1596+ return authz
1597+ },
1598+ expect : & structs.IndexedNodeDump {
1599+ Dump : structs.NodeDump {},
1600+ ImportedDump : structs.NodeDump {},
1601+ QueryMeta : structs.QueryMeta {ResultsFilteredByACLs : true },
1602+ },
1603+ },
1604+ "can read the imported node but not the service" : {
1605+ authzFn : func () acl.Authorizer {
1606+ // Wildcard node read also grants read to imported nodes.
1607+ policy , err := acl .NewPolicyFromSource (`
1608+ node "" {
14951609 policy = "read"
14961610 }
14971611 ` , acl .SyntaxLegacy , nil , nil )
1498- require .NoError (t , err )
1499-
1500- authz , err := acl .NewPolicyAuthorizerWithDefaults (acl .DenyAll (), []* acl.Policy {policy }, nil )
1501- require .NoError (t , err )
1612+ require .NoError (t , err )
15021613
1503- list := makeList ( )
1504- New ( authz , logger ). Filter ( list )
1614+ authz , err := acl . NewPolicyAuthorizerWithDefaults ( acl . DenyAll (), [] * acl. Policy { policy }, nil )
1615+ require . NoError ( t , err )
15051616
1506- require .Len (t , list .Dump , 1 )
1507- require .Empty (t , list .Dump [0 ].Services )
1508- require .True (t , list .QueryMeta .ResultsFilteredByACLs , "ResultsFilteredByACLs should be true" )
1509- })
1617+ return authz
1618+ },
1619+ expect : & structs.IndexedNodeDump {
1620+ Dump : structs.NodeDump {
1621+ {
1622+ Node : "node1" ,
1623+ Services : []* structs.NodeService {},
1624+ Checks : structs.HealthChecks {},
1625+ },
1626+ },
1627+ ImportedDump : structs.NodeDump {
1628+ {
1629+ Node : "node1" ,
1630+ PeerName : "cluster-02" ,
1631+ Services : []* structs.NodeService {},
1632+ Checks : structs.HealthChecks {},
1633+ },
1634+ },
1635+ QueryMeta : structs.QueryMeta {ResultsFilteredByACLs : true },
1636+ },
1637+ },
1638+ "can read all data" : {
1639+ authzFn : func () acl.Authorizer {
1640+ policy , err := acl .NewPolicyFromSource (`
1641+ service "" {
1642+ policy = "read"
1643+ }
1644+ node "" {
1645+ policy = "read"
1646+ }
1647+ ` , acl .SyntaxLegacy , nil , nil )
1648+ require .NoError (t , err )
15101649
1511- t .Run ("denied" , func (t * testing.T ) {
1650+ authz , err := acl .NewPolicyAuthorizerWithDefaults (acl .DenyAll (), []* acl.Policy {policy }, nil )
1651+ require .NoError (t , err )
15121652
1513- list := makeList ()
1514- New (acl .DenyAll (), logger ).Filter (list )
1653+ return authz
1654+ },
1655+ expect : & structs.IndexedNodeDump {
1656+ Dump : structs.NodeDump {
1657+ {
1658+ Node : "node1" ,
1659+ Services : []* structs.NodeService {
1660+ {
1661+ ID : "foo" ,
1662+ Service : "foo" ,
1663+ },
1664+ },
1665+ Checks : []* structs.HealthCheck {
1666+ {
1667+ Node : "node1" ,
1668+ CheckID : "check1" ,
1669+ ServiceName : "foo" ,
1670+ },
1671+ },
1672+ },
1673+ },
1674+ ImportedDump : structs.NodeDump {
1675+ {
1676+ Node : "node1" ,
1677+ PeerName : "cluster-02" ,
1678+ Services : []* structs.NodeService {
1679+ {
1680+ ID : "foo" ,
1681+ Service : "foo" ,
1682+ PeerName : "cluster-02" ,
1683+ },
1684+ },
1685+ Checks : []* structs.HealthCheck {
1686+ {
1687+ Node : "node1" ,
1688+ CheckID : "check1" ,
1689+ ServiceName : "foo" ,
1690+ PeerName : "cluster-02" ,
1691+ },
1692+ },
1693+ },
1694+ },
1695+ QueryMeta : structs.QueryMeta {ResultsFilteredByACLs : false },
1696+ },
1697+ },
1698+ }
15151699
1516- require .Empty (t , list .Dump )
1517- require .True (t , list .QueryMeta .ResultsFilteredByACLs , "ResultsFilteredByACLs should be true" )
1518- })
1700+ for name , tc := range tt {
1701+ t .Run (name , func (t * testing.T ) {
1702+ run (t , tc )
1703+ })
1704+ }
15191705}
15201706
15211707func TestACL_filterNodes (t * testing.T ) {
0 commit comments