Skip to content

Commit

Permalink
Create allowIfNonSandboxUser to remove duplicate code
Browse files Browse the repository at this point in the history
Signed-off-by: David Kwon <[email protected]>
  • Loading branch information
dkwon17 committed Nov 2, 2023
1 parent ee3efe6 commit 6bd5dc9
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 74 deletions.
39 changes: 39 additions & 0 deletions pkg/webhook/validatingwebhook/validate.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
package validatingwebhook

import (
"context"
"encoding/json"
"html"
"strings"

toolchainv1alpha1 "github.com/codeready-toolchain/api/api/v1alpha1"
userv1 "github.com/openshift/api/user/v1"
"github.com/pkg/errors"
admissionv1 "k8s.io/api/admission/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/types"
runtimeClient "sigs.k8s.io/controller-runtime/pkg/client"
logf "sigs.k8s.io/controller-runtime/pkg/log"
)

Expand All @@ -18,6 +26,37 @@ var (
log = logf.Log.WithName("validating_webhook")
)

func allowIfNonSandboxUser(body []byte, client *runtimeClient.Client) []byte {
admReview := admissionv1.AdmissionReview{}
if _, _, err := deserializer.Decode(body, nil, &admReview); err != nil {
// sanitize the body
escapedBody := html.EscapeString(string(body))
log.Error(err, "unable to deserialize the admission review object", "body", escapedBody)
return denyAdmissionRequest(admReview, errors.Wrapf(err, "unable to deserialize the admission review object - body: %v", escapedBody))
}
requestingUsername := admReview.Request.UserInfo.Username
// allow admission request if the user is a system user
if strings.HasPrefix(requestingUsername, "system:") {
return allowAdmissionRequest(admReview)
}
//check if the requesting user is a sandbox user
requestingUser := &userv1.User{}
err := (*client).Get(context.TODO(), types.NamespacedName{
Name: admReview.Request.UserInfo.Username,
}, requestingUser)

if err != nil {
log.Error(err, "unable to find the user requesting creation of the "+admReview.Request.Kind.Kind+" resource", "username", admReview.Request.UserInfo.Username)
return denyAdmissionRequest(admReview, errors.Errorf("unable to find the user requesting the creation of the %s resource", admReview.Request.Kind.Kind))
}
if requestingUser.GetLabels()[toolchainv1alpha1.ProviderLabelKey] == toolchainv1alpha1.ProviderLabelValue {
log.Info("sandbox user is trying to create a "+admReview.Request.Kind.Kind, "AdmissionReview", admReview)
return denyAdmissionRequest(admReview, errors.Errorf("this is a Dev Sandbox enforced restriction. you are trying to create a %s resource, which is not allowed", admReview.Request.Kind.Kind))
}
// at this point, it is clear the user isn't a sandbox user, allow request
return allowAdmissionRequest(admReview)
}

func denyAdmissionRequest(admReview admissionv1.AdmissionReview, err error) []byte {
response := &admissionv1.AdmissionResponse{
Allowed: false,
Expand Down
38 changes: 1 addition & 37 deletions pkg/webhook/validatingwebhook/validate_checluster_request.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
package validatingwebhook

import (
"context"
"html"
"io"
"net/http"
"strings"

toolchainv1alpha1 "github.com/codeready-toolchain/api/api/v1alpha1"

userv1 "github.com/openshift/api/user/v1"
"github.com/pkg/errors"
admissionv1 "k8s.io/api/admission/v1"
"k8s.io/apimachinery/pkg/types"
runtimeClient "sigs.k8s.io/controller-runtime/pkg/client"
)

Expand Down Expand Up @@ -44,32 +35,5 @@ func (v CheClusterRequestValidator) HandleValidate(w http.ResponseWriter, r *htt

func (v CheClusterRequestValidator) validate(body []byte) []byte {
log.Info("incoming request", "body", string(body))
admReview := admissionv1.AdmissionReview{}
if _, _, err := deserializer.Decode(body, nil, &admReview); err != nil {
// sanitize the body
escapedBody := html.EscapeString(string(body))
log.Error(err, "unable to deserialize the admission review object", "body", escapedBody)
return denyAdmissionRequest(admReview, errors.Wrapf(err, "unable to deserialize the admission review object - body: %v", escapedBody))
}
requestingUsername := admReview.Request.UserInfo.Username
// allow admission request if the user is a system user
if strings.HasPrefix(requestingUsername, "system:") {
return allowAdmissionRequest(admReview)
}
//check if the requesting user is a sandbox user
requestingUser := &userv1.User{}
err := v.Client.Get(context.TODO(), types.NamespacedName{
Name: admReview.Request.UserInfo.Username,
}, requestingUser)

if err != nil {
log.Error(err, "unable to find the user requesting creation of the CheCluster resource", "username", admReview.Request.UserInfo.Username)
return denyAdmissionRequest(admReview, errors.New("unable to find the user requesting the creation of the CheCluster resource"))
}
if requestingUser.GetLabels()[toolchainv1alpha1.ProviderLabelKey] == toolchainv1alpha1.ProviderLabelValue {
log.Info("sandbox user is trying to create a CheCluster", "AdmissionReview", admReview)
return denyAdmissionRequest(admReview, errors.New("this is a Dev Sandbox enforced restriction. you are trying to create a CheCluster resource, which is not allowed"))
}
// at this point, it is clear the user isn't a sandbox user, allow request
return allowAdmissionRequest(admReview)
return allowIfNonSandboxUser(body, &v.Client)
}
38 changes: 1 addition & 37 deletions pkg/webhook/validatingwebhook/validate_k8simagepuller_request.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
package validatingwebhook

import (
"context"
"html"
"io"
"net/http"
"strings"

toolchainv1alpha1 "github.com/codeready-toolchain/api/api/v1alpha1"

userv1 "github.com/openshift/api/user/v1"
"github.com/pkg/errors"
admissionv1 "k8s.io/api/admission/v1"
"k8s.io/apimachinery/pkg/types"
runtimeClient "sigs.k8s.io/controller-runtime/pkg/client"
)

Expand Down Expand Up @@ -44,32 +35,5 @@ func (v K8sImagePullerRequestValidator) HandleValidate(w http.ResponseWriter, r

func (v K8sImagePullerRequestValidator) validate(body []byte) []byte {
log.Info("incoming request", "body", string(body))
admReview := admissionv1.AdmissionReview{}
if _, _, err := deserializer.Decode(body, nil, &admReview); err != nil {
// sanitize the body
escapedBody := html.EscapeString(string(body))
log.Error(err, "unable to deserialize the admission review object", "body", escapedBody)
return denyAdmissionRequest(admReview, errors.Wrapf(err, "unable to deserialize the admission review object - body: %v", escapedBody))
}
requestingUsername := admReview.Request.UserInfo.Username
// allow admission request if the user is a system user
if strings.HasPrefix(requestingUsername, "system:") {
return allowAdmissionRequest(admReview)
}
//check if the requesting user is a sandbox user
requestingUser := &userv1.User{}
err := v.Client.Get(context.TODO(), types.NamespacedName{
Name: admReview.Request.UserInfo.Username,
}, requestingUser)

if err != nil {
log.Error(err, "unable to find the user requesting creation of the KubernetesImagePuller resource", "username", admReview.Request.UserInfo.Username)
return denyAdmissionRequest(admReview, errors.New("unable to find the user requesting the creation of the KubernetesImagePuller resource"))
}
if requestingUser.GetLabels()[toolchainv1alpha1.ProviderLabelKey] == toolchainv1alpha1.ProviderLabelValue {
log.Info("sandbox user is trying to create a KubernetesImagePuller", "AdmissionReview", admReview)
return denyAdmissionRequest(admReview, errors.New("this is a Dev Sandbox enforced restriction. you are trying to create a KubernetesImagePuller resource, which is not allowed"))
}
// at this point, it is clear the user isn't a sandbox user, allow request
return allowAdmissionRequest(admReview)
return allowIfNonSandboxUser(body, &v.Client)
}

0 comments on commit 6bd5dc9

Please sign in to comment.