2024-01-24 10:37:48 +01:00
|
|
|
package auth
|
2020-03-11 18:14:23 -07:00
|
|
|
|
|
|
|
import (
|
2022-11-29 14:59:40 +01:00
|
|
|
"context"
|
2024-08-20 01:55:32 -07:00
|
|
|
"fmt"
|
|
|
|
"strings"
|
2022-11-29 14:59:40 +01:00
|
|
|
|
2020-03-17 11:05:20 -07:00
|
|
|
"github.com/go-logr/logr"
|
2020-10-07 11:12:31 -07:00
|
|
|
"github.com/kyverno/kyverno/pkg/auth"
|
2022-08-31 14:03:47 +08:00
|
|
|
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
2020-03-11 18:14:23 -07:00
|
|
|
)
|
|
|
|
|
2024-08-20 01:55:32 -07:00
|
|
|
// AuthChecks provides methods to performing operations on resource
|
|
|
|
type AuthChecks interface {
|
|
|
|
// User returns the subject
|
|
|
|
User() string
|
|
|
|
// CanI returns 'true' if user has permissions for all specified verbs.
|
|
|
|
// When the result is 'false' a message with details on missing verbs is returned.
|
|
|
|
CanI(ctx context.Context, verbs []string, gvk, namespace, name, subresource string) (bool, string, error)
|
2020-03-11 18:14:23 -07:00
|
|
|
}
|
|
|
|
|
2022-05-17 08:19:03 +02:00
|
|
|
// Auth provides implementation to check if caller/self/kyverno has access to perofrm operations
|
2020-03-11 18:14:23 -07:00
|
|
|
type Auth struct {
|
2022-05-03 07:30:04 +02:00
|
|
|
client dclient.Interface
|
2023-04-24 18:31:42 +08:00
|
|
|
user string
|
2020-03-17 11:05:20 -07:00
|
|
|
log logr.Logger
|
2020-03-11 18:14:23 -07:00
|
|
|
}
|
|
|
|
|
2022-05-17 08:19:03 +02:00
|
|
|
// NewAuth returns a new instance of Auth for operations
|
2023-04-24 18:31:42 +08:00
|
|
|
func NewAuth(client dclient.Interface, user string, log logr.Logger) *Auth {
|
2020-03-11 18:14:23 -07:00
|
|
|
a := Auth{
|
|
|
|
client: client,
|
2023-04-24 18:31:42 +08:00
|
|
|
user: user,
|
2020-03-17 11:05:20 -07:00
|
|
|
log: log,
|
2020-03-11 18:14:23 -07:00
|
|
|
}
|
|
|
|
return &a
|
|
|
|
}
|
|
|
|
|
2024-08-20 01:55:32 -07:00
|
|
|
func (a *Auth) User() string {
|
|
|
|
return a.user
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *Auth) CanI(ctx context.Context, verbs []string, gvk, namespace, name, subresource string) (bool, string, error) {
|
|
|
|
var failedVerbs []string
|
|
|
|
for _, v := range verbs {
|
|
|
|
if ok, err := a.check(ctx, v, gvk, namespace, name, subresource); err != nil {
|
|
|
|
return false, "", err
|
|
|
|
} else if !ok {
|
|
|
|
failedVerbs = append(failedVerbs, v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(failedVerbs) > 0 {
|
|
|
|
msg := buildMessage(gvk, subresource, failedVerbs, a.user, namespace)
|
|
|
|
return false, msg, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return true, "", nil
|
|
|
|
}
|
|
|
|
|
2020-03-11 18:14:23 -07:00
|
|
|
// CanICreate returns 'true' if self can 'create' resource
|
2024-08-07 17:09:16 +03:00
|
|
|
func (a *Auth) CanICreate(ctx context.Context, gvk, namespace, name, subresource string) (bool, error) {
|
2024-08-20 01:55:32 -07:00
|
|
|
return a.check(ctx, "create", gvk, namespace, name, subresource)
|
2020-03-11 18:14:23 -07:00
|
|
|
}
|
|
|
|
|
2024-08-20 01:55:32 -07:00
|
|
|
func (a *Auth) check(ctx context.Context, verb, gvk, namespace, name, subresource string) (bool, error) {
|
|
|
|
subjectReview := a.client.GetKubeClient().AuthorizationV1().SubjectAccessReviews()
|
|
|
|
canI := auth.NewCanI(a.client.Discovery(), subjectReview, gvk, namespace, name, verb, subresource, a.user)
|
2023-09-05 13:16:50 +03:00
|
|
|
ok, _, err := canI.RunAccessCheck(ctx)
|
2020-03-11 18:14:23 -07:00
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
return ok, nil
|
|
|
|
}
|
|
|
|
|
2024-08-20 01:55:32 -07:00
|
|
|
func buildMessage(gvk string, subresource string, failedVerbs []string, user string, namespace string) string {
|
|
|
|
resource := gvk
|
|
|
|
if subresource != "" {
|
|
|
|
resource = gvk + "/" + subresource
|
2020-03-11 18:14:23 -07:00
|
|
|
}
|
|
|
|
|
2024-08-20 01:55:32 -07:00
|
|
|
permissions := strings.Join(failedVerbs, ",")
|
|
|
|
msg := fmt.Sprintf("%s requires permissions %s for resource %s", user, permissions, resource)
|
|
|
|
if namespace != "" {
|
|
|
|
msg = fmt.Sprintf("%s in namespace %s", msg, namespace)
|
2020-03-11 18:14:23 -07:00
|
|
|
}
|
2024-08-20 01:55:32 -07:00
|
|
|
return msg
|
2020-03-11 18:14:23 -07:00
|
|
|
}
|