github.imxd.top/hashicorp/consul@v1.4.5/acl/policy_test.go (about)

     1  package acl
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/require"
     8  )
     9  
    10  func errStartsWith(t *testing.T, actual error, expected string) {
    11  	t.Helper()
    12  	require.Error(t, actual)
    13  	require.Truef(t, strings.HasPrefix(actual.Error(), expected), "Received unexpected error: %#v\nExpecting an error with the prefix: %q", actual, expected)
    14  }
    15  
    16  func TestPolicySourceParse(t *testing.T) {
    17  	ljoin := func(lines ...string) string {
    18  		return strings.Join(lines, "\n")
    19  	}
    20  	cases := []struct {
    21  		Name     string
    22  		Syntax   SyntaxVersion
    23  		Rules    string
    24  		Expected *Policy
    25  		Err      string
    26  	}{
    27  		{
    28  			"Legacy Basic",
    29  			SyntaxLegacy,
    30  			ljoin(
    31  				`agent "foo" {      `,
    32  				`	policy = "read"  `,
    33  				`}                  `,
    34  				`agent "bar" {      `,
    35  				`	policy = "write" `,
    36  				`}                  `,
    37  				`event "" {         `,
    38  				`	policy = "read"  `,
    39  				`}                  `,
    40  				`event "foo" {      `,
    41  				`	policy = "write" `,
    42  				`}                  `,
    43  				`event "bar" {      `,
    44  				`	policy = "deny"  `,
    45  				`}                  `,
    46  				`key "" {           `,
    47  				`	policy = "read"  `,
    48  				`}                  `,
    49  				`key "foo/" {       `,
    50  				`	policy = "write" `,
    51  				`}                  `,
    52  				`key "foo/bar/" {   `,
    53  				`	policy = "read"  `,
    54  				`}                  `,
    55  				`key "foo/bar/baz" {`,
    56  				`	policy = "deny"  `,
    57  				`}                  `,
    58  				`keyring = "deny"   `,
    59  				`node "" {          `,
    60  				`	policy = "read"  `,
    61  				`}                  `,
    62  				`node "foo" {       `,
    63  				`	policy = "write" `,
    64  				`}                  `,
    65  				`node "bar" {       `,
    66  				`	policy = "deny"  `,
    67  				`}                  `,
    68  				`operator = "deny"  `,
    69  				`service "" {       `,
    70  				`	policy = "write" `,
    71  				`}                  `,
    72  				`service "foo" {    `,
    73  				`	policy = "read"  `,
    74  				`}                  `,
    75  				`session "foo" {    `,
    76  				`	policy = "write" `,
    77  				`}                  `,
    78  				`session "bar" {    `,
    79  				`	policy = "deny"  `,
    80  				`}                  `,
    81  				`query "" {         `,
    82  				`	policy = "read"  `,
    83  				`}                  `,
    84  				`query "foo" {      `,
    85  				`	policy = "write" `,
    86  				`}                  `,
    87  				`query "bar" {      `,
    88  				`	policy = "deny"  `,
    89  				`}                  `),
    90  			&Policy{
    91  				AgentPrefixes: []*AgentPolicy{
    92  					&AgentPolicy{
    93  						Node:   "foo",
    94  						Policy: PolicyRead,
    95  					},
    96  					&AgentPolicy{
    97  						Node:   "bar",
    98  						Policy: PolicyWrite,
    99  					},
   100  				},
   101  				EventPrefixes: []*EventPolicy{
   102  					&EventPolicy{
   103  						Event:  "",
   104  						Policy: PolicyRead,
   105  					},
   106  					&EventPolicy{
   107  						Event:  "foo",
   108  						Policy: PolicyWrite,
   109  					},
   110  					&EventPolicy{
   111  						Event:  "bar",
   112  						Policy: PolicyDeny,
   113  					},
   114  				},
   115  				Keyring: PolicyDeny,
   116  				KeyPrefixes: []*KeyPolicy{
   117  					&KeyPolicy{
   118  						Prefix: "",
   119  						Policy: PolicyRead,
   120  					},
   121  					&KeyPolicy{
   122  						Prefix: "foo/",
   123  						Policy: PolicyWrite,
   124  					},
   125  					&KeyPolicy{
   126  						Prefix: "foo/bar/",
   127  						Policy: PolicyRead,
   128  					},
   129  					&KeyPolicy{
   130  						Prefix: "foo/bar/baz",
   131  						Policy: PolicyDeny,
   132  					},
   133  				},
   134  				NodePrefixes: []*NodePolicy{
   135  					&NodePolicy{
   136  						Name:   "",
   137  						Policy: PolicyRead,
   138  					},
   139  					&NodePolicy{
   140  						Name:   "foo",
   141  						Policy: PolicyWrite,
   142  					},
   143  					&NodePolicy{
   144  						Name:   "bar",
   145  						Policy: PolicyDeny,
   146  					},
   147  				},
   148  				Operator: PolicyDeny,
   149  				PreparedQueryPrefixes: []*PreparedQueryPolicy{
   150  					&PreparedQueryPolicy{
   151  						Prefix: "",
   152  						Policy: PolicyRead,
   153  					},
   154  					&PreparedQueryPolicy{
   155  						Prefix: "foo",
   156  						Policy: PolicyWrite,
   157  					},
   158  					&PreparedQueryPolicy{
   159  						Prefix: "bar",
   160  						Policy: PolicyDeny,
   161  					},
   162  				},
   163  				ServicePrefixes: []*ServicePolicy{
   164  					&ServicePolicy{
   165  						Name:   "",
   166  						Policy: PolicyWrite,
   167  					},
   168  					&ServicePolicy{
   169  						Name:   "foo",
   170  						Policy: PolicyRead,
   171  					},
   172  				},
   173  				SessionPrefixes: []*SessionPolicy{
   174  					&SessionPolicy{
   175  						Node:   "foo",
   176  						Policy: PolicyWrite,
   177  					},
   178  					&SessionPolicy{
   179  						Node:   "bar",
   180  						Policy: PolicyDeny,
   181  					},
   182  				},
   183  			},
   184  			"",
   185  		},
   186  		{
   187  			"Legacy (JSON)",
   188  			SyntaxLegacy,
   189  			ljoin(
   190  				`{                         `,
   191  				`	"agent": {              `,
   192  				`		"foo": {             `,
   193  				`			"policy": "write" `,
   194  				`		},                   `,
   195  				`		"bar": {             `,
   196  				`			"policy": "deny"  `,
   197  				`		}                    `,
   198  				`	},                      `,
   199  				`	"event": {              `,
   200  				`		"": {                `,
   201  				`			"policy": "read"  `,
   202  				`		},                   `,
   203  				`		"foo": {             `,
   204  				`			"policy": "write" `,
   205  				`		},                   `,
   206  				`		"bar": {             `,
   207  				`			"policy": "deny"  `,
   208  				`		}                    `,
   209  				`	},                      `,
   210  				`	"key": {                `,
   211  				`		"": {                `,
   212  				`			"policy": "read"  `,
   213  				`		},                   `,
   214  				`		"foo/": {            `,
   215  				`			"policy": "write" `,
   216  				`		},                   `,
   217  				`		"foo/bar/": {        `,
   218  				`			"policy": "read"  `,
   219  				`		},                   `,
   220  				`		"foo/bar/baz": {     `,
   221  				`			"policy": "deny"  `,
   222  				`		}                    `,
   223  				`	},                      `,
   224  				`	"keyring": "deny",      `,
   225  				`	"node": {               `,
   226  				`		"": {                `,
   227  				`			"policy": "read"  `,
   228  				`		},                   `,
   229  				`		"foo": {             `,
   230  				`			"policy": "write" `,
   231  				`		},                   `,
   232  				`		"bar": {             `,
   233  				`			"policy": "deny"  `,
   234  				`		}                    `,
   235  				`	},                      `,
   236  				`	"operator": "deny",     `,
   237  				`	"query": {              `,
   238  				`		"": {                `,
   239  				`			"policy": "read"  `,
   240  				`		},                   `,
   241  				`		"foo": {             `,
   242  				`			"policy": "write" `,
   243  				`		},                   `,
   244  				`		"bar": {             `,
   245  				`			"policy": "deny"  `,
   246  				`		}                    `,
   247  				`	},                      `,
   248  				`	"service": {            `,
   249  				`		"": {                `,
   250  				`			"policy": "write" `,
   251  				`		},                   `,
   252  				`		"foo": {             `,
   253  				`			"policy": "read"  `,
   254  				`		}                    `,
   255  				`	},                      `,
   256  				`	"session": {            `,
   257  				`		"foo": {             `,
   258  				`			"policy": "write" `,
   259  				`		},                   `,
   260  				`		"bar": {             `,
   261  				`			"policy": "deny"  `,
   262  				`		}                    `,
   263  				`	}                       `,
   264  				`}                         `),
   265  			&Policy{
   266  				AgentPrefixes: []*AgentPolicy{
   267  					&AgentPolicy{
   268  						Node:   "foo",
   269  						Policy: PolicyWrite,
   270  					},
   271  					&AgentPolicy{
   272  						Node:   "bar",
   273  						Policy: PolicyDeny,
   274  					},
   275  				},
   276  				EventPrefixes: []*EventPolicy{
   277  					&EventPolicy{
   278  						Event:  "",
   279  						Policy: PolicyRead,
   280  					},
   281  					&EventPolicy{
   282  						Event:  "foo",
   283  						Policy: PolicyWrite,
   284  					},
   285  					&EventPolicy{
   286  						Event:  "bar",
   287  						Policy: PolicyDeny,
   288  					},
   289  				},
   290  				Keyring: PolicyDeny,
   291  				KeyPrefixes: []*KeyPolicy{
   292  					&KeyPolicy{
   293  						Prefix: "",
   294  						Policy: PolicyRead,
   295  					},
   296  					&KeyPolicy{
   297  						Prefix: "foo/",
   298  						Policy: PolicyWrite,
   299  					},
   300  					&KeyPolicy{
   301  						Prefix: "foo/bar/",
   302  						Policy: PolicyRead,
   303  					},
   304  					&KeyPolicy{
   305  						Prefix: "foo/bar/baz",
   306  						Policy: PolicyDeny,
   307  					},
   308  				},
   309  				NodePrefixes: []*NodePolicy{
   310  					&NodePolicy{
   311  						Name:   "",
   312  						Policy: PolicyRead,
   313  					},
   314  					&NodePolicy{
   315  						Name:   "foo",
   316  						Policy: PolicyWrite,
   317  					},
   318  					&NodePolicy{
   319  						Name:   "bar",
   320  						Policy: PolicyDeny,
   321  					},
   322  				},
   323  				Operator: PolicyDeny,
   324  				PreparedQueryPrefixes: []*PreparedQueryPolicy{
   325  					&PreparedQueryPolicy{
   326  						Prefix: "",
   327  						Policy: PolicyRead,
   328  					},
   329  					&PreparedQueryPolicy{
   330  						Prefix: "foo",
   331  						Policy: PolicyWrite,
   332  					},
   333  					&PreparedQueryPolicy{
   334  						Prefix: "bar",
   335  						Policy: PolicyDeny,
   336  					},
   337  				},
   338  				ServicePrefixes: []*ServicePolicy{
   339  					&ServicePolicy{
   340  						Name:   "",
   341  						Policy: PolicyWrite,
   342  					},
   343  					&ServicePolicy{
   344  						Name:   "foo",
   345  						Policy: PolicyRead,
   346  					},
   347  				},
   348  				SessionPrefixes: []*SessionPolicy{
   349  					&SessionPolicy{
   350  						Node:   "foo",
   351  						Policy: PolicyWrite,
   352  					},
   353  					&SessionPolicy{
   354  						Node:   "bar",
   355  						Policy: PolicyDeny,
   356  					},
   357  				},
   358  			},
   359  			"",
   360  		},
   361  		{
   362  			"Service No Intentions (Legacy)",
   363  			SyntaxLegacy,
   364  			ljoin(
   365  				`service "foo" {    `,
   366  				`   policy = "write"`,
   367  				`}                  `),
   368  			&Policy{
   369  				ServicePrefixes: []*ServicePolicy{
   370  					{
   371  						Name:   "foo",
   372  						Policy: "write",
   373  					},
   374  				},
   375  			},
   376  			"",
   377  		},
   378  		{
   379  			"Service Intentions (Legacy)",
   380  			SyntaxLegacy,
   381  			ljoin(
   382  				`service "foo" {       `,
   383  				`   policy = "write"   `,
   384  				`   intentions = "read"`,
   385  				`}                     `),
   386  			&Policy{
   387  				ServicePrefixes: []*ServicePolicy{
   388  					{
   389  						Name:       "foo",
   390  						Policy:     "write",
   391  						Intentions: "read",
   392  					},
   393  				},
   394  			},
   395  			"",
   396  		},
   397  		{
   398  			"Service Intention: invalid value (Legacy)",
   399  			SyntaxLegacy,
   400  			ljoin(
   401  				`service "foo" {      `,
   402  				`   policy = "write"  `,
   403  				`   intentions = "foo"`,
   404  				`}                    `),
   405  			nil,
   406  			"Invalid service intentions policy",
   407  		},
   408  		{
   409  			"Bad Policy - ACL",
   410  
   411  			SyntaxCurrent,
   412  			`acl = "nope"`,
   413  			nil,
   414  			"Invalid acl policy",
   415  		},
   416  		{
   417  			"Bad Policy - Agent",
   418  			SyntaxCurrent,
   419  			`agent "foo" { policy = "nope" }`,
   420  			nil,
   421  			"Invalid agent policy",
   422  		},
   423  		{
   424  			"Bad Policy - Agent Prefix",
   425  			SyntaxCurrent,
   426  			`agent_prefix "foo" { policy = "nope" }`,
   427  			nil,
   428  			"Invalid agent_prefix policy",
   429  		},
   430  		{
   431  			"Bad Policy - Key",
   432  			SyntaxCurrent,
   433  			`key "foo" { policy = "nope" }`,
   434  			nil,
   435  			"Invalid key policy",
   436  		},
   437  		{
   438  			"Bad Policy - Key Prefix",
   439  			SyntaxCurrent,
   440  			`key_prefix "foo" { policy = "nope" }`,
   441  			nil,
   442  			"Invalid key_prefix policy",
   443  		},
   444  		{
   445  			"Bad Policy - Node",
   446  			SyntaxCurrent,
   447  			`node "foo" { policy = "nope" }`,
   448  			nil,
   449  			"Invalid node policy",
   450  		},
   451  		{
   452  			"Bad Policy - Node Prefix",
   453  			SyntaxCurrent,
   454  			`node_prefix "foo" { policy = "nope" }`,
   455  			nil,
   456  			"Invalid node_prefix policy",
   457  		},
   458  		{
   459  			"Bad Policy - Service",
   460  			SyntaxCurrent,
   461  			`service "foo" { policy = "nope" }`,
   462  			nil,
   463  			"Invalid service policy",
   464  		},
   465  		{
   466  			"Bad Policy - Service Prefix",
   467  			SyntaxCurrent,
   468  			`service_prefix "foo" { policy = "nope" }`,
   469  			nil,
   470  			"Invalid service_prefix policy",
   471  		},
   472  		{
   473  			"Bad Policy - Session",
   474  			SyntaxCurrent,
   475  			`session "foo" { policy = "nope" }`,
   476  			nil,
   477  			"Invalid session policy",
   478  		},
   479  		{
   480  			"Bad Policy - Session Prefix",
   481  			SyntaxCurrent,
   482  			`session_prefix "foo" { policy = "nope" }`,
   483  			nil,
   484  			"Invalid session_prefix policy",
   485  		},
   486  		{
   487  			"Bad Policy - Event",
   488  			SyntaxCurrent,
   489  			`event "foo" { policy = "nope" }`,
   490  			nil,
   491  			"Invalid event policy",
   492  		},
   493  		{
   494  			"Bad Policy - Event Prefix",
   495  			SyntaxCurrent,
   496  			`event_prefix "foo" { policy = "nope" }`,
   497  			nil,
   498  			"Invalid event_prefix policy",
   499  		},
   500  		{
   501  			"Bad Policy - Prepared Query",
   502  			SyntaxCurrent,
   503  			`query "foo" { policy = "nope" }`,
   504  			nil,
   505  			"Invalid query policy",
   506  		},
   507  		{
   508  			"Bad Policy - Prepared Query Prefix",
   509  			SyntaxCurrent,
   510  			`query_prefix "foo" { policy = "nope" }`,
   511  			nil,
   512  			"Invalid query_prefix policy",
   513  		},
   514  		{
   515  			"Bad Policy - Keyring",
   516  			SyntaxCurrent,
   517  			`keyring = "nope"`,
   518  			nil,
   519  			"Invalid keyring policy",
   520  		},
   521  		{
   522  			"Bad Policy - Operator",
   523  			SyntaxCurrent,
   524  			`operator = "nope"`,
   525  			nil,
   526  			"Invalid operator policy",
   527  		},
   528  		{
   529  			"Keyring Empty",
   530  			SyntaxCurrent,
   531  			`keyring = ""`,
   532  			&Policy{Keyring: ""},
   533  			"",
   534  		},
   535  		{
   536  			"Operator Empty",
   537  			SyntaxCurrent,
   538  			`operator = ""`,
   539  			&Policy{Operator: ""},
   540  			"",
   541  		},
   542  	}
   543  
   544  	for _, tc := range cases {
   545  		t.Run(tc.Name, func(t *testing.T) {
   546  			req := require.New(t)
   547  			actual, err := NewPolicyFromSource("", 0, tc.Rules, tc.Syntax, nil)
   548  			if tc.Err != "" {
   549  				errStartsWith(t, err, tc.Err)
   550  			} else {
   551  				req.Equal(tc.Expected, actual)
   552  			}
   553  		})
   554  	}
   555  }
   556  
   557  func TestMergePolicies(t *testing.T) {
   558  	type mergeTest struct {
   559  		name     string
   560  		input    []*Policy
   561  		expected *Policy
   562  	}
   563  
   564  	tests := []mergeTest{
   565  		{
   566  			name: "Agents",
   567  			input: []*Policy{
   568  				&Policy{
   569  					Agents: []*AgentPolicy{
   570  						&AgentPolicy{
   571  							Node:   "foo",
   572  							Policy: PolicyWrite,
   573  						},
   574  						&AgentPolicy{
   575  							Node:   "bar",
   576  							Policy: PolicyRead,
   577  						},
   578  						&AgentPolicy{
   579  							Node:   "baz",
   580  							Policy: PolicyWrite,
   581  						},
   582  					},
   583  					AgentPrefixes: []*AgentPolicy{
   584  						&AgentPolicy{
   585  							Node:   "000",
   586  							Policy: PolicyWrite,
   587  						},
   588  						&AgentPolicy{
   589  							Node:   "111",
   590  							Policy: PolicyRead,
   591  						},
   592  						&AgentPolicy{
   593  							Node:   "222",
   594  							Policy: PolicyWrite,
   595  						},
   596  					},
   597  				},
   598  				&Policy{
   599  					Agents: []*AgentPolicy{
   600  						&AgentPolicy{
   601  							Node:   "foo",
   602  							Policy: PolicyRead,
   603  						},
   604  						&AgentPolicy{
   605  							Node:   "baz",
   606  							Policy: PolicyDeny,
   607  						},
   608  					},
   609  					AgentPrefixes: []*AgentPolicy{
   610  						&AgentPolicy{
   611  							Node:   "000",
   612  							Policy: PolicyRead,
   613  						},
   614  						&AgentPolicy{
   615  							Node:   "222",
   616  							Policy: PolicyDeny,
   617  						},
   618  					},
   619  				},
   620  			},
   621  			expected: &Policy{
   622  				Agents: []*AgentPolicy{
   623  					&AgentPolicy{
   624  						Node:   "foo",
   625  						Policy: PolicyWrite,
   626  					},
   627  					&AgentPolicy{
   628  						Node:   "bar",
   629  						Policy: PolicyRead,
   630  					},
   631  					&AgentPolicy{
   632  						Node:   "baz",
   633  						Policy: PolicyDeny,
   634  					},
   635  				},
   636  				AgentPrefixes: []*AgentPolicy{
   637  					&AgentPolicy{
   638  						Node:   "000",
   639  						Policy: PolicyWrite,
   640  					},
   641  					&AgentPolicy{
   642  						Node:   "111",
   643  						Policy: PolicyRead,
   644  					},
   645  					&AgentPolicy{
   646  						Node:   "222",
   647  						Policy: PolicyDeny,
   648  					},
   649  				},
   650  			},
   651  		},
   652  		{
   653  			name: "Events",
   654  			input: []*Policy{
   655  				&Policy{
   656  					Events: []*EventPolicy{
   657  						&EventPolicy{
   658  							Event:  "foo",
   659  							Policy: PolicyWrite,
   660  						},
   661  						&EventPolicy{
   662  							Event:  "bar",
   663  							Policy: PolicyRead,
   664  						},
   665  						&EventPolicy{
   666  							Event:  "baz",
   667  							Policy: PolicyWrite,
   668  						},
   669  					},
   670  					EventPrefixes: []*EventPolicy{
   671  						&EventPolicy{
   672  							Event:  "000",
   673  							Policy: PolicyWrite,
   674  						},
   675  						&EventPolicy{
   676  							Event:  "111",
   677  							Policy: PolicyRead,
   678  						},
   679  						&EventPolicy{
   680  							Event:  "222",
   681  							Policy: PolicyWrite,
   682  						},
   683  					},
   684  				},
   685  				&Policy{
   686  					Events: []*EventPolicy{
   687  						&EventPolicy{
   688  							Event:  "foo",
   689  							Policy: PolicyRead,
   690  						},
   691  						&EventPolicy{
   692  							Event:  "baz",
   693  							Policy: PolicyDeny,
   694  						},
   695  					},
   696  					EventPrefixes: []*EventPolicy{
   697  						&EventPolicy{
   698  							Event:  "000",
   699  							Policy: PolicyRead,
   700  						},
   701  						&EventPolicy{
   702  							Event:  "222",
   703  							Policy: PolicyDeny,
   704  						},
   705  					},
   706  				},
   707  			},
   708  			expected: &Policy{
   709  				Events: []*EventPolicy{
   710  					&EventPolicy{
   711  						Event:  "foo",
   712  						Policy: PolicyWrite,
   713  					},
   714  					&EventPolicy{
   715  						Event:  "bar",
   716  						Policy: PolicyRead,
   717  					},
   718  					&EventPolicy{
   719  						Event:  "baz",
   720  						Policy: PolicyDeny,
   721  					},
   722  				},
   723  				EventPrefixes: []*EventPolicy{
   724  					&EventPolicy{
   725  						Event:  "000",
   726  						Policy: PolicyWrite,
   727  					},
   728  					&EventPolicy{
   729  						Event:  "111",
   730  						Policy: PolicyRead,
   731  					},
   732  					&EventPolicy{
   733  						Event:  "222",
   734  						Policy: PolicyDeny,
   735  					},
   736  				},
   737  			},
   738  		},
   739  		{
   740  			name: "Node",
   741  			input: []*Policy{
   742  				&Policy{
   743  					Nodes: []*NodePolicy{
   744  						&NodePolicy{
   745  							Name:   "foo",
   746  							Policy: PolicyWrite,
   747  						},
   748  						&NodePolicy{
   749  							Name:   "bar",
   750  							Policy: PolicyRead,
   751  						},
   752  						&NodePolicy{
   753  							Name:   "baz",
   754  							Policy: PolicyWrite,
   755  						},
   756  					},
   757  					NodePrefixes: []*NodePolicy{
   758  						&NodePolicy{
   759  							Name:   "000",
   760  							Policy: PolicyWrite,
   761  						},
   762  						&NodePolicy{
   763  							Name:   "111",
   764  							Policy: PolicyRead,
   765  						},
   766  						&NodePolicy{
   767  							Name:   "222",
   768  							Policy: PolicyWrite,
   769  						},
   770  					},
   771  				},
   772  				&Policy{
   773  					Nodes: []*NodePolicy{
   774  						&NodePolicy{
   775  							Name:   "foo",
   776  							Policy: PolicyRead,
   777  						},
   778  						&NodePolicy{
   779  							Name:   "baz",
   780  							Policy: PolicyDeny,
   781  						},
   782  					},
   783  					NodePrefixes: []*NodePolicy{
   784  						&NodePolicy{
   785  							Name:   "000",
   786  							Policy: PolicyRead,
   787  						},
   788  						&NodePolicy{
   789  							Name:   "222",
   790  							Policy: PolicyDeny,
   791  						},
   792  					},
   793  				},
   794  			},
   795  			expected: &Policy{
   796  				Nodes: []*NodePolicy{
   797  					&NodePolicy{
   798  						Name:   "foo",
   799  						Policy: PolicyWrite,
   800  					},
   801  					&NodePolicy{
   802  						Name:   "bar",
   803  						Policy: PolicyRead,
   804  					},
   805  					&NodePolicy{
   806  						Name:   "baz",
   807  						Policy: PolicyDeny,
   808  					},
   809  				},
   810  				NodePrefixes: []*NodePolicy{
   811  					&NodePolicy{
   812  						Name:   "000",
   813  						Policy: PolicyWrite,
   814  					},
   815  					&NodePolicy{
   816  						Name:   "111",
   817  						Policy: PolicyRead,
   818  					},
   819  					&NodePolicy{
   820  						Name:   "222",
   821  						Policy: PolicyDeny,
   822  					},
   823  				},
   824  			},
   825  		},
   826  		{
   827  			name: "Keys",
   828  			input: []*Policy{
   829  				&Policy{
   830  					Keys: []*KeyPolicy{
   831  						&KeyPolicy{
   832  							Prefix: "foo",
   833  							Policy: PolicyWrite,
   834  						},
   835  						&KeyPolicy{
   836  							Prefix: "bar",
   837  							Policy: PolicyRead,
   838  						},
   839  						&KeyPolicy{
   840  							Prefix: "baz",
   841  							Policy: PolicyWrite,
   842  						},
   843  						&KeyPolicy{
   844  							Prefix: "zoo",
   845  							Policy: PolicyList,
   846  						},
   847  					},
   848  					KeyPrefixes: []*KeyPolicy{
   849  						&KeyPolicy{
   850  							Prefix: "000",
   851  							Policy: PolicyWrite,
   852  						},
   853  						&KeyPolicy{
   854  							Prefix: "111",
   855  							Policy: PolicyRead,
   856  						},
   857  						&KeyPolicy{
   858  							Prefix: "222",
   859  							Policy: PolicyWrite,
   860  						},
   861  						&KeyPolicy{
   862  							Prefix: "333",
   863  							Policy: PolicyList,
   864  						},
   865  					},
   866  				},
   867  				&Policy{
   868  					Keys: []*KeyPolicy{
   869  						&KeyPolicy{
   870  							Prefix: "foo",
   871  							Policy: PolicyRead,
   872  						},
   873  						&KeyPolicy{
   874  							Prefix: "baz",
   875  							Policy: PolicyDeny,
   876  						},
   877  						&KeyPolicy{
   878  							Prefix: "zoo",
   879  							Policy: PolicyRead,
   880  						},
   881  					},
   882  					KeyPrefixes: []*KeyPolicy{
   883  						&KeyPolicy{
   884  							Prefix: "000",
   885  							Policy: PolicyRead,
   886  						},
   887  						&KeyPolicy{
   888  							Prefix: "222",
   889  							Policy: PolicyDeny,
   890  						},
   891  						&KeyPolicy{
   892  							Prefix: "333",
   893  							Policy: PolicyRead,
   894  						},
   895  					},
   896  				},
   897  			},
   898  			expected: &Policy{
   899  				Keys: []*KeyPolicy{
   900  					&KeyPolicy{
   901  						Prefix: "foo",
   902  						Policy: PolicyWrite,
   903  					},
   904  					&KeyPolicy{
   905  						Prefix: "bar",
   906  						Policy: PolicyRead,
   907  					},
   908  					&KeyPolicy{
   909  						Prefix: "baz",
   910  						Policy: PolicyDeny,
   911  					},
   912  					&KeyPolicy{
   913  						Prefix: "zoo",
   914  						Policy: PolicyList,
   915  					},
   916  				},
   917  				KeyPrefixes: []*KeyPolicy{
   918  					&KeyPolicy{
   919  						Prefix: "000",
   920  						Policy: PolicyWrite,
   921  					},
   922  					&KeyPolicy{
   923  						Prefix: "111",
   924  						Policy: PolicyRead,
   925  					},
   926  					&KeyPolicy{
   927  						Prefix: "222",
   928  						Policy: PolicyDeny,
   929  					},
   930  					&KeyPolicy{
   931  						Prefix: "333",
   932  						Policy: PolicyList,
   933  					},
   934  				},
   935  			},
   936  		},
   937  		{
   938  			name: "Services",
   939  			input: []*Policy{
   940  				&Policy{
   941  					Services: []*ServicePolicy{
   942  						&ServicePolicy{
   943  							Name:       "foo",
   944  							Policy:     PolicyWrite,
   945  							Intentions: PolicyWrite,
   946  						},
   947  						&ServicePolicy{
   948  							Name:       "bar",
   949  							Policy:     PolicyRead,
   950  							Intentions: PolicyRead,
   951  						},
   952  						&ServicePolicy{
   953  							Name:       "baz",
   954  							Policy:     PolicyWrite,
   955  							Intentions: PolicyWrite,
   956  						},
   957  					},
   958  					ServicePrefixes: []*ServicePolicy{
   959  						&ServicePolicy{
   960  							Name:       "000",
   961  							Policy:     PolicyWrite,
   962  							Intentions: PolicyWrite,
   963  						},
   964  						&ServicePolicy{
   965  							Name:       "111",
   966  							Policy:     PolicyRead,
   967  							Intentions: PolicyRead,
   968  						},
   969  						&ServicePolicy{
   970  							Name:       "222",
   971  							Policy:     PolicyWrite,
   972  							Intentions: PolicyWrite,
   973  						},
   974  					},
   975  				},
   976  				&Policy{
   977  					Services: []*ServicePolicy{
   978  						&ServicePolicy{
   979  							Name:       "foo",
   980  							Policy:     PolicyRead,
   981  							Intentions: PolicyRead,
   982  						},
   983  						&ServicePolicy{
   984  							Name:       "baz",
   985  							Policy:     PolicyDeny,
   986  							Intentions: PolicyDeny,
   987  						},
   988  					},
   989  					ServicePrefixes: []*ServicePolicy{
   990  						&ServicePolicy{
   991  							Name:       "000",
   992  							Policy:     PolicyRead,
   993  							Intentions: PolicyRead,
   994  						},
   995  						&ServicePolicy{
   996  							Name:       "222",
   997  							Policy:     PolicyDeny,
   998  							Intentions: PolicyDeny,
   999  						},
  1000  					},
  1001  				},
  1002  			},
  1003  			expected: &Policy{
  1004  				Services: []*ServicePolicy{
  1005  					&ServicePolicy{
  1006  						Name:       "foo",
  1007  						Policy:     PolicyWrite,
  1008  						Intentions: PolicyWrite,
  1009  					},
  1010  					&ServicePolicy{
  1011  						Name:       "bar",
  1012  						Policy:     PolicyRead,
  1013  						Intentions: PolicyRead,
  1014  					},
  1015  					&ServicePolicy{
  1016  						Name:       "baz",
  1017  						Policy:     PolicyDeny,
  1018  						Intentions: PolicyDeny,
  1019  					},
  1020  				},
  1021  				ServicePrefixes: []*ServicePolicy{
  1022  					&ServicePolicy{
  1023  						Name:       "000",
  1024  						Policy:     PolicyWrite,
  1025  						Intentions: PolicyWrite,
  1026  					},
  1027  					&ServicePolicy{
  1028  						Name:       "111",
  1029  						Policy:     PolicyRead,
  1030  						Intentions: PolicyRead,
  1031  					},
  1032  					&ServicePolicy{
  1033  						Name:       "222",
  1034  						Policy:     PolicyDeny,
  1035  						Intentions: PolicyDeny,
  1036  					},
  1037  				},
  1038  			},
  1039  		},
  1040  		{
  1041  			name: "Sessions",
  1042  			input: []*Policy{
  1043  				&Policy{
  1044  					Sessions: []*SessionPolicy{
  1045  						&SessionPolicy{
  1046  							Node:   "foo",
  1047  							Policy: PolicyWrite,
  1048  						},
  1049  						&SessionPolicy{
  1050  							Node:   "bar",
  1051  							Policy: PolicyRead,
  1052  						},
  1053  						&SessionPolicy{
  1054  							Node:   "baz",
  1055  							Policy: PolicyWrite,
  1056  						},
  1057  					},
  1058  					SessionPrefixes: []*SessionPolicy{
  1059  						&SessionPolicy{
  1060  							Node:   "000",
  1061  							Policy: PolicyWrite,
  1062  						},
  1063  						&SessionPolicy{
  1064  							Node:   "111",
  1065  							Policy: PolicyRead,
  1066  						},
  1067  						&SessionPolicy{
  1068  							Node:   "222",
  1069  							Policy: PolicyWrite,
  1070  						},
  1071  					},
  1072  				},
  1073  				&Policy{
  1074  					Sessions: []*SessionPolicy{
  1075  						&SessionPolicy{
  1076  							Node:   "foo",
  1077  							Policy: PolicyRead,
  1078  						},
  1079  						&SessionPolicy{
  1080  							Node:   "baz",
  1081  							Policy: PolicyDeny,
  1082  						},
  1083  					},
  1084  					SessionPrefixes: []*SessionPolicy{
  1085  						&SessionPolicy{
  1086  							Node:   "000",
  1087  							Policy: PolicyRead,
  1088  						},
  1089  						&SessionPolicy{
  1090  							Node:   "222",
  1091  							Policy: PolicyDeny,
  1092  						},
  1093  					},
  1094  				},
  1095  			},
  1096  			expected: &Policy{
  1097  				Sessions: []*SessionPolicy{
  1098  					&SessionPolicy{
  1099  						Node:   "foo",
  1100  						Policy: PolicyWrite,
  1101  					},
  1102  					&SessionPolicy{
  1103  						Node:   "bar",
  1104  						Policy: PolicyRead,
  1105  					},
  1106  					&SessionPolicy{
  1107  						Node:   "baz",
  1108  						Policy: PolicyDeny,
  1109  					},
  1110  				},
  1111  				SessionPrefixes: []*SessionPolicy{
  1112  					&SessionPolicy{
  1113  						Node:   "000",
  1114  						Policy: PolicyWrite,
  1115  					},
  1116  					&SessionPolicy{
  1117  						Node:   "111",
  1118  						Policy: PolicyRead,
  1119  					},
  1120  					&SessionPolicy{
  1121  						Node:   "222",
  1122  						Policy: PolicyDeny,
  1123  					},
  1124  				},
  1125  			},
  1126  		},
  1127  		{
  1128  			name: "Prepared Queries",
  1129  			input: []*Policy{
  1130  				&Policy{
  1131  					PreparedQueries: []*PreparedQueryPolicy{
  1132  						&PreparedQueryPolicy{
  1133  							Prefix: "foo",
  1134  							Policy: PolicyWrite,
  1135  						},
  1136  						&PreparedQueryPolicy{
  1137  							Prefix: "bar",
  1138  							Policy: PolicyRead,
  1139  						},
  1140  						&PreparedQueryPolicy{
  1141  							Prefix: "baz",
  1142  							Policy: PolicyWrite,
  1143  						},
  1144  					},
  1145  					PreparedQueryPrefixes: []*PreparedQueryPolicy{
  1146  						&PreparedQueryPolicy{
  1147  							Prefix: "000",
  1148  							Policy: PolicyWrite,
  1149  						},
  1150  						&PreparedQueryPolicy{
  1151  							Prefix: "111",
  1152  							Policy: PolicyRead,
  1153  						},
  1154  						&PreparedQueryPolicy{
  1155  							Prefix: "222",
  1156  							Policy: PolicyWrite,
  1157  						},
  1158  					},
  1159  				},
  1160  				&Policy{
  1161  					PreparedQueries: []*PreparedQueryPolicy{
  1162  						&PreparedQueryPolicy{
  1163  							Prefix: "foo",
  1164  							Policy: PolicyRead,
  1165  						},
  1166  						&PreparedQueryPolicy{
  1167  							Prefix: "baz",
  1168  							Policy: PolicyDeny,
  1169  						},
  1170  					},
  1171  					PreparedQueryPrefixes: []*PreparedQueryPolicy{
  1172  						&PreparedQueryPolicy{
  1173  							Prefix: "000",
  1174  							Policy: PolicyRead,
  1175  						},
  1176  						&PreparedQueryPolicy{
  1177  							Prefix: "222",
  1178  							Policy: PolicyDeny,
  1179  						},
  1180  					},
  1181  				},
  1182  			},
  1183  			expected: &Policy{
  1184  				PreparedQueries: []*PreparedQueryPolicy{
  1185  					&PreparedQueryPolicy{
  1186  						Prefix: "foo",
  1187  						Policy: PolicyWrite,
  1188  					},
  1189  					&PreparedQueryPolicy{
  1190  						Prefix: "bar",
  1191  						Policy: PolicyRead,
  1192  					},
  1193  					&PreparedQueryPolicy{
  1194  						Prefix: "baz",
  1195  						Policy: PolicyDeny,
  1196  					},
  1197  				},
  1198  				PreparedQueryPrefixes: []*PreparedQueryPolicy{
  1199  					&PreparedQueryPolicy{
  1200  						Prefix: "000",
  1201  						Policy: PolicyWrite,
  1202  					},
  1203  					&PreparedQueryPolicy{
  1204  						Prefix: "111",
  1205  						Policy: PolicyRead,
  1206  					},
  1207  					&PreparedQueryPolicy{
  1208  						Prefix: "222",
  1209  						Policy: PolicyDeny,
  1210  					},
  1211  				},
  1212  			},
  1213  		},
  1214  		{
  1215  			name: "Write Precedence",
  1216  			input: []*Policy{
  1217  				&Policy{
  1218  					ACL:      PolicyRead,
  1219  					Keyring:  PolicyRead,
  1220  					Operator: PolicyRead,
  1221  				},
  1222  				&Policy{
  1223  					ACL:      PolicyWrite,
  1224  					Keyring:  PolicyWrite,
  1225  					Operator: PolicyWrite,
  1226  				},
  1227  			},
  1228  			expected: &Policy{
  1229  				ACL:      PolicyWrite,
  1230  				Keyring:  PolicyWrite,
  1231  				Operator: PolicyWrite,
  1232  			},
  1233  		},
  1234  		{
  1235  			name: "Deny Precedence",
  1236  			input: []*Policy{
  1237  				&Policy{
  1238  					ACL:      PolicyWrite,
  1239  					Keyring:  PolicyWrite,
  1240  					Operator: PolicyWrite,
  1241  				},
  1242  				&Policy{
  1243  					ACL:      PolicyDeny,
  1244  					Keyring:  PolicyDeny,
  1245  					Operator: PolicyDeny,
  1246  				},
  1247  			},
  1248  			expected: &Policy{
  1249  				ACL:      PolicyDeny,
  1250  				Keyring:  PolicyDeny,
  1251  				Operator: PolicyDeny,
  1252  			},
  1253  		},
  1254  		{
  1255  			name: "Read Precedence",
  1256  			input: []*Policy{
  1257  				&Policy{
  1258  					ACL:      PolicyRead,
  1259  					Keyring:  PolicyRead,
  1260  					Operator: PolicyRead,
  1261  				},
  1262  				&Policy{},
  1263  			},
  1264  			expected: &Policy{
  1265  				ACL:      PolicyRead,
  1266  				Keyring:  PolicyRead,
  1267  				Operator: PolicyRead,
  1268  			},
  1269  		},
  1270  	}
  1271  
  1272  	req := require.New(t)
  1273  
  1274  	for _, tcase := range tests {
  1275  		t.Run(tcase.name, func(t *testing.T) {
  1276  			act := MergePolicies(tcase.input)
  1277  			exp := tcase.expected
  1278  			req.Equal(exp.ACL, act.ACL)
  1279  			req.Equal(exp.Keyring, act.Keyring)
  1280  			req.Equal(exp.Operator, act.Operator)
  1281  			req.ElementsMatch(exp.Agents, act.Agents)
  1282  			req.ElementsMatch(exp.AgentPrefixes, act.AgentPrefixes)
  1283  			req.ElementsMatch(exp.Events, act.Events)
  1284  			req.ElementsMatch(exp.EventPrefixes, act.EventPrefixes)
  1285  			req.ElementsMatch(exp.Keys, act.Keys)
  1286  			req.ElementsMatch(exp.KeyPrefixes, act.KeyPrefixes)
  1287  			req.ElementsMatch(exp.Nodes, act.Nodes)
  1288  			req.ElementsMatch(exp.NodePrefixes, act.NodePrefixes)
  1289  			req.ElementsMatch(exp.PreparedQueries, act.PreparedQueries)
  1290  			req.ElementsMatch(exp.PreparedQueryPrefixes, act.PreparedQueryPrefixes)
  1291  			req.ElementsMatch(exp.Services, act.Services)
  1292  			req.ElementsMatch(exp.ServicePrefixes, act.ServicePrefixes)
  1293  			req.ElementsMatch(exp.Sessions, act.Sessions)
  1294  			req.ElementsMatch(exp.SessionPrefixes, act.SessionPrefixes)
  1295  		})
  1296  	}
  1297  
  1298  }
  1299  
  1300  func TestRulesTranslate(t *testing.T) {
  1301  	input := `
  1302  # top level comment
  1303  
  1304  # block comment
  1305  agent "" {
  1306    # policy comment
  1307    policy = "write"
  1308  }
  1309  
  1310  # block comment
  1311  key "" {
  1312    # policy comment
  1313    policy = "write"
  1314  }
  1315  
  1316  # block comment
  1317  node "" {
  1318    # policy comment
  1319    policy = "write"
  1320  }
  1321  
  1322  # block comment
  1323  event "" {
  1324    # policy comment
  1325    policy = "write"
  1326  }
  1327  
  1328  # block comment
  1329  service "" {
  1330    # policy comment
  1331    policy = "write"
  1332  }
  1333  
  1334  # block comment
  1335  session "" {
  1336    # policy comment
  1337    policy = "write"
  1338  }
  1339  
  1340  # block comment
  1341  query "" {
  1342    # policy comment
  1343    policy = "write"
  1344  }
  1345  
  1346  # comment
  1347  keyring = "write"
  1348  
  1349  # comment
  1350  operator = "write"
  1351  `
  1352  
  1353  	expected := `
  1354  # top level comment
  1355  
  1356  # block comment
  1357  agent_prefix "" {
  1358    # policy comment
  1359    policy = "write"
  1360  }
  1361  
  1362  # block comment
  1363  key_prefix "" {
  1364    # policy comment
  1365    policy = "write"
  1366  }
  1367  
  1368  # block comment
  1369  node_prefix "" {
  1370    # policy comment
  1371    policy = "write"
  1372  }
  1373  
  1374  # block comment
  1375  event_prefix "" {
  1376    # policy comment
  1377    policy = "write"
  1378  }
  1379  
  1380  # block comment
  1381  service_prefix "" {
  1382    # policy comment
  1383    policy = "write"
  1384  }
  1385  
  1386  # block comment
  1387  session_prefix "" {
  1388    # policy comment
  1389    policy = "write"
  1390  }
  1391  
  1392  # block comment
  1393  query_prefix "" {
  1394    # policy comment
  1395    policy = "write"
  1396  }
  1397  
  1398  # comment
  1399  keyring = "write"
  1400  
  1401  # comment
  1402  operator = "write"
  1403  `
  1404  
  1405  	output, err := TranslateLegacyRules([]byte(input))
  1406  	require.NoError(t, err)
  1407  	require.Equal(t, strings.Trim(expected, "\n"), string(output))
  1408  }
  1409  
  1410  func TestPrecedence(t *testing.T) {
  1411  	type testCase struct {
  1412  		name     string
  1413  		a        string
  1414  		b        string
  1415  		expected bool
  1416  	}
  1417  
  1418  	cases := []testCase{
  1419  		{
  1420  			name:     "Deny Over Write",
  1421  			a:        PolicyDeny,
  1422  			b:        PolicyWrite,
  1423  			expected: true,
  1424  		},
  1425  		{
  1426  			name:     "Deny Over List",
  1427  			a:        PolicyDeny,
  1428  			b:        PolicyList,
  1429  			expected: true,
  1430  		},
  1431  		{
  1432  			name:     "Deny Over Read",
  1433  			a:        PolicyDeny,
  1434  			b:        PolicyRead,
  1435  			expected: true,
  1436  		},
  1437  		{
  1438  			name:     "Deny Over Unknown",
  1439  			a:        PolicyDeny,
  1440  			b:        "not a policy",
  1441  			expected: true,
  1442  		},
  1443  		{
  1444  			name:     "Write Over List",
  1445  			a:        PolicyWrite,
  1446  			b:        PolicyList,
  1447  			expected: true,
  1448  		},
  1449  		{
  1450  			name:     "Write Over Read",
  1451  			a:        PolicyWrite,
  1452  			b:        PolicyRead,
  1453  			expected: true,
  1454  		},
  1455  		{
  1456  			name:     "Write Over Unknown",
  1457  			a:        PolicyWrite,
  1458  			b:        "not a policy",
  1459  			expected: true,
  1460  		},
  1461  		{
  1462  			name:     "List Over Read",
  1463  			a:        PolicyList,
  1464  			b:        PolicyRead,
  1465  			expected: true,
  1466  		},
  1467  		{
  1468  			name:     "List Over Unknown",
  1469  			a:        PolicyList,
  1470  			b:        "not a policy",
  1471  			expected: true,
  1472  		},
  1473  		{
  1474  			name:     "Read Over Unknown",
  1475  			a:        PolicyRead,
  1476  			b:        "not a policy",
  1477  			expected: true,
  1478  		},
  1479  		{
  1480  			name:     "Write Over Deny",
  1481  			a:        PolicyWrite,
  1482  			b:        PolicyDeny,
  1483  			expected: false,
  1484  		},
  1485  		{
  1486  			name:     "List Over Deny",
  1487  			a:        PolicyList,
  1488  			b:        PolicyDeny,
  1489  			expected: false,
  1490  		},
  1491  		{
  1492  			name:     "Read Over Deny",
  1493  			a:        PolicyRead,
  1494  			b:        PolicyDeny,
  1495  			expected: false,
  1496  		},
  1497  		{
  1498  			name:     "Deny Over Unknown",
  1499  			a:        PolicyDeny,
  1500  			b:        "not a policy",
  1501  			expected: true,
  1502  		},
  1503  		{
  1504  			name:     "List Over Write",
  1505  			a:        PolicyList,
  1506  			b:        PolicyWrite,
  1507  			expected: false,
  1508  		},
  1509  		{
  1510  			name:     "Read Over Write",
  1511  			a:        PolicyRead,
  1512  			b:        PolicyWrite,
  1513  			expected: false,
  1514  		},
  1515  		{
  1516  			name:     "Unknown Over Write",
  1517  			a:        "not a policy",
  1518  			b:        PolicyWrite,
  1519  			expected: false,
  1520  		},
  1521  		{
  1522  			name:     "Read Over List",
  1523  			a:        PolicyRead,
  1524  			b:        PolicyList,
  1525  			expected: false,
  1526  		},
  1527  		{
  1528  			name:     "Unknown Over List",
  1529  			a:        "not a policy",
  1530  			b:        PolicyList,
  1531  			expected: false,
  1532  		},
  1533  		{
  1534  			name:     "Unknown Over Read",
  1535  			a:        "not a policy",
  1536  			b:        PolicyRead,
  1537  			expected: false,
  1538  		},
  1539  	}
  1540  
  1541  	for _, tcase := range cases {
  1542  		t.Run(tcase.name, func(t *testing.T) {
  1543  			require.Equal(t, tcase.expected, takesPrecedenceOver(tcase.a, tcase.b))
  1544  		})
  1545  	}
  1546  }