github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/core/secrets/secret_test.go (about)

     1  // Copyright 2021 Canonical Ltd.
     2  // Licensed under the LGPLv3, see LICENCE file for details.
     3  
     4  package secrets_test
     5  
     6  import (
     7  	"fmt"
     8  	"time"
     9  
    10  	jc "github.com/juju/testing/checkers"
    11  	"github.com/rs/xid"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"github.com/juju/juju/core/secrets"
    15  )
    16  
    17  type SecretURISuite struct{}
    18  
    19  var _ = gc.Suite(&SecretURISuite{})
    20  
    21  const (
    22  	secretID        = "9m4e2mr0ui3e8a215n4g"
    23  	secretSource    = "deadbeef-1bad-500d-9000-4b1d0d06f00d"
    24  	secretURI       = "secret:9m4e2mr0ui3e8a215n4g"
    25  	remoteSecretURI = "secret://deadbeef-1bad-500d-9000-4b1d0d06f00d/9m4e2mr0ui3e8a215n4g"
    26  	remoteSecretID  = "deadbeef-1bad-500d-9000-4b1d0d06f00d/9m4e2mr0ui3e8a215n4g"
    27  )
    28  
    29  func (s *SecretURISuite) TestParseURI(c *gc.C) {
    30  	for _, t := range []struct {
    31  		in       string
    32  		str      string
    33  		expected *secrets.URI
    34  		err      string
    35  	}{
    36  		{
    37  			in:  "http:nope",
    38  			err: `secret URI scheme "http" not valid`,
    39  		}, {
    40  			in:  "secret:a/b/c",
    41  			err: `secret URI "secret:a/b/c" not valid`,
    42  		}, {
    43  			in:  "secret:a.b.",
    44  			err: `secret URI "secret:a.b." not valid`,
    45  		}, {
    46  			in:  "secret:a.b#",
    47  			err: `secret URI "secret:a.b#" not valid`,
    48  		}, {
    49  			in: secretURI,
    50  			expected: &secrets.URI{
    51  				ID: secretID,
    52  			},
    53  		}, {
    54  			in:  secretID,
    55  			str: secretURI,
    56  			expected: &secrets.URI{
    57  				ID: secretID,
    58  			},
    59  		}, {
    60  			in:  remoteSecretURI,
    61  			str: remoteSecretURI,
    62  			expected: &secrets.URI{
    63  				ID:         secretID,
    64  				SourceUUID: secretSource,
    65  			},
    66  		}, {
    67  			in:  remoteSecretID,
    68  			str: remoteSecretURI,
    69  			expected: &secrets.URI{
    70  				ID:         secretID,
    71  				SourceUUID: secretSource,
    72  			},
    73  		},
    74  	} {
    75  		result, err := secrets.ParseURI(t.in)
    76  		if t.err != "" || result == nil {
    77  			c.Check(err, gc.ErrorMatches, t.err)
    78  		} else {
    79  			c.Check(result, jc.DeepEquals, t.expected)
    80  			if t.str != "" {
    81  				c.Check(result.String(), gc.Equals, t.str)
    82  			} else {
    83  				c.Check(result.String(), gc.Equals, t.in)
    84  			}
    85  		}
    86  	}
    87  }
    88  
    89  func (s *SecretURISuite) TestString(c *gc.C) {
    90  	expected := &secrets.URI{
    91  		ID: secretID,
    92  	}
    93  	str := expected.String()
    94  	c.Assert(str, gc.Equals, secretURI)
    95  	uri, err := secrets.ParseURI(str)
    96  	c.Assert(err, jc.ErrorIsNil)
    97  	c.Assert(uri, jc.DeepEquals, expected)
    98  }
    99  
   100  func (s *SecretURISuite) TestStringWithSource(c *gc.C) {
   101  	expected := &secrets.URI{
   102  		SourceUUID: secretSource,
   103  		ID:         secretID,
   104  	}
   105  	str := expected.String()
   106  	c.Assert(str, gc.Equals, fmt.Sprintf("secret://%s/%s", secretSource, secretID))
   107  	uri, err := secrets.ParseURI(str)
   108  	c.Assert(err, jc.ErrorIsNil)
   109  	c.Assert(uri, jc.DeepEquals, expected)
   110  }
   111  
   112  func (s *SecretURISuite) TestName(c *gc.C) {
   113  	uri := &secrets.URI{ID: secretID}
   114  	name := uri.Name(666)
   115  	c.Assert(name, gc.Equals, `9m4e2mr0ui3e8a215n4g-666`)
   116  }
   117  
   118  func (s *SecretURISuite) TestNew(c *gc.C) {
   119  	URI := secrets.NewURI()
   120  	_, err := xid.FromString(URI.ID)
   121  	c.Assert(err, jc.ErrorIsNil)
   122  }
   123  
   124  func (s *SecretURISuite) TestWithSource(c *gc.C) {
   125  	uri := &secrets.URI{ID: secretID}
   126  	uri = uri.WithSource(secretSource)
   127  	c.Assert(uri.SourceUUID, gc.Equals, secretSource)
   128  	c.Assert(uri.ID, gc.Equals, secretID)
   129  }
   130  
   131  func (s *SecretURISuite) TestIsLocal(c *gc.C) {
   132  	URI := secrets.NewURI()
   133  	c.Assert(URI.IsLocal("other-uuid"), jc.IsTrue)
   134  	URI2 := URI.WithSource("some-uuid")
   135  	c.Assert(URI2.IsLocal("some-uuid"), jc.IsTrue)
   136  	c.Assert(URI2.IsLocal("other-uuid"), jc.IsFalse)
   137  }
   138  
   139  type SecretSuite struct{}
   140  
   141  var _ = gc.Suite(&SecretSuite{})
   142  
   143  func ptr[T any](v T) *T {
   144  	return &v
   145  }
   146  
   147  func (s *SecretSuite) TestValidateConfig(c *gc.C) {
   148  	cfg := secrets.SecretConfig{
   149  		RotatePolicy: ptr(secrets.RotateDaily),
   150  	}
   151  	err := cfg.Validate()
   152  	c.Assert(err, gc.ErrorMatches, "cannot specify a secret rotate policy without a next rotate time")
   153  
   154  	cfg = secrets.SecretConfig{
   155  		NextRotateTime: ptr(time.Now()),
   156  	}
   157  	err = cfg.Validate()
   158  	c.Assert(err, gc.ErrorMatches, "cannot specify a secret rotate time without a rotate policy")
   159  }