opencloud icon indicating copy to clipboard operation
opencloud copied to clipboard

every settings service start writes the role bundles to system storage

Open butonic opened this issue 1 month ago • 0 comments

Describe the bug

Whenever we start the settings service it writes the configured role bundles to the system storage:

// we need to lazy initialize the MetadataClient because metadata service might not be ready
func (s *Store) initMetadataClient(mdc MetadataClient) error {
	ctx := context.TODO()
	err := mdc.Init(ctx, settingsSpaceID)
	if err != nil {
		return err
	}

	for _, p := range []string{
		rootFolderLocation,
		accountsFolderLocation,
		bundleFolderLocation,
		valuesFolderLocation,
	} {
		err = mdc.MakeDirIfNotExist(ctx, p)
		if err != nil {
			return err
		}
	}

	for _, p := range s.cfg.Bundles {
		b, err := json.Marshal(p)
		if err != nil {
			return err
		}
		err = mdc.SimpleUpload(ctx, bundlePath(p.Id), b)
		if err != nil {
			return err
		}
	}

	for _, p := range defaults.DefaultRoleAssignments(s.cfg) {
		accountUUID := p.AccountUuid
		roleID := p.RoleId
		err = mdc.MakeDirIfNotExist(ctx, accountPath(accountUUID))
		if err != nil {
			return err
		}

		assIDs, err := mdc.ReadDir(ctx, accountPath(accountUUID))
		if err != nil {
			return err
		}

		adminUserID := accountUUID == s.cfg.AdminUserID
		if len(assIDs) > 0 && !adminUserID {
			// There is already a role assignment for this ID, skip to the next
			continue
		}
		// for the adminUserID we need to check if the user has the admin role every time
		if adminUserID {
			err = s.userMustHaveAdminRole(accountUUID, assIDs, mdc)
			if err != nil {
				return err
			}
			continue
		}

		ass := &settingsmsg.UserRoleAssignment{
			Id:          uuid.NewString(),
			AccountUuid: accountUUID,
			RoleId:      roleID,
		}

		b, err := json.Marshal(ass)
		if err != nil {
			return err
		}
		err = mdc.SimpleUpload(ctx, assignmentPath(accountUUID, ass.Id), b)
		if err != nil {
			return err
		}
	}

	s.mdc = mdc
	return nil
}

The s.cfg.Bundles is filled either with the built in default or the ones configured with: SETTINGS_BUNDLES_PATH

Looking at the settings code we seem to always read the roles from the settings sevice:

// ListRoles implements the RoleServiceHandler interface
func (g Service) ListRoles(_ context.Context, req *settingssvc.ListBundlesRequest, res *settingssvc.ListBundlesResponse) error {
	//accountUUID := getValidatedAccountUUID(c, "me")
	if validationError := validateListRoles(req); validationError != nil {
		return merrors.BadRequest(g.id, "%s", validationError)
	}
	r, err := g.manager.ListBundles(settingsmsg.Bundle_TYPE_ROLE, req.GetBundleIds())
	if err != nil {
		return merrors.NotFound(g.id, "%s", err)
	}
	// TODO: only allow listing roles when user has account/role/... management permissions
	res.Bundles = r
	return nil
}

The ListBundles the calls the system storage:

// ListBundles returns all bundles in the dataPath folder that match the given type.
func (s *Store) ListBundles(bundleType settingsmsg.Bundle_Type, bundleIDs []string) ([]*settingsmsg.Bundle, error) {
	s.Init()
	ctx := context.TODO()

	if len(bundleIDs) == 0 {
		bIDs, err := s.mdc.ReadDir(ctx, bundleFolderLocation)
		switch err.(type) {
		case nil:
			// continue
		case errtypes.NotFound:
			return make([]*settingsmsg.Bundle, 0), nil
		default:
			return nil, err
		}

		bundleIDs = bIDs
	}
	var bundles []*settingsmsg.Bundle
	for _, id := range bundleIDs {
		if id == defaults.BundleUUIDServiceAccount {
			bundles = append(bundles, defaults.ServiceAccountBundle())
			continue
		}
		b, err := s.mdc.SimpleDownload(ctx, bundlePath(id))
		switch err.(type) {
		case nil:
			// continue
		case errtypes.NotFound:
			continue
		default:
			return nil, err
		}

		bundle := &settingsmsg.Bundle{}
		err = json.Unmarshal(b, bundle)
		if err != nil {
			return nil, err
		}

		if bundle.Type == bundleType {
			bundles = append(bundles, bundle)
		}

	}
	return bundles, nil
}

AFAICT we could just server the role bundles from the config ... no need to read from/write to systems storage.

butonic avatar Nov 25 '25 10:11 butonic