github.com/drone/runner-go@v1.12.0/secret/encrypted_test.go (about)

     1  // Copyright 2019 Drone.IO Inc. All rights reserved.
     2  // Use of this source code is governed by the Polyform License
     3  // that can be found in the LICENSE file.
     4  
     5  package secret
     6  
     7  import (
     8  	"testing"
     9  
    10  	"github.com/drone/drone-go/drone"
    11  	"github.com/drone/runner-go/manifest"
    12  )
    13  
    14  func TestEncrypted(t *testing.T) {
    15  	args := &Request{
    16  		Name:  "docker_password",
    17  		Build: &drone.Build{Event: drone.EventPullRequest},
    18  		Repo:  &drone.Repo{Private: false, Secret: passcode},
    19  		Conf: &manifest.Manifest{
    20  			Resources: []manifest.Resource{
    21  				&manifest.Secret{
    22  					Name: "docker_password",
    23  					Data: ciphertext,
    24  				},
    25  			},
    26  		},
    27  	}
    28  	service := Encrypted()
    29  	secret, err := service.Find(noContext, args)
    30  	if err != nil {
    31  		t.Errorf("Expect secret found and decrypted, got error. %s", err)
    32  	}
    33  	if secret == nil {
    34  		t.Errorf("Expect secret found and decrypted")
    35  	}
    36  	if got, want := secret.Data, plaintext; got != want {
    37  		t.Errorf("Expect plaintext %s, got %s", want, got)
    38  	}
    39  }
    40  
    41  // This test verifies that a nil secret and nil error are
    42  // returned if no corresponding secret resource entry is found
    43  // in the manifest. No error is returned because Not Found is
    44  // not considered an error.
    45  func TestEncrypted_NotFound(t *testing.T) {
    46  	args := &Request{
    47  		Name:  "docker_password",
    48  		Build: &drone.Build{Event: drone.EventPush},
    49  		Conf: &manifest.Manifest{
    50  			Resources: []manifest.Resource{
    51  				&manifest.Signature{
    52  					Name: "signature",
    53  					Hmac: "<some signature>",
    54  				},
    55  				&manifest.Secret{
    56  					Name: "docker_username",
    57  					Data: ciphertext,
    58  				},
    59  			},
    60  		},
    61  	}
    62  	service := Encrypted()
    63  	secret, err := service.Find(noContext, args)
    64  	if err != nil {
    65  		t.Errorf("Expect nil error when secret not exists")
    66  	}
    67  	if secret != nil {
    68  		t.Errorf("Expect nil secret when secret not exists")
    69  	}
    70  }
    71  
    72  // This test verifies that if a secret is decrypted and the
    73  // value is an empty string, a nil secret and nil error are
    74  // returned by the provider.
    75  func TestEncrypted_EmptyData(t *testing.T) {
    76  	args := &Request{
    77  		Name:  "docker_password",
    78  		Build: &drone.Build{Event: drone.EventPush},
    79  		Conf: &manifest.Manifest{
    80  			Resources: []manifest.Resource{
    81  				&manifest.Secret{
    82  					Name: "docker_password",
    83  					Data: "", // should skip
    84  				},
    85  			},
    86  		},
    87  	}
    88  	service := Encrypted()
    89  	secret, err := service.Find(noContext, args)
    90  	if err != nil {
    91  		t.Errorf("Expect nil error when secret not exists")
    92  	}
    93  	if secret != nil {
    94  		t.Errorf("Expect nil secret when secret not exists")
    95  	}
    96  }
    97  
    98  // This test verifies that encrypted secrets are not exposed
    99  // the all the following criteria is met, a) the repository is
   100  // private b) the event is a pull request and c) the pull
   101  // requests comes from a fork.
   102  func TestEncrypted_PullRequest_Public_Fork(t *testing.T) {
   103  	args := &Request{
   104  		Name:  "docker_password",
   105  		Build: &drone.Build{Event: drone.EventPullRequest, Fork: "octocat/hello-world"},
   106  		Repo:  &drone.Repo{Private: false},
   107  		Conf: &manifest.Manifest{
   108  			Resources: []manifest.Resource{
   109  				&manifest.Secret{
   110  					Name: "docker_password",
   111  					Data: ciphertext,
   112  				},
   113  			},
   114  		},
   115  	}
   116  	service := Encrypted()
   117  	secret, err := service.Find(noContext, args)
   118  	if err != nil {
   119  		t.Errorf("Expect nil error when secret not exists")
   120  	}
   121  	if secret != nil {
   122  		t.Errorf("Expect nil secret when secret not exists")
   123  	}
   124  }
   125  
   126  // This test verifies that an error decoding an ecrypted secret
   127  // is returned to the caller.
   128  func TestEncrypted_DecodeError(t *testing.T) {
   129  	args := &Request{
   130  		Name:  "docker_password",
   131  		Build: &drone.Build{Event: drone.EventPullRequest},
   132  		Repo:  &drone.Repo{Private: false, Secret: passcode},
   133  		Conf: &manifest.Manifest{
   134  			Resources: []manifest.Resource{
   135  				&manifest.Secret{
   136  					Name: "docker_password",
   137  					Data: "<invalid text>",
   138  				},
   139  			},
   140  		},
   141  	}
   142  	service := Encrypted()
   143  	_, err := service.Find(noContext, args)
   144  	if err == nil {
   145  		t.Errorf("Expect base64 decode error")
   146  	}
   147  }
   148  
   149  // This test verifies that if a secret key is invalid, resulting
   150  // in a decryption error, the error is returned to the caller.
   151  func TestEncrypted_Decrypt_InvalidKey(t *testing.T) {
   152  	args := &Request{
   153  		Name:  "docker_password",
   154  		Build: &drone.Build{Event: drone.EventPullRequest},
   155  		Repo:  &drone.Repo{Private: false, Secret: "id0cvCE0F1tgWeR4WvAXwChyRdDi8gHL"},
   156  		Conf: &manifest.Manifest{
   157  			Resources: []manifest.Resource{
   158  				&manifest.Secret{
   159  					Name: "docker_password",
   160  					Data: ciphertext,
   161  				},
   162  			},
   163  		},
   164  	}
   165  	service := Encrypted()
   166  	_, err := service.Find(noContext, args)
   167  	if err == nil {
   168  		t.Errorf("Expect decryption error")
   169  	}
   170  }
   171  
   172  // This test verifies that if a secret key is malformed,
   173  // resulting in a decryption error, the error is returned to the
   174  // caller.
   175  func TestEncrypted_Decrypt_MalformedKey(t *testing.T) {
   176  	args := &Request{
   177  		Name:  "docker_password",
   178  		Build: &drone.Build{Event: drone.EventPullRequest},
   179  		Repo:  &drone.Repo{Private: false, Secret: "<invalid key>"},
   180  		Conf: &manifest.Manifest{
   181  			Resources: []manifest.Resource{
   182  				&manifest.Secret{
   183  					Name: "docker_password",
   184  					Data: ciphertext,
   185  				},
   186  			},
   187  		},
   188  	}
   189  	service := Encrypted()
   190  	_, err := service.Find(noContext, args)
   191  	if err == nil {
   192  		t.Errorf("Expect decryption error")
   193  	}
   194  }
   195  
   196  // This test verifies that if an encrypted secret is malformed,
   197  // resulting in a decryption error, the error is returned to the
   198  // caller.
   199  func TestEncrypted_Decrypt_MalformedBlock(t *testing.T) {
   200  	args := &Request{
   201  		Name:  "docker_password",
   202  		Build: &drone.Build{Event: drone.EventPullRequest},
   203  		Repo:  &drone.Repo{Private: false, Secret: passcode},
   204  		Conf: &manifest.Manifest{
   205  			Resources: []manifest.Resource{
   206  				&manifest.Secret{
   207  					Name: "docker_password",
   208  					Data: "<malformed ciphertext>",
   209  				},
   210  			},
   211  		},
   212  	}
   213  	service := Encrypted()
   214  	_, err := service.Find(noContext, args)
   215  	if err == nil {
   216  		t.Errorf("Expect decryption error")
   217  	}
   218  }
   219  
   220  var (
   221  	plaintext  = `correct-horse-battery-staple`
   222  	ciphertext = `6OEK5rMVitI+S7//bLJSuwbIGq7/rtlj/V30DhhUa1sYWQd+CsCb/YUUhJ1F6pRBTVlBmiFHxq4=`
   223  	passcode   = `O9AhOJ23FHtiiXejAl381QG4fg9Zv3LK`
   224  )