diff --git a/pkg/models/tenant/tenant.go b/pkg/models/tenant/tenant.go index 1f1f200e7350751189de0d426605b21e231454a4..8b7c18274c703ecd41fdab42e9782864c72cafa0 100644 --- a/pkg/models/tenant/tenant.go +++ b/pkg/models/tenant/tenant.go @@ -557,14 +557,13 @@ func (t *tenantOperator) DeleteWorkspace(workspace string) error { return t.ksclient.TenantV1alpha2().WorkspaceTemplates().Delete(workspace, metav1.NewDeleteOptions(0)) } -// listIntersectedNamespaces lists the namespaces which meet all the following conditions at the same time -// 1. the namespace which belongs to user. -// 2. the namespace in workspace which is in workspaces when workspaces is not empty. -// 3. the namespace in workspace which contains one of workspaceSubstrs when workspaceSubstrs is not empty. -// 4. the namespace which is in namespaces when namespaces is not empty. -// 5. the namespace which contains one of namespaceSubstrs when namespaceSubstrs is not empty. -func (t *tenantOperator) listIntersectedNamespaces(user user.Info, - workspaces, workspaceSubstrs, namespaces, namespaceSubstrs []string) ([]*corev1.Namespace, error) { +// listIntersectedNamespaces returns a list of namespaces that MUST meet ALL the following filters: +// 1. If `workspaces` is not empty, the namespace SHOULD belong to one of the specified workpsaces. +// 2. If `workspaceSubstrs` is not empty, the namespace SHOULD belong to a workspace whose name contains one of the specified substrings. +// 3. If `namespaces` is not empty, the namespace SHOULD be one of the specified namespacs. +// 4. If `namespaceSubstrs` is not empty, the namespace's name SHOULD contain one of the specified substrings. +func (t *tenantOperator) listIntersectedNamespaces(workspaces, workspaceSubstrs, + namespaces, namespaceSubstrs []string) ([]*corev1.Namespace, error) { var ( namespaceSet = stringSet(namespaces) workspaceSet = stringSet(workspaces) @@ -573,7 +572,7 @@ func (t *tenantOperator) listIntersectedNamespaces(user user.Info, ) includeNsWithoutWs := len(workspaceSet) == 0 && len(workspaceSubstrs) == 0 - result, err := t.ListNamespaces(user, "", query.New()) + result, err := t.resourceGetter.List("namespaces", "", query.New()) if err != nil { return nil, err } @@ -609,7 +608,7 @@ func (t *tenantOperator) listIntersectedNamespaces(user user.Info, } func (t *tenantOperator) Events(user user.Info, queryParam *eventsv1alpha1.Query) (*eventsv1alpha1.APIResponse, error) { - iNamespaces, err := t.listIntersectedNamespaces(user, + iNamespaces, err := t.listIntersectedNamespaces( stringutils.Split(queryParam.WorkspaceFilter, ","), stringutils.Split(queryParam.WorkspaceSearch, ","), stringutils.Split(queryParam.InvolvedObjectNamespaceFilter, ","), @@ -670,7 +669,7 @@ func (t *tenantOperator) Events(user user.Info, queryParam *eventsv1alpha1.Query } func (t *tenantOperator) QueryLogs(user user.Info, query *loggingv1alpha2.Query) (*loggingv1alpha2.APIResponse, error) { - iNamespaces, err := t.listIntersectedNamespaces(user, + iNamespaces, err := t.listIntersectedNamespaces( stringutils.Split(query.WorkspaceFilter, ","), stringutils.Split(query.WorkspaceSearch, ","), stringutils.Split(query.NamespaceFilter, ","), @@ -741,7 +740,7 @@ func (t *tenantOperator) QueryLogs(user user.Info, query *loggingv1alpha2.Query) } func (t *tenantOperator) ExportLogs(user user.Info, query *loggingv1alpha2.Query, writer io.Writer) error { - iNamespaces, err := t.listIntersectedNamespaces(user, + iNamespaces, err := t.listIntersectedNamespaces( stringutils.Split(query.WorkspaceFilter, ","), stringutils.Split(query.WorkspaceSearch, ","), stringutils.Split(query.NamespaceFilter, ","), @@ -795,7 +794,7 @@ func (t *tenantOperator) ExportLogs(user user.Info, query *loggingv1alpha2.Query } func (t *tenantOperator) Auditing(user user.Info, queryParam *auditingv1alpha1.Query) (*auditingv1alpha1.APIResponse, error) { - iNamespaces, err := t.listIntersectedNamespaces(user, + iNamespaces, err := t.listIntersectedNamespaces( stringutils.Split(queryParam.WorkspaceFilter, ","), stringutils.Split(queryParam.WorkspaceSearch, ","), stringutils.Split(queryParam.ObjectRefNamespaceFilter, ","), @@ -806,21 +805,43 @@ func (t *tenantOperator) Auditing(user user.Info, queryParam *auditingv1alpha1.Q } namespaceCreateTimeMap := make(map[string]time.Time) + + // Now auditing and event have the same authorization mechanism, so we can determine whether the user + // has permission to view the auditing log in ns by judging whether the user has the permission to view the event in ns. for _, ns := range iNamespaces { - namespaceCreateTimeMap[ns.Name] = ns.CreationTimestamp.Time + listEvts := authorizer.AttributesRecord{ + User: user, + Verb: "list", + APIGroup: "", + APIVersion: "v1", + Namespace: ns.Name, + Resource: "events", + ResourceRequest: true, + ResourceScope: request.NamespaceScope, + } + decision, _, err := t.authorizer.Authorize(listEvts) + if err != nil { + klog.Error(err) + return nil, err + } + if decision == authorizer.DecisionAllow { + namespaceCreateTimeMap[ns.Name] = ns.CreationTimestamp.Time + } } // If there are no ns and ws query conditions, - // those events with empty `ObjectRef.Namespace` will also be listed when user can list all namespaces + // those events with empty `objectRef.namespace` will also be listed when user can list all events if len(queryParam.WorkspaceFilter) == 0 && len(queryParam.ObjectRefNamespaceFilter) == 0 && len(queryParam.WorkspaceSearch) == 0 && len(queryParam.ObjectRefNamespaceSearch) == 0 { - listNs := authorizer.AttributesRecord{ + listEvts := authorizer.AttributesRecord{ User: user, Verb: "list", - Resource: "namespaces", + APIGroup: "", + APIVersion: "v1", + Resource: "events", ResourceRequest: true, ResourceScope: request.ClusterScope, } - decision, _, err := t.authorizer.Authorize(listNs) + decision, _, err := t.authorizer.Authorize(listEvts) if err != nil { klog.Error(err) return nil, err