Fix lint errors
This commit is contained in:
parent
4fe609a043
commit
6deaa0fb1a
@ -35,6 +35,7 @@ import (
|
|||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
|
|
||||||
|
"github.com/suzerain-io/pinniped/internal/constable"
|
||||||
"github.com/suzerain-io/pinniped/internal/controller/apicerts"
|
"github.com/suzerain-io/pinniped/internal/controller/apicerts"
|
||||||
"github.com/suzerain-io/pinniped/internal/controllerlib"
|
"github.com/suzerain-io/pinniped/internal/controllerlib"
|
||||||
"github.com/suzerain-io/pinniped/internal/provider"
|
"github.com/suzerain-io/pinniped/internal/provider"
|
||||||
@ -46,14 +47,13 @@ const (
|
|||||||
// This string must match the name of the Service declared in the deployment yaml.
|
// This string must match the name of the Service declared in the deployment yaml.
|
||||||
serviceName = "local-user-authenticator"
|
serviceName = "local-user-authenticator"
|
||||||
|
|
||||||
// TODO there must be a better way to get this specific json result string without needing to hardcode it
|
|
||||||
unauthenticatedResponse = `{"apiVersion":"authentication.k8s.io/v1beta1","kind":"TokenReview","status":{"authenticated":false}}`
|
unauthenticatedResponse = `{"apiVersion":"authentication.k8s.io/v1beta1","kind":"TokenReview","status":{"authenticated":false}}`
|
||||||
|
|
||||||
// TODO there must be a better way to get this specific json result string without needing to hardcode it
|
|
||||||
authenticatedResponseTemplate = `{"apiVersion":"authentication.k8s.io/v1beta1","kind":"TokenReview","status":{"authenticated":true,"user":{"username":"%s","uid":"%s","groups":%s}}}`
|
authenticatedResponseTemplate = `{"apiVersion":"authentication.k8s.io/v1beta1","kind":"TokenReview","status":{"authenticated":true,"user":{"username":"%s","uid":"%s","groups":%s}}}`
|
||||||
|
|
||||||
singletonWorker = 1
|
singletonWorker = 1
|
||||||
defaultResyncInterval = 3 * time.Minute
|
defaultResyncInterval = 3 * time.Minute
|
||||||
|
|
||||||
|
invalidRequest = constable.Error("invalid request")
|
||||||
)
|
)
|
||||||
|
|
||||||
type webhook struct {
|
type webhook struct {
|
||||||
@ -111,47 +111,11 @@ func (w *webhook) start(ctx context.Context, l net.Listener) error {
|
|||||||
func (w *webhook) ServeHTTP(rsp http.ResponseWriter, req *http.Request) {
|
func (w *webhook) ServeHTTP(rsp http.ResponseWriter, req *http.Request) {
|
||||||
defer req.Body.Close()
|
defer req.Body.Close()
|
||||||
|
|
||||||
if req.URL.Path != "/authenticate" {
|
username, password, err := getUsernameAndPasswordFromRequest(rsp, req)
|
||||||
klog.InfoS("received request path other than /authenticate", "path", req.URL.Path)
|
if err != nil {
|
||||||
rsp.WriteHeader(http.StatusNotFound)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if req.Method != http.MethodPost {
|
|
||||||
klog.InfoS("received request method other than post", "method", req.Method)
|
|
||||||
rsp.WriteHeader(http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !headerContains(req, "Content-Type", "application/json") {
|
|
||||||
klog.InfoS("content type is not application/json", "Content-Type", req.Header.Values("Content-Type"))
|
|
||||||
rsp.WriteHeader(http.StatusUnsupportedMediaType)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !headerContains(req, "Accept", "application/json") &&
|
|
||||||
!headerContains(req, "Accept", "application/*") &&
|
|
||||||
!headerContains(req, "Accept", "*/*") {
|
|
||||||
klog.InfoS("client does not accept application/json", "Accept", req.Header.Values("Accept"))
|
|
||||||
rsp.WriteHeader(http.StatusUnsupportedMediaType)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var body authenticationv1.TokenReview
|
|
||||||
if err := json.NewDecoder(req.Body).Decode(&body); err != nil {
|
|
||||||
klog.InfoS("failed to decode body", "err", err)
|
|
||||||
rsp.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
tokenSegments := strings.SplitN(body.Spec.Token, ":", 2)
|
|
||||||
if len(tokenSegments) != 2 {
|
|
||||||
klog.InfoS("bad token format in request")
|
|
||||||
rsp.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
username := tokenSegments[0]
|
|
||||||
password := tokenSegments[1]
|
|
||||||
|
|
||||||
secret, err := w.secretInformer.Lister().Secrets(namespace).Get(username)
|
secret, err := w.secretInformer.Lister().Secrets(namespace).Get(username)
|
||||||
notFound := k8serrors.IsNotFound(err)
|
notFound := k8serrors.IsNotFound(err)
|
||||||
if err != nil && !notFound {
|
if err != nil && !notFound {
|
||||||
@ -193,6 +157,50 @@ func (w *webhook) ServeHTTP(rsp http.ResponseWriter, req *http.Request) {
|
|||||||
respondWithAuthenticated(rsp, secret.ObjectMeta.Name, string(secret.UID), groups)
|
respondWithAuthenticated(rsp, secret.ObjectMeta.Name, string(secret.UID), groups)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getUsernameAndPasswordFromRequest(rsp http.ResponseWriter, req *http.Request) (string, string, error) {
|
||||||
|
if req.URL.Path != "/authenticate" {
|
||||||
|
klog.InfoS("received request path other than /authenticate", "path", req.URL.Path)
|
||||||
|
rsp.WriteHeader(http.StatusNotFound)
|
||||||
|
return "", "", invalidRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.Method != http.MethodPost {
|
||||||
|
klog.InfoS("received request method other than post", "method", req.Method)
|
||||||
|
rsp.WriteHeader(http.StatusMethodNotAllowed)
|
||||||
|
return "", "", invalidRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
if !headerContains(req, "Content-Type", "application/json") {
|
||||||
|
klog.InfoS("content type is not application/json", "Content-Type", req.Header.Values("Content-Type"))
|
||||||
|
rsp.WriteHeader(http.StatusUnsupportedMediaType)
|
||||||
|
return "", "", invalidRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
if !headerContains(req, "Accept", "application/json") &&
|
||||||
|
!headerContains(req, "Accept", "application/*") &&
|
||||||
|
!headerContains(req, "Accept", "*/*") {
|
||||||
|
klog.InfoS("client does not accept application/json", "Accept", req.Header.Values("Accept"))
|
||||||
|
rsp.WriteHeader(http.StatusUnsupportedMediaType)
|
||||||
|
return "", "", invalidRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
var body authenticationv1.TokenReview
|
||||||
|
if err := json.NewDecoder(req.Body).Decode(&body); err != nil {
|
||||||
|
klog.InfoS("failed to decode body", "err", err)
|
||||||
|
rsp.WriteHeader(http.StatusBadRequest)
|
||||||
|
return "", "", invalidRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenSegments := strings.SplitN(body.Spec.Token, ":", 2)
|
||||||
|
if len(tokenSegments) != 2 {
|
||||||
|
klog.InfoS("bad token format in request")
|
||||||
|
rsp.WriteHeader(http.StatusBadRequest)
|
||||||
|
return "", "", invalidRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
return tokenSegments[0], tokenSegments[1], nil
|
||||||
|
}
|
||||||
|
|
||||||
func headerContains(req *http.Request, headerName, s string) bool {
|
func headerContains(req *http.Request, headerName, s string) bool {
|
||||||
headerValues := req.Header.Values(headerName)
|
headerValues := req.Header.Values(headerName)
|
||||||
for i := range headerValues {
|
for i := range headerValues {
|
||||||
|
@ -451,9 +451,9 @@ func unauthenticatedResponseJSON() *string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func authenticatedResponseJSON(user, uid string, groups []string) *string {
|
func authenticatedResponseJSON(user, uid string, groups []string) *string {
|
||||||
var quotedGroups []string
|
quotedGroups := make([]string, len(groups))
|
||||||
for _, group := range groups {
|
for i, group := range groups {
|
||||||
quotedGroups = append(quotedGroups, `"`+group+`"`)
|
quotedGroups[i] = `"` + group + `"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Very specific expected result. Avoid using json package so we know exactly what we're asserting.
|
// Very specific expected result. Avoid using json package so we know exactly what we're asserting.
|
||||||
|
@ -93,6 +93,7 @@ func TestSuccessfulCredentialRequest(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
for _, group := range expectedTestUserGroups {
|
for _, group := range expectedTestUserGroups {
|
||||||
|
group := group
|
||||||
t.Run("access as group "+group, func(t *testing.T) {
|
t.Run("access as group "+group, func(t *testing.T) {
|
||||||
addTestClusterRoleBinding(ctx, t, adminClient, &rbacv1.ClusterRoleBinding{
|
addTestClusterRoleBinding(ctx, t, adminClient, &rbacv1.ClusterRoleBinding{
|
||||||
TypeMeta: metav1.TypeMeta{},
|
TypeMeta: metav1.TypeMeta{},
|
||||||
|
Loading…
Reference in New Issue
Block a user