github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/apiserver/facades/controller/usersecrets/secrets_test.go (about)

     1  // Copyright 2023 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package usersecrets_test
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/juju/collections/set"
    10  	"github.com/juju/names/v5"
    11  	"github.com/juju/testing"
    12  	jc "github.com/juju/testing/checkers"
    13  	"go.uber.org/mock/gomock"
    14  	gc "gopkg.in/check.v1"
    15  
    16  	commonsecrets "github.com/juju/juju/apiserver/common/secrets"
    17  	facademocks "github.com/juju/juju/apiserver/facade/mocks"
    18  	"github.com/juju/juju/apiserver/facades/controller/usersecrets"
    19  	"github.com/juju/juju/apiserver/facades/controller/usersecrets/mocks"
    20  	coresecrets "github.com/juju/juju/core/secrets"
    21  	"github.com/juju/juju/rpc/params"
    22  	"github.com/juju/juju/secrets/provider"
    23  	coretesting "github.com/juju/juju/testing"
    24  )
    25  
    26  type userSecretsSuite struct {
    27  	testing.IsolationSuite
    28  
    29  	authorizer *facademocks.MockAuthorizer
    30  	resources  *facademocks.MockResources
    31  	authTag    names.Tag
    32  
    33  	state         *mocks.MockSecretsState
    34  	stringWatcher *mocks.MockStringsWatcher
    35  
    36  	provider *mocks.MockSecretBackendProvider
    37  	backend  *mocks.MockSecretsBackend
    38  
    39  	facade *usersecrets.UserSecretsManager
    40  }
    41  
    42  var _ = gc.Suite(&userSecretsSuite{})
    43  
    44  func (s *userSecretsSuite) setup(c *gc.C) *gomock.Controller {
    45  	ctrl := gomock.NewController(c)
    46  
    47  	s.authorizer = facademocks.NewMockAuthorizer(ctrl)
    48  	s.resources = facademocks.NewMockResources(ctrl)
    49  	s.authTag = names.NewUserTag("foo")
    50  	s.state = mocks.NewMockSecretsState(ctrl)
    51  	s.stringWatcher = mocks.NewMockStringsWatcher(ctrl)
    52  
    53  	s.provider = mocks.NewMockSecretBackendProvider(ctrl)
    54  	s.backend = mocks.NewMockSecretsBackend(ctrl)
    55  	s.PatchValue(&commonsecrets.GetProvider, func(string) (provider.SecretBackendProvider, error) { return s.provider, nil })
    56  
    57  	s.authorizer.EXPECT().AuthController().Return(true)
    58  
    59  	var err error
    60  	s.facade, err = usersecrets.NewTestAPI(
    61  		s.authorizer, s.resources, s.authTag,
    62  		coretesting.ControllerTag.Id(), coretesting.ModelTag.Id(), s.state,
    63  		func() (*provider.ModelBackendConfigInfo, error) {
    64  			return &provider.ModelBackendConfigInfo{
    65  				ActiveID: "backend-id",
    66  				Configs: map[string]provider.ModelBackendConfig{
    67  					"backend-id": {
    68  						ControllerUUID: coretesting.ControllerTag.Id(),
    69  						ModelUUID:      coretesting.ModelTag.Id(),
    70  						ModelName:      "some-model",
    71  						BackendConfig: provider.BackendConfig{
    72  							BackendType: "active-type",
    73  							Config:      map[string]interface{}{"foo": "active-type"},
    74  						},
    75  					},
    76  				},
    77  			}, nil
    78  		},
    79  	)
    80  	c.Assert(err, jc.ErrorIsNil)
    81  	return ctrl
    82  }
    83  
    84  func (s *userSecretsSuite) TestWatchRevisionsToPrune(c *gc.C) {
    85  	defer s.setup(c).Finish()
    86  
    87  	s.state.EXPECT().WatchRevisionsToPrune([]names.Tag{names.NewModelTag(coretesting.ModelTag.Id())}).Return(s.stringWatcher, nil)
    88  	s.resources.EXPECT().Register(s.stringWatcher).Return("watcher-id")
    89  	stringChan := make(chan []string, 1)
    90  	stringChan <- []string{"1", "2", "3"}
    91  	s.stringWatcher.EXPECT().Changes().Return(stringChan)
    92  
    93  	result, err := s.facade.WatchRevisionsToPrune()
    94  	c.Assert(err, jc.ErrorIsNil)
    95  	c.Assert(result, jc.DeepEquals, params.StringsWatchResult{
    96  		StringsWatcherId: "watcher-id",
    97  		Changes:          []string{"1", "2", "3"},
    98  	})
    99  }
   100  
   101  func (s *userSecretsSuite) TestDeleteRevisionsAutoPruneEnabled(c *gc.C) {
   102  	defer s.setup(c).Finish()
   103  
   104  	uri := coresecrets.NewURI()
   105  	s.state.EXPECT().GetSecret(uri).Return(&coresecrets.SecretMetadata{
   106  		URI: uri, OwnerTag: coretesting.ModelTag.String(),
   107  		AutoPrune: true,
   108  	}, nil).Times(2)
   109  	s.state.EXPECT().GetSecretRevision(uri, 666).Return(&coresecrets.SecretRevisionMetadata{
   110  		Revision: 666,
   111  		ValueRef: &coresecrets.ValueRef{BackendID: "backend-id", RevisionID: "rev-666"},
   112  	}, nil)
   113  	s.state.EXPECT().DeleteSecret(uri, []int{666}).Return([]coresecrets.ValueRef{{
   114  		BackendID:  "backend-id",
   115  		RevisionID: "rev-666",
   116  	}}, nil)
   117  
   118  	cfg := &provider.ModelBackendConfig{
   119  		ControllerUUID: coretesting.ControllerTag.Id(),
   120  		ModelUUID:      coretesting.ModelTag.Id(),
   121  		ModelName:      "some-model",
   122  		BackendConfig: provider.BackendConfig{
   123  			BackendType: "active-type",
   124  			Config:      map[string]interface{}{"foo": "active-type"},
   125  		},
   126  	}
   127  	s.provider.EXPECT().NewBackend(cfg).Return(s.backend, nil)
   128  	s.backend.EXPECT().DeleteContent(gomock.Any(), "rev-666").Return(nil)
   129  	s.provider.EXPECT().CleanupSecrets(
   130  		cfg, names.NewUserTag("foo"),
   131  		provider.SecretRevisions{uri.ID: set.NewStrings("rev-666")},
   132  	).Return(nil)
   133  
   134  	results, err := s.facade.DeleteRevisions(
   135  		params.DeleteSecretArgs{
   136  			Args: []params.DeleteSecretArg{
   137  				{
   138  					URI:       uri.String(),
   139  					Revisions: []int{666},
   140  				},
   141  			},
   142  		},
   143  	)
   144  	c.Assert(err, jc.ErrorIsNil)
   145  	c.Assert(results, jc.DeepEquals, params.ErrorResults{
   146  		Results: []params.ErrorResult{{}},
   147  	})
   148  }
   149  
   150  func (s *userSecretsSuite) TestDeleteRevisionsAutoPruneDisabled(c *gc.C) {
   151  	defer s.setup(c).Finish()
   152  
   153  	uri := coresecrets.NewURI()
   154  	s.state.EXPECT().GetSecret(uri).Return(&coresecrets.SecretMetadata{
   155  		URI: uri, OwnerTag: coretesting.ModelTag.String(),
   156  		AutoPrune: false,
   157  	}, nil).Times(2)
   158  
   159  	results, err := s.facade.DeleteRevisions(
   160  		params.DeleteSecretArgs{
   161  			Args: []params.DeleteSecretArg{
   162  				{
   163  					URI:       uri.String(),
   164  					Revisions: []int{666},
   165  				},
   166  			},
   167  		},
   168  	)
   169  	c.Assert(err, jc.ErrorIsNil)
   170  	c.Assert(results, jc.DeepEquals, params.ErrorResults{
   171  		Results: []params.ErrorResult{
   172  			{
   173  				Error: &params.Error{
   174  					Message: fmt.Sprintf("cannot delete non auto-prune secret %q", uri.String()),
   175  				},
   176  			},
   177  		},
   178  	})
   179  }