diff --git a/pkg/registry/apis/iam/authorizer/resource_permissions.go b/pkg/registry/apis/iam/authorizer/resource_permissions.go index 0fbf413adac..098037c93b7 100644 --- a/pkg/registry/apis/iam/authorizer/resource_permissions.go +++ b/pkg/registry/apis/iam/authorizer/resource_permissions.go @@ -179,19 +179,17 @@ func (r *ResourcePermissionsAuthorizer) FilterList(ctx context.Context, list run canViewFuncs = map[schema.GroupResource]types.ItemChecker{} ) for _, item := range l.Items { - gr := schema.GroupResource{ - Group: item.Spec.Resource.ApiGroup, - Resource: item.Spec.Resource.Resource, - } + target := item.Spec.Resource + targetGR := schema.GroupResource{Group: target.ApiGroup, Resource: target.Resource} // Reuse the same canView for items with the same resource - canView, found := canViewFuncs[gr] + canView, found := canViewFuncs[targetGR] if !found { listReq := types.ListRequest{ Namespace: item.Namespace, - Group: item.Spec.Resource.ApiGroup, - Resource: item.Spec.Resource.Resource, + Group: target.ApiGroup, + Resource: target.Resource, Verb: utils.VerbGetPermissions, } @@ -200,12 +198,9 @@ func (r *ResourcePermissionsAuthorizer) FilterList(ctx context.Context, list run return nil, err } - canViewFuncs[gr] = canView + canViewFuncs[targetGR] = canView } - target := item.Spec.Resource - targetGR := schema.GroupResource{Group: target.ApiGroup, Resource: target.Resource} - parent := "" // Fetch the parent of the resource // It's not efficient to do for every item in the list, but it's a good starting point. diff --git a/pkg/registry/apis/iam/register.go b/pkg/registry/apis/iam/register.go index ea1b1225f41..63fc7253e8a 100644 --- a/pkg/registry/apis/iam/register.go +++ b/pkg/registry/apis/iam/register.go @@ -246,6 +246,8 @@ func (b *IdentityAccessManagementAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *ge //nolint:staticcheck // not yet migrated to OpenFeature enableZanzanaSync := b.features.IsEnabledGlobally(featuremgmt.FlagKubernetesAuthzZanzanaSync) + //nolint:staticcheck // not yet migrated to OpenFeature + enableAuthzApis := b.features.IsEnabledGlobally(featuremgmt.FlagKubernetesAuthzApis) // teams + users must have shorter names because they are often used as part of another name opts.StorageOptsRegister(iamv0.TeamResourceInfo.GroupResource(), apistore.StorageOptions{ @@ -255,6 +257,60 @@ func (b *IdentityAccessManagementAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *ge MaximumNameLength: 80, }) + if err := b.UpdateTeamsAPIGroup(opts, storage); err != nil { + return err + } + + if err := b.UpdateTeamBindingsAPIGroup(opts, storage, enableZanzanaSync); err != nil { + return err + } + + if err := b.UpdateUsersAPIGroup(opts, storage, enableZanzanaSync); err != nil { + return err + } + + if err := b.UpdateServiceAccountsAPIGroup(opts, storage); err != nil { + return err + } + + // SSO settings apis + if b.ssoLegacyStore != nil { + ssoResource := legacyiamv0.SSOSettingResourceInfo + storage[ssoResource.StoragePath()] = b.ssoLegacyStore + } + + if err := b.UpdateExternalGroupMappingAPIGroup(apiGroupInfo, opts, storage); err != nil { + return err + } + + if enableAuthzApis { + // v0alpha1 + if err := b.UpdateCoreRolesAPIGroup(apiGroupInfo, opts, storage, enableZanzanaSync); err != nil { + return err + } + + // Role registration is delegated to the RoleApiInstaller + if err := b.roleApiInstaller.RegisterStorage(apiGroupInfo, &opts, storage); err != nil { + return err + } + + if err := b.UpdateRoleBindingsAPIGroup(apiGroupInfo, opts, storage, enableZanzanaSync); err != nil { + return err + } + } + + //nolint:staticcheck // not yet migrated to OpenFeature + if b.features.IsEnabledGlobally(featuremgmt.FlagKubernetesAuthzResourcePermissionApis) { + if err := b.UpdateResourcePermissionsAPIGroup(apiGroupInfo, opts, storage, enableZanzanaSync); err != nil { + return err + } + } + + apiGroupInfo.VersionedResourcesStorageMap[legacyiamv0.VERSION] = storage + return nil +} + +func (b *IdentityAccessManagementAPIBuilder) UpdateTeamsAPIGroup(opts builder.APIGroupOptions, storage map[string]rest.Storage) error { teamResource := iamv0.TeamResourceInfo teamUniStore, err := grafanaregistry.NewRegistryStore(opts.Scheme, teamResource, opts.OptsGetter) if err != nil { @@ -276,6 +332,10 @@ func (b *IdentityAccessManagementAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *ge storage[teamResource.StoragePath("groups")] = b.teamGroupsHandler } + return nil +} + +func (b *IdentityAccessManagementAPIBuilder) UpdateTeamBindingsAPIGroup(opts builder.APIGroupOptions, storage map[string]rest.Storage, enableZanzanaSync bool) error { teamBindingResource := iamv0.TeamBindingResourceInfo teamBindingUniStore, err := grafanaregistry.NewRegistryStore(opts.Scheme, teamBindingResource, opts.OptsGetter) if err != nil { @@ -298,8 +358,10 @@ func (b *IdentityAccessManagementAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *ge } storage[teamBindingResource.StoragePath()] = dw } + return nil +} - // User store registration +func (b *IdentityAccessManagementAPIBuilder) UpdateUsersAPIGroup(opts builder.APIGroupOptions, storage map[string]rest.Storage, enableZanzanaSync bool) error { userResource := iamv0.UserResourceInfo userUniStore, err := grafanaregistry.NewRegistryStore(opts.Scheme, userResource, opts.OptsGetter) if err != nil { @@ -325,7 +387,10 @@ func (b *IdentityAccessManagementAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *ge storage[userResource.StoragePath("teams")] = user.NewLegacyTeamMemberREST(b.store) - // Service Accounts store registration + return nil +} + +func (b *IdentityAccessManagementAPIBuilder) UpdateServiceAccountsAPIGroup(opts builder.APIGroupOptions, storage map[string]rest.Storage) error { saResource := iamv0.ServiceAccountResourceInfo saUniStore, err := grafanaregistry.NewRegistryStore(opts.Scheme, saResource, opts.OptsGetter) if err != nil { @@ -343,11 +408,10 @@ func (b *IdentityAccessManagementAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *ge storage[saResource.StoragePath("tokens")] = serviceaccount.NewLegacyTokenREST(b.store) - if b.ssoLegacyStore != nil { - ssoResource := legacyiamv0.SSOSettingResourceInfo - storage[ssoResource.StoragePath()] = b.ssoLegacyStore - } + return nil +} +func (b *IdentityAccessManagementAPIBuilder) UpdateExternalGroupMappingAPIGroup(apiGroupInfo *genericapiserver.APIGroupInfo, opts builder.APIGroupOptions, storage map[string]rest.Storage) error { extGroupMappingResource := iamv0.ExternalGroupMappingResourceInfo extGroupMappingUniStore, err := grafanaregistry.NewRegistryStore(opts.Scheme, extGroupMappingResource, opts.OptsGetter) if err != nil { @@ -376,48 +440,47 @@ func (b *IdentityAccessManagementAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *ge authzWrapper := storewrapper.New(extGroupMappingStore, iamauthorizer.NewExternalGroupMappingAuthorizer(b.accessClient)) storage[extGroupMappingResource.StoragePath()] = authzWrapper + return nil +} - //nolint:staticcheck // not yet migrated to OpenFeature - if b.features.IsEnabledGlobally(featuremgmt.FlagKubernetesAuthzApis) { - // v0alpha1 - coreRoleStore, err := NewLocalStore(iamv0.CoreRoleInfo, apiGroupInfo.Scheme, opts.OptsGetter, b.reg, b.accessClient, b.coreRolesStorage) - if err != nil { - return err - } - if enableZanzanaSync { - b.logger.Info("Enabling hooks for CoreRole to sync to Zanzana") - h := NewRoleHooks(b.zClient, b.zTickets, b.logger) - coreRoleStore.AfterCreate = h.AfterRoleCreate - coreRoleStore.AfterDelete = h.AfterRoleDelete - coreRoleStore.BeginUpdate = h.BeginRoleUpdate - } - storage[iamv0.CoreRoleInfo.StoragePath()] = coreRoleStore - - // Role registration is delegated to the RoleApiInstaller - if err := b.roleApiInstaller.RegisterStorage(apiGroupInfo, &opts, storage); err != nil { - return err - } - - roleBindingStore, err := NewLocalStore(iamv0.RoleBindingInfo, apiGroupInfo.Scheme, opts.OptsGetter, b.reg, b.accessClient, b.roleBindingsStorage) - if err != nil { - return err - } - if enableZanzanaSync { - b.logger.Info("Enabling hooks for RoleBinding to sync to Zanzana") - roleBindingStore.AfterCreate = b.AfterRoleBindingCreate - roleBindingStore.AfterDelete = b.AfterRoleBindingDelete - roleBindingStore.BeginUpdate = b.BeginRoleBindingUpdate - } - storage[iamv0.RoleBindingInfo.StoragePath()] = roleBindingStore +func (b *IdentityAccessManagementAPIBuilder) UpdateCoreRolesAPIGroup( + apiGroupInfo *genericapiserver.APIGroupInfo, + opts builder.APIGroupOptions, + storage map[string]rest.Storage, + enableZanzanaSync bool, +) error { + coreRoleStore, err := NewLocalStore(iamv0.CoreRoleInfo, apiGroupInfo.Scheme, opts.OptsGetter, b.reg, b.accessClient, b.coreRolesStorage) + if err != nil { + return err } - //nolint:staticcheck // not yet migrated to OpenFeature - if b.features.IsEnabledGlobally(featuremgmt.FlagKubernetesAuthzResourcePermissionApis) { - if err := b.UpdateResourcePermissionsAPIGroup(apiGroupInfo, opts, storage, enableZanzanaSync); err != nil { - return err - } + if enableZanzanaSync { + b.logger.Info("Enabling hooks for CoreRole to sync to Zanzana") + h := NewRoleHooks(b.zClient, b.zTickets, b.logger) + coreRoleStore.AfterCreate = h.AfterRoleCreate + coreRoleStore.AfterDelete = h.AfterRoleDelete + coreRoleStore.BeginUpdate = h.BeginRoleUpdate } + storage[iamv0.CoreRoleInfo.StoragePath()] = coreRoleStore + return nil +} - apiGroupInfo.VersionedResourcesStorageMap[legacyiamv0.VERSION] = storage +func (b *IdentityAccessManagementAPIBuilder) UpdateRoleBindingsAPIGroup( + apiGroupInfo *genericapiserver.APIGroupInfo, + opts builder.APIGroupOptions, + storage map[string]rest.Storage, + enableZanzanaSync bool, +) error { + roleBindingStore, err := NewLocalStore(iamv0.RoleBindingInfo, apiGroupInfo.Scheme, opts.OptsGetter, b.reg, b.accessClient, b.roleBindingsStorage) + if err != nil { + return err + } + if enableZanzanaSync { + b.logger.Info("Enabling hooks for RoleBinding to sync to Zanzana") + roleBindingStore.AfterCreate = b.AfterRoleBindingCreate + roleBindingStore.AfterDelete = b.AfterRoleBindingDelete + roleBindingStore.BeginUpdate = b.BeginRoleBindingUpdate + } + storage[iamv0.RoleBindingInfo.StoragePath()] = roleBindingStore return nil }