...

Source file src/edge-infra.dev/pkg/f8n/devinfra/repo/owners/policybot/policy/predicate/signature_test.go

Documentation: edge-infra.dev/pkg/f8n/devinfra/repo/owners/policybot/policy/predicate

     1  // Copyright 2021 Palantir Technologies, Inc.
     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 predicate
    16  
    17  import (
    18  	"context"
    19  	"testing"
    20  
    21  	"github.com/stretchr/testify/assert"
    22  
    23  	"edge-infra.dev/pkg/f8n/devinfra/repo/owners/policybot/pull"
    24  	"edge-infra.dev/pkg/f8n/devinfra/repo/owners/policybot/pull/pulltest"
    25  
    26  	"edge-infra.dev/pkg/f8n/devinfra/repo/owners/policybot/policy/common"
    27  )
    28  
    29  func TestHasValidSignatures(t *testing.T) {
    30  	pTrue := HasValidSignatures(true)
    31  	pFalse := HasValidSignatures(false)
    32  
    33  	testCases := []SignatureTestCase{
    34  		{
    35  			"ValidSignature",
    36  			&pulltest.Context{
    37  				AuthorValue: "mhaypenny",
    38  				CommitsValue: []*pull.Commit{
    39  					{
    40  						SHA:       "abcdef123456789",
    41  						Author:    "mhaypenny",
    42  						Committer: "mhaypenny",
    43  						Signature: &pull.Signature{
    44  							Type:    pull.SignatureGpg,
    45  							IsValid: true,
    46  							Signer:  "ttest",
    47  							State:   "VALID",
    48  							KeyID:   "3AA5C34371567BD2",
    49  						},
    50  					},
    51  				},
    52  			},
    53  			&common.PredicateResult{
    54  				Satisfied:       true,
    55  				Values:          []string{"abcdef123456789"},
    56  				ConditionValues: []string{"valid signatures"},
    57  			},
    58  		},
    59  		{
    60  			"InvalidSignature",
    61  			&pulltest.Context{
    62  				AuthorValue: "mhaypenny",
    63  				CommitsValue: []*pull.Commit{
    64  					{
    65  						SHA:       "abcdef123456789",
    66  						Author:    "mhaypenny",
    67  						Committer: "mhaypenny",
    68  						Signature: &pull.Signature{
    69  							Type:    pull.SignatureGpg,
    70  							IsValid: false,
    71  							Signer:  "ttest",
    72  							State:   "INVALID",
    73  							KeyID:   "3AA5C34371567BD2",
    74  						},
    75  					},
    76  				},
    77  			},
    78  			&common.PredicateResult{
    79  				Satisfied:       false,
    80  				Values:          []string{"abcdef123456789"},
    81  				ConditionValues: []string{"valid signatures"},
    82  			},
    83  		},
    84  		{
    85  			"NoSignature",
    86  			&pulltest.Context{
    87  				AuthorValue: "mhaypenny",
    88  				CommitsValue: []*pull.Commit{
    89  					{
    90  						SHA:       "abcdef123456789",
    91  						Author:    "mhaypenny",
    92  						Committer: "mhaypenny",
    93  						Signature: nil,
    94  					},
    95  				},
    96  			},
    97  			&common.PredicateResult{
    98  				Satisfied:       false,
    99  				Values:          []string{"abcdef123456789"},
   100  				ConditionValues: []string{"valid signatures"},
   101  			},
   102  		},
   103  	}
   104  
   105  	runSignatureTests(t, pTrue, testCases)
   106  
   107  	// Invert the expected outcomes and test against the false predicate
   108  	for idx := range testCases {
   109  		testCases[idx].ExpectedPredicateResult.Satisfied = !testCases[idx].ExpectedPredicateResult.Satisfied
   110  	}
   111  	runSignatureTests(t, pFalse, testCases)
   112  }
   113  
   114  func TestHasValidSignaturesBy(t *testing.T) {
   115  	p := &HasValidSignaturesBy{
   116  		common.Actors{
   117  			Teams:         []string{"testorg/team"},
   118  			Users:         []string{"mhaypenny"},
   119  			Organizations: []string{"testorg"},
   120  		},
   121  	}
   122  
   123  	runSignatureTests(t, p, []SignatureTestCase{
   124  		{
   125  			"ValidSignatureByUser",
   126  			&pulltest.Context{
   127  				AuthorValue: "mhaypenny",
   128  				CommitsValue: []*pull.Commit{
   129  					{
   130  						SHA:       "abcdef123456789",
   131  						Author:    "mhaypenny",
   132  						Committer: "mhaypenny",
   133  						Signature: &pull.Signature{
   134  							Type:    pull.SignatureGpg,
   135  							IsValid: true,
   136  							Signer:  "mhaypenny",
   137  							State:   "VALID",
   138  							KeyID:   "3AA5C34371567BD2",
   139  						},
   140  					},
   141  				},
   142  			},
   143  			&common.PredicateResult{
   144  				Satisfied: true,
   145  				Values:    []string{"abcdef123456789"},
   146  				ConditionsMap: map[string][]string{
   147  					"Organizations": p.Organizations,
   148  					"Teams":         p.Teams,
   149  					"Users":         p.Users,
   150  				},
   151  			},
   152  		},
   153  		{
   154  			"ValidSignatureButNotUser",
   155  			&pulltest.Context{
   156  				AuthorValue: "badcommitter",
   157  				CommitsValue: []*pull.Commit{
   158  					{
   159  						SHA:       "abcdef123456789",
   160  						Author:    "badcommitter",
   161  						Committer: "badcommitter",
   162  						Signature: &pull.Signature{
   163  							Type:    pull.SignatureGpg,
   164  							IsValid: true,
   165  							Signer:  "badcommitter",
   166  							State:   "VALID",
   167  							KeyID:   "3AD5C34671567BC3",
   168  						},
   169  					},
   170  				},
   171  			},
   172  			&common.PredicateResult{
   173  				Satisfied: false,
   174  				Values:    []string{"badcommitter"},
   175  				ConditionsMap: map[string][]string{
   176  					"Organizations": p.Organizations,
   177  					"Teams":         p.Teams,
   178  					"Users":         p.Users,
   179  				},
   180  			},
   181  		},
   182  		{
   183  			"ValidSignatureByTeamMember",
   184  			&pulltest.Context{
   185  				AuthorValue: "ttest",
   186  				TeamMemberships: map[string][]string{
   187  					"ttest": {
   188  						"testorg/team",
   189  					},
   190  				},
   191  				CommitsValue: []*pull.Commit{
   192  					{
   193  						SHA:       "abcdef123456789",
   194  						Author:    "ttest",
   195  						Committer: "ttest",
   196  						Signature: &pull.Signature{
   197  							Type:    pull.SignatureGpg,
   198  							IsValid: true,
   199  							Signer:  "ttest",
   200  							State:   "VALID",
   201  							KeyID:   "3AA5C34371567BD2",
   202  						},
   203  					},
   204  				},
   205  			},
   206  			&common.PredicateResult{
   207  				Satisfied: true,
   208  				Values:    []string{"abcdef123456789"},
   209  				ConditionsMap: map[string][]string{
   210  					"Organizations": p.Organizations,
   211  					"Teams":         p.Teams,
   212  					"Users":         p.Users,
   213  				},
   214  			},
   215  		},
   216  		{
   217  			"NoSignature",
   218  			&pulltest.Context{
   219  				AuthorValue: "mhaypenny",
   220  				CommitsValue: []*pull.Commit{
   221  					{
   222  						SHA:       "abcdef123456789",
   223  						Author:    "mhaypenny",
   224  						Committer: "mhaypenny",
   225  						Signature: nil,
   226  					},
   227  				},
   228  			},
   229  			&common.PredicateResult{
   230  				Satisfied: false,
   231  				Values:    []string{"abcdef123456789"},
   232  				ConditionsMap: map[string][]string{
   233  					"Organizations": p.Organizations,
   234  					"Teams":         p.Teams,
   235  					"Users":         p.Users,
   236  				},
   237  			},
   238  		},
   239  	})
   240  }
   241  
   242  func TestHasValidSignaturesByKeys(t *testing.T) {
   243  	p := &HasValidSignaturesByKeys{
   244  		KeyIDs: []string{"3AA5C34371567BD2"},
   245  	}
   246  
   247  	runSignatureTests(t, p, []SignatureTestCase{
   248  		{
   249  			"ValidSignatureByValidKey",
   250  			&pulltest.Context{
   251  				AuthorValue: "mhaypenny",
   252  				CommitsValue: []*pull.Commit{
   253  					{
   254  						SHA:       "abcdef123456789",
   255  						Author:    "ttest",
   256  						Committer: "ttest",
   257  						Signature: &pull.Signature{
   258  							Type:    pull.SignatureGpg,
   259  							IsValid: true,
   260  							Signer:  "mhaypenny",
   261  							State:   "VALID",
   262  							KeyID:   "3AA5C34371567BD2",
   263  						},
   264  					},
   265  				},
   266  			},
   267  			&common.PredicateResult{
   268  				Satisfied:       true,
   269  				Values:          []string{"abcdef123456789"},
   270  				ConditionValues: []string{"3AA5C34371567BD2"},
   271  			},
   272  		},
   273  		{
   274  			"ValidSignatureByInvalidKey",
   275  			&pulltest.Context{
   276  				AuthorValue: "mhaypenny",
   277  				CommitsValue: []*pull.Commit{
   278  					{
   279  						SHA:       "abcdef123456789",
   280  						Author:    "ttest",
   281  						Committer: "ttest",
   282  						Signature: &pull.Signature{
   283  							Type:    pull.SignatureGpg,
   284  							IsValid: true,
   285  							Signer:  "mhaypenny",
   286  							State:   "VALID",
   287  							KeyID:   "3AB5C35371567CE7",
   288  						},
   289  					},
   290  				},
   291  			},
   292  			&common.PredicateResult{
   293  				Satisfied:       false,
   294  				Values:          []string{"3AB5C35371567CE7"},
   295  				ConditionValues: []string{"3AA5C34371567BD2"},
   296  			},
   297  		},
   298  		{
   299  			"InvalidSignatureByInvalidKey",
   300  			&pulltest.Context{
   301  				AuthorValue: "mhaypenny",
   302  				CommitsValue: []*pull.Commit{
   303  					{
   304  						SHA:       "abcdef123456789",
   305  						Author:    "ttest",
   306  						Committer: "ttest",
   307  						Signature: &pull.Signature{
   308  							Type:    pull.SignatureGpg,
   309  							IsValid: false,
   310  							Signer:  "mhaypenny",
   311  							State:   "BAD_EMAIL",
   312  							KeyID:   "3AB5C35371567CE7",
   313  						},
   314  					},
   315  				},
   316  			},
   317  			&common.PredicateResult{
   318  				Satisfied:       false,
   319  				Values:          []string{"abcdef123456789"},
   320  				ConditionValues: []string{"3AA5C34371567BD2"},
   321  			},
   322  		},
   323  	})
   324  }
   325  
   326  type SignatureTestCase struct {
   327  	Name                    string
   328  	Context                 pull.Context
   329  	ExpectedPredicateResult *common.PredicateResult
   330  }
   331  
   332  func runSignatureTests(t *testing.T, p Predicate, cases []SignatureTestCase) {
   333  	ctx := context.Background()
   334  
   335  	for _, tc := range cases {
   336  		t.Run(tc.Name, func(t *testing.T) {
   337  			predicateResult, err := p.Evaluate(ctx, tc.Context)
   338  			if assert.NoError(t, err, "evaluation failed") {
   339  				assertPredicateResult(t, tc.ExpectedPredicateResult, predicateResult)
   340  			}
   341  		})
   342  	}
   343  }
   344  

View as plain text