github.com/fnproject/cli@v0.0.0-20240508150455-e5d88bd86117/commands/image_signature_test.go (about) 1 package commands 2 3 import ( 4 "crypto/rsa" 5 "encoding/base64" 6 "encoding/json" 7 "github.com/fnproject/cli/common" 8 "github.com/fnproject/cli/config" 9 "github.com/fnproject/fn_go/provider/oracle" 10 ociCommon "github.com/oracle/oci-go-sdk/v65/common" 11 "github.com/spf13/viper" 12 "net/url" 13 "testing" 14 ) 15 16 type mockConfigurationProvider struct { 17 region string 18 } 19 20 func (mcp *mockConfigurationProvider) TenancyOCID() (string, error) { return "", nil } 21 func (mcp *mockConfigurationProvider) UserOCID() (string, error) { return "", nil } 22 func (mcp *mockConfigurationProvider) KeyID() (string, error) { return "", nil } 23 func (mcp *mockConfigurationProvider) KeyFingerprint() (string, error) { return "", nil } 24 func (mcp *mockConfigurationProvider) PrivateRSAKey() (*rsa.PrivateKey, error) { return nil, nil } 25 func (mcp *mockConfigurationProvider) AuthType() (ociCommon.AuthConfig, error) { 26 return ociCommon.AuthConfig{}, nil 27 } 28 func (mcp *mockConfigurationProvider) Region() (string, error) { return mcp.region, nil } 29 30 var _ ociCommon.ConfigurationProvider = &mockConfigurationProvider{} 31 32 func TestIsSignatureConfigured(t *testing.T) { 33 // signature configuration is valid if all 4 values are set 34 signingDetails := common.SigningDetails{ 35 ImageCompartmentId: "ocid1.compartment.test", 36 KmsKeyId: "ocid1.kmskey.test", 37 KmsKeyVersionId: "ocid1.kmskeyversion.test", 38 SigningAlgorithm: "SHA_256_RSA_PKCS_PSS", 39 } 40 configured, err := isSignatureConfigured(signingDetails) 41 if !configured { 42 t.Fatal("expected true") 43 } 44 if err != nil { 45 t.Fatalf("expected no error, but found %s", err) 46 } 47 // signature configuration is invalid if partial values are set 48 signingDetails.ImageCompartmentId = "" 49 configured, err = isSignatureConfigured(signingDetails) 50 if err == nil { 51 t.Fatal("expected error") 52 } 53 // signature configuration is valid if no values are set 54 signingDetails = common.SigningDetails{} 55 configured, err = isSignatureConfigured(signingDetails) 56 if configured { 57 t.Fatal("expected false") 58 } 59 if err != nil { 60 t.Fatalf("expected no error, but found %s", err) 61 } 62 } 63 64 func TestGetRegion(t *testing.T) { 65 // when FnApiUrl is set, retrieve region from the URL 66 oracleProvider := &oracle.OracleProvider{ 67 FnApiUrl: &url.URL{Host: "functions.us-ashburn-1.oci.oraclecloud.com"}, 68 } 69 region := getRegion(oracleProvider) 70 expected := "us-ashburn-1" 71 if region != expected { 72 t.Fatalf("expected %s, but found %s", expected, region) 73 } 74 // when FnApiUrl is not set or cannot be parsed, retrieve region from OCI configuration provider 75 oracleProvider.FnApiUrl.Host = "functions.com" 76 oracleProvider.ConfigurationProvider = &mockConfigurationProvider{"us-phoenix-1"} 77 region = getRegion(oracleProvider) 78 expected = "us-phoenix-1" 79 if region != expected { 80 t.Fatalf("expected %s, but found %s", expected, region) 81 } 82 } 83 84 func TestGetRepositoryName(t *testing.T) { 85 viper.Set(config.EnvFnRegistry, "iad.ocir.io/test") 86 ff := &common.FuncFileV20180708{ 87 Version: "1.0.0", 88 Name: "testfn", 89 } 90 repositoryName, err := getRepositoryName(ff) 91 if err != nil { 92 t.Fatalf("expected no error, but found %s", err) 93 } 94 expected := "testfn" 95 if repositoryName != expected { 96 t.Fatalf("expected %s, but found %s", expected, repositoryName) 97 } 98 viper.Set(config.EnvFnRegistry, "iad.ocir.io/test/test2") 99 repositoryName, err = getRepositoryName(ff) 100 if err != nil { 101 t.Fatalf("expected no error, but found %s", err) 102 } 103 expected = "test2/testfn" 104 if repositoryName != expected { 105 t.Fatalf("expected %s, but found %s", expected, repositoryName) 106 } 107 } 108 109 func TestCreateImageSignatureMessage(t *testing.T) { 110 region, imageDigest, repositoryName := "us-ashburn-1", "sha256:digestvalue", "test/reponame" 111 signingDetails := common.SigningDetails{ 112 ImageCompartmentId: "ocid1.compartment.test", 113 KmsKeyId: "ocid1.key.test", 114 KmsKeyVersionId: "ocid1.keyversion.test", 115 SigningAlgorithm: "SHA_256_RSA_PKCS_PSS", 116 } 117 message, err := createImageSignatureMessage(region, imageDigest, repositoryName, signingDetails) 118 if err != nil { 119 t.Fatalf("expected no error, but found %s", err) 120 } 121 messageBytes, _ := json.Marshal(&Message{ 122 Description: "image signed by fn CLI", 123 ImageDigest: imageDigest, 124 KmsKeyId: signingDetails.KmsKeyId, 125 KmsKeyVersionId: signingDetails.KmsKeyVersionId, 126 Metadata: "{\"signedBy\":\"fn CLI\"}", 127 Region: region, 128 RepositoryName: repositoryName, 129 SigningAlgorithm: signingDetails.SigningAlgorithm, 130 }) 131 expectedMessage := base64.StdEncoding.EncodeToString(messageBytes) 132 if message != expectedMessage { 133 t.Fatalf("expected %s, but found %s", expectedMessage, message) 134 } 135 } 136 137 func TestBuildCryptoEndpoint(t *testing.T) { 138 // test old style regional endpoints 139 region, keyId := "us-ashburn-1", "ocid1.key.oc1.iad.testvault.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefgh" 140 endpoint, err := buildCryptoEndpoint(region, keyId) 141 if err != nil { 142 t.Fatalf("expected no error, but found %s", err) 143 } 144 expected := "https://testvault-crypto.kms.us-ashburn-1.oraclecloud.com" 145 if endpoint != expected { 146 t.Fatalf("expected %s, found %s", expected, endpoint) 147 } 148 // test new style regional endpoints 149 region, keyId = "us-sanjose-1", "ocid1.key.oc1.us-sanjose-1.testvault.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefgh" 150 endpoint, err = buildCryptoEndpoint(region, keyId) 151 if err != nil { 152 t.Fatalf("expected no error, but found %s", err) 153 } 154 expected = "https://testvault-crypto.kms.us-sanjose-1.oci.oraclecloud.com" 155 if endpoint != expected { 156 t.Fatalf("expected %s, found %s", expected, endpoint) 157 } 158 // invalid key results in error 159 keyId = "invalidocid" 160 endpoint, err = buildCryptoEndpoint(region, keyId) 161 if err == nil { 162 t.Fatalf("expected error, but found %s", endpoint) 163 } 164 } 165 166 func TestFindMissingValues(t *testing.T) { 167 tests := map[string]common.SigningDetails{ 168 "kms_key_id,kms_key_version_id,signing_algorithm": {ImageCompartmentId: "test"}, 169 "kms_key_version_id,signing_algorithm": {ImageCompartmentId: "test", KmsKeyId: "test"}, 170 "signing_algorithm": {ImageCompartmentId: "test", KmsKeyId: "test", KmsKeyVersionId: "test"}, 171 } 172 for expected, signingDetails := range tests { 173 actual := findMissingValues(signingDetails) 174 if actual != expected { 175 t.Fatalf("input: %+v, expected: %s, actual: %s", signingDetails, expected, actual) 176 } 177 } 178 }