Compare commits
5 Commits
main
...
defer_reso
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99c5db9a2e | ||
|
|
b0abeefa28 | ||
|
|
02b8262ed9 | ||
|
|
3e992ee802 | ||
|
|
5a50627386 |
@ -39,7 +39,7 @@ type Controller struct {
|
||||
tenant string
|
||||
credentials account.M365Config
|
||||
|
||||
ownerLookup idname.GetResourceIDAndNamer
|
||||
resourceHandler idname.GetResourceIDAndNamer
|
||||
// maps of resource owner ids to names, and names to ids.
|
||||
// not guaranteed to be populated, only here as a post-population
|
||||
// reference for processes that choose to populate the values.
|
||||
@ -83,43 +83,22 @@ func NewController(
|
||||
return nil, clues.Wrap(err, "creating api client").WithClues(ctx)
|
||||
}
|
||||
|
||||
var rCli *resourceClient
|
||||
|
||||
// no failure for unknown service.
|
||||
// In that case we create a controller that doesn't attempt to look up any resource
|
||||
// data. This case helps avoid unnecessary service calls when the end user is running
|
||||
// repo init and connect commands via the CLI. All other callers should be expected
|
||||
// to pass in a known service, or else expect downstream failures.
|
||||
if pst != path.UnknownService {
|
||||
rc := resource.UnknownResource
|
||||
|
||||
switch pst {
|
||||
case path.ExchangeService, path.OneDriveService:
|
||||
rc = resource.Users
|
||||
case path.GroupsService:
|
||||
rc = resource.Groups
|
||||
case path.SharePointService:
|
||||
rc = resource.Sites
|
||||
}
|
||||
|
||||
rCli, err = getResourceClient(rc, ac)
|
||||
if err != nil {
|
||||
return nil, clues.Wrap(err, "creating resource client").WithClues(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
ctrl := Controller{
|
||||
AC: ac,
|
||||
IDNameLookup: idname.NewCache(nil),
|
||||
|
||||
credentials: creds,
|
||||
ownerLookup: rCli,
|
||||
tenant: acct.ID(),
|
||||
wg: &sync.WaitGroup{},
|
||||
backupDriveIDNames: idname.NewCache(nil),
|
||||
backupSiteIDWebURL: idname.NewCache(nil),
|
||||
}
|
||||
|
||||
// TODO: remove in favor of calling setResourceHandler in the newServiceHandler once
|
||||
// all operations types are populated. When we do that, we can also remove pst from
|
||||
// the func params in this call.
|
||||
ctrl.setResourceHandler(pst)
|
||||
|
||||
return &ctrl, nil
|
||||
}
|
||||
|
||||
@ -127,6 +106,32 @@ func (ctrl *Controller) VerifyAccess(ctx context.Context) error {
|
||||
return ctrl.AC.Access().GetToken(ctx)
|
||||
}
|
||||
|
||||
func (ctrl *Controller) setResourceHandler(
|
||||
serviceInOperation path.ServiceType,
|
||||
) {
|
||||
var rh *resourceGetter
|
||||
|
||||
switch serviceInOperation {
|
||||
case path.ExchangeService, path.OneDriveService:
|
||||
rh = &resourceGetter{
|
||||
enum: resource.Users,
|
||||
getter: ctrl.AC.Users(),
|
||||
}
|
||||
case path.GroupsService:
|
||||
rh = &resourceGetter{
|
||||
enum: resource.Sites,
|
||||
getter: ctrl.AC.Sites(),
|
||||
}
|
||||
case path.SharePointService:
|
||||
rh = &resourceGetter{
|
||||
enum: resource.Groups,
|
||||
getter: ctrl.AC.Groups(),
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.resourceHandler = rh
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Processing Status
|
||||
// ---------------------------------------------------------------------------
|
||||
@ -203,20 +208,9 @@ func (ctrl *Controller) CacheItemInfo(dii details.ItemInfo) {
|
||||
// Resource Lookup Handling
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
func getResourceClient(rc resource.Category, ac api.Client) (*resourceClient, error) {
|
||||
switch rc {
|
||||
case resource.Users:
|
||||
return &resourceClient{enum: rc, getter: ac.Users()}, nil
|
||||
case resource.Sites:
|
||||
return &resourceClient{enum: rc, getter: ac.Sites()}, nil
|
||||
case resource.Groups:
|
||||
return &resourceClient{enum: rc, getter: ac.Groups()}, nil
|
||||
default:
|
||||
return nil, clues.New("unrecognized owner resource type").With("resource_enum", rc)
|
||||
}
|
||||
}
|
||||
var _ idname.GetResourceIDAndNamer = &resourceGetter{}
|
||||
|
||||
type resourceClient struct {
|
||||
type resourceGetter struct {
|
||||
enum resource.Category
|
||||
getter getIDAndNamer
|
||||
}
|
||||
@ -233,15 +227,13 @@ type getIDAndNamer interface {
|
||||
)
|
||||
}
|
||||
|
||||
var _ idname.GetResourceIDAndNamer = &resourceClient{}
|
||||
|
||||
// GetResourceIDAndNameFrom looks up the resource's canonical id and display name.
|
||||
// If the resource is present in the idNameSwapper, then that interface's id and
|
||||
// name values are returned. As a fallback, the resource calls the discovery
|
||||
// api to fetch the user or site using the resource value. This fallback assumes
|
||||
// that the resource is a well formed ID or display name of appropriate design
|
||||
// (PrincipalName for users, WebURL for sites).
|
||||
func (r resourceClient) GetResourceIDAndNameFrom(
|
||||
func (r resourceGetter) GetResourceIDAndNameFrom(
|
||||
ctx context.Context,
|
||||
owner string,
|
||||
ins idname.Cacher,
|
||||
@ -294,11 +286,11 @@ func (ctrl *Controller) PopulateProtectedResourceIDAndName(
|
||||
resourceID string, // input value, can be either id or name
|
||||
ins idname.Cacher,
|
||||
) (idname.Provider, error) {
|
||||
if ctrl.ownerLookup == nil {
|
||||
if ctrl.resourceHandler == nil {
|
||||
return nil, clues.Stack(ErrNoResourceLookup).WithClues(ctx)
|
||||
}
|
||||
|
||||
pr, err := ctrl.ownerLookup.GetResourceIDAndNameFrom(ctx, resourceID, ins)
|
||||
pr, err := ctrl.resourceHandler.GetResourceIDAndNameFrom(ctx, resourceID, ins)
|
||||
if err != nil {
|
||||
return nil, clues.Wrap(err, "identifying resource owner")
|
||||
}
|
||||
|
||||
@ -57,18 +57,18 @@ func (suite *ControllerUnitSuite) TestPopulateOwnerIDAndNamesFrom() {
|
||||
var (
|
||||
itn = map[string]string{id: name}
|
||||
nti = map[string]string{name: id}
|
||||
lookup = &resourceClient{
|
||||
lookup = &resourceGetter{
|
||||
enum: resource.Users,
|
||||
getter: &mock.IDNameGetter{ID: id, Name: name},
|
||||
}
|
||||
noLookup = &resourceClient{enum: resource.Users, getter: &mock.IDNameGetter{}}
|
||||
noLookup = &resourceGetter{enum: resource.Users, getter: &mock.IDNameGetter{}}
|
||||
)
|
||||
|
||||
table := []struct {
|
||||
name string
|
||||
protectedResource string
|
||||
ins inMock.Cache
|
||||
rc *resourceClient
|
||||
rc *resourceGetter
|
||||
expectID string
|
||||
expectName string
|
||||
expectErr require.ErrorAssertionFunc
|
||||
@ -238,7 +238,7 @@ func (suite *ControllerUnitSuite) TestPopulateOwnerIDAndNamesFrom() {
|
||||
ctx, flush := tester.NewContext(t)
|
||||
defer flush()
|
||||
|
||||
ctrl := &Controller{ownerLookup: test.rc}
|
||||
ctrl := &Controller{resourceHandler: test.rc}
|
||||
|
||||
resource, err := ctrl.PopulateProtectedResourceIDAndName(ctx, test.protectedResource, test.ins)
|
||||
test.expectErr(t, err, clues.ToCore(err))
|
||||
@ -260,7 +260,7 @@ func (suite *ControllerUnitSuite) TestPopulateOwnerIDAndNamesFrom_nilCheck() {
|
||||
ctx, flush := tester.NewContext(t)
|
||||
defer flush()
|
||||
|
||||
ctrl := &Controller{ownerLookup: nil}
|
||||
ctrl := &Controller{resourceHandler: nil}
|
||||
|
||||
_, err := ctrl.PopulateProtectedResourceIDAndName(ctx, "", nil)
|
||||
require.ErrorIs(t, err, ErrNoResourceLookup, clues.ToCore(err))
|
||||
|
||||
@ -17,6 +17,11 @@ func (ctrl *Controller) NewServiceHandler(
|
||||
opts control.Options,
|
||||
service path.ServiceType,
|
||||
) (inject.ServiceHandler, error) {
|
||||
// currently a no-op, since export doesn't look up any resources.
|
||||
// but we want it set in place at the head of a NewServiceHandler
|
||||
// as a standard behavior.
|
||||
ctrl.setResourceHandler(service)
|
||||
|
||||
switch service {
|
||||
case path.OneDriveService:
|
||||
return onedrive.NewOneDriveHandler(opts), nil
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user