mirror of
https://github.com/rancher/os.git
synced 2025-09-08 02:01:27 +00:00
87 lines
2.6 KiB
Go
87 lines
2.6 KiB
Go
package server
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"strings"
|
|
|
|
v1 "github.com/rancher/os2/pkg/apis/rancheros.cattle.io/v1"
|
|
"github.com/rancher/os2/pkg/clients"
|
|
roscontrollers "github.com/rancher/os2/pkg/generated/controllers/rancheros.cattle.io/v1"
|
|
corecontrollers "github.com/rancher/wrangler/pkg/generated/controllers/core/v1"
|
|
"github.com/sirupsen/logrus"
|
|
corev1 "k8s.io/api/core/v1"
|
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
|
)
|
|
|
|
type sharedSecretAuth struct {
|
|
secretCache corecontrollers.SecretCache
|
|
machineCache roscontrollers.MachineInventoryCache
|
|
}
|
|
|
|
func newSharedSecretAuth(clients *clients.Clients) *sharedSecretAuth {
|
|
server := &sharedSecretAuth{
|
|
secretCache: clients.Core.Secret().Cache(),
|
|
machineCache: clients.OS.MachineInventory().Cache(),
|
|
}
|
|
|
|
server.secretCache.AddIndexer(tokenIndex, func(obj *corev1.Secret) ([]string, error) {
|
|
if string(obj.Type) != tokenType {
|
|
return nil, nil
|
|
}
|
|
t := obj.Data[tokenKey]
|
|
if len(t) == 0 {
|
|
return nil, nil
|
|
}
|
|
return []string{base64.StdEncoding.EncodeToString(t)}, nil
|
|
})
|
|
|
|
server.machineCache.AddIndexer(machineBySecretNameIndex, func(obj *v1.MachineInventory) ([]string, error) {
|
|
if obj.Spec.MachineTokenSecretName == "" {
|
|
return nil, nil
|
|
}
|
|
return []string{obj.Namespace + "/" + obj.Spec.MachineTokenSecretName}, nil
|
|
})
|
|
|
|
return server
|
|
}
|
|
|
|
func (s *sharedSecretAuth) Authenticate(resp http.ResponseWriter, req *http.Request, registerNamespace string) (*v1.MachineInventory, bool, io.WriteCloser, error) {
|
|
token := strings.TrimPrefix(req.Header.Get("Authorization"), "Bearer ")
|
|
if token == "" || registerNamespace != "" {
|
|
return nil, true, nil, nil
|
|
}
|
|
|
|
secrets, err := s.secretCache.GetByIndex(tokenIndex, token)
|
|
if apierrors.IsNotFound(err) || len(secrets) == 0 {
|
|
return nil, false, nil, fmt.Errorf("token not found")
|
|
} else if err != nil {
|
|
return nil, false, nil, err
|
|
} else if len(secrets) > 1 {
|
|
logrus.Errorf("Multiple machine secrets with the same value [%s/%s, %s/%s, ...]",
|
|
secrets[0].Namespace, secrets[0].Name, secrets[1].Namespace, secrets[1].Name)
|
|
return nil, false, nil, fmt.Errorf("token not found")
|
|
}
|
|
|
|
machines, err := s.machineCache.GetByIndex(machineBySecretNameIndex, secrets[0].Namespace+"/"+secrets[0].Name)
|
|
if len(machines) > 1 {
|
|
logrus.Errorf("Multiple machine inventories with the token: %v", machines)
|
|
}
|
|
if apierrors.IsNotFound(err) || len(machines) != 1 {
|
|
return nil, false, nil, fmt.Errorf("machine not found")
|
|
} else if err != nil {
|
|
return nil, false, nil, err
|
|
}
|
|
return machines[0], false, writeCloser{resp}, nil
|
|
}
|
|
|
|
type writeCloser struct {
|
|
io.Writer
|
|
}
|
|
|
|
func (writeCloser) Close() error {
|
|
return nil
|
|
}
|