Skip to content

Commit

Permalink
Refactored createHandler and added comments to debug
Browse files Browse the repository at this point in the history
  • Loading branch information
catttam committed Jan 25, 2024
1 parent c570b9e commit 2d998cd
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 36 deletions.
51 changes: 38 additions & 13 deletions pkg/handlers/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,27 @@ func MakeCreateHandler(cfg *types.Config, back types.ServerlessBackend) gin.Hand
return func(c *gin.Context) {
var service types.Service

mcUntyped, mcExists := c.Get("mc")
uidOrigin, uidExists := c.Get("uid_origin")

if !mcExists {
c.String(http.StatusInternalServerError, fmt.Sprintf("Missing multitenancy config"))
}
if !uidExists {
c.String(http.StatusInternalServerError, fmt.Sprintf("Missing EGI user uid"))
}

mc, mcParsed := mcUntyped.(*auth.MultitenancyConfig)
uid, uidParsed := uidOrigin.(string)

if !mcParsed {
c.String(http.StatusInternalServerError, fmt.Sprintf("Error parsing multitenancy config: %v", mcParsed))
}

if !uidParsed {
c.String(http.StatusInternalServerError, fmt.Sprintf("Error parsing uid origin: %v", uidParsed))
}

if err := c.ShouldBindJSON(&service); err != nil {
c.String(http.StatusBadRequest, fmt.Sprintf("The service specification is not valid: %v", err))
return
Expand All @@ -60,6 +81,7 @@ func MakeCreateHandler(cfg *types.Config, back types.ServerlessBackend) gin.Hand
// Check service values and set defaults
checkValues(&service, cfg)

// Check if the service VO is present on the cluster VO's and if the user creating the service is enrrolled in such
if service.VO != "" {
for _, vo := range cfg.OIDCGroups {
if vo == service.VO {
Expand All @@ -68,11 +90,25 @@ func MakeCreateHandler(cfg *types.Config, back types.ServerlessBackend) gin.Hand
if err != nil {
c.String(http.StatusBadRequest, fmt.Sprintln(err))
}
service.Labels["uid"] = uid
service.AllowedUsers = append(service.AllowedUsers, uid)
createLogger.Println("Creating service for user: ", uid)
break
}
}
}

// Check if users in allowed_users have a MinIO associated user
minIOAdminClient, _ := utils.MakeMinIOAdminClient(cfg)
uids := mc.CheckUsersInCache(service.AllowedUsers)
if len(uids) == 0 {
for _, uid := range uids {
sk, _ := auth.GenerateRandomKey(8)
minIOAdminClient.CreateMinIOUser(uid, sk)
mc.CreateSecretForOIDC(uid, sk)
}
}

createLogger.Println("Service labels: ", service.Labels)
// Create the service
if err := back.CreateService(service); err != nil {
Expand All @@ -93,7 +129,7 @@ func MakeCreateHandler(cfg *types.Config, back types.ServerlessBackend) gin.Hand
}

// Create buckets/folders based on the Input and Output and enable notifications
if err := createBuckets(&service, cfg, service.AllowedUsers); err != nil {
if err := createBuckets(&service, cfg, minIOAdminClient, service.AllowedUsers); err != nil {
if err == errInput {
c.String(http.StatusBadRequest, err.Error())
} else {
Expand Down Expand Up @@ -167,7 +203,7 @@ func checkValues(service *types.Service, cfg *types.Config) {
service.Token = utils.GenerateToken()
}

func createBuckets(service *types.Service, cfg *types.Config, allowed_users []string) error {
func createBuckets(service *types.Service, cfg *types.Config, minIOAdminClient *utils.MinIOAdminClient, allowed_users []string) error {
var s3Client *s3.S3
var cdmiClient *cdmi.Client
var provName, provID string
Expand Down Expand Up @@ -232,8 +268,6 @@ func createBuckets(service *types.Service, cfg *types.Config, allowed_users []st

// Create group for the service and add users
// TODO error control

minIOAdminClient, _ := utils.MakeMinIOAdminClient(cfg)
err = minIOAdminClient.CreateServiceGroup(splitPath[0])
if err != nil {
return fmt.Errorf("error creating service group for bucket %s: %v", splitPath[0], err)
Expand Down Expand Up @@ -360,12 +394,6 @@ func isStorageProviderDefined(storageName string, storageID string, providers *t
func checkIdentity(service *types.Service, cfg *types.Config, authHeader string) error {
oidcManager, _ := auth.NewOIDCManager(cfg.OIDCIssuer, cfg.OIDCSubject, cfg.OIDCGroups)
rawToken := strings.TrimPrefix(authHeader, "Bearer ")
uid, err := oidcManager.GetUID(rawToken)

if err != nil {
createLogger.Println("Unknown user origin")
return err
}

hasVO, err := oidcManager.UserHasVO(rawToken, service.VO)

Expand All @@ -378,9 +406,6 @@ func checkIdentity(service *types.Service, cfg *types.Config, authHeader string)
}

service.Labels["vo"] = service.VO
service.Labels["uid"] = uid
service.AllowedUsers = append(service.AllowedUsers, uid)
createLogger.Println("Creating service for user: ", uid)

return nil
}
Expand Down
45 changes: 37 additions & 8 deletions pkg/utils/auth/multitenancy.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ package auth

import (
"context"
"crypto/rand"
"encoding/base64"

v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -26,37 +28,37 @@ import (

const ServicesNamespace = "oscar-svc"

type multitenancyConfig struct {
type MultitenancyConfig struct {
kubeClientset *kubernetes.Clientset
owner_uid string
usersCache []string
}

func NewMultitenancyConfig(kubeClientset *kubernetes.Clientset, uid string) *multitenancyConfig {
return &multitenancyConfig{
func NewMultitenancyConfig(kubeClientset *kubernetes.Clientset, uid string) *MultitenancyConfig {
return &MultitenancyConfig{
kubeClientset: kubeClientset,
owner_uid: uid,
usersCache: []string{uid},
}
}

// TODO periodically check that the users stored on cache still exist on MinIO (cronjob)
func (mc *multitenancyConfig) UpdateCacheStatus() {
func (mc *MultitenancyConfig) UpdateCacheStatus() {
// 1. List users on MinIO
// 2. List secrets
// 3. Compare both lists and delete from secrets the missmatchs
// 4. updateCache
}

func (mc *multitenancyConfig) UpdateCache(uid string) {
func (mc *MultitenancyConfig) UpdateCache(uid string) {
mc.usersCache = append(mc.usersCache, uid)
}

func (mc *multitenancyConfig) ClearCache() {
func (mc *MultitenancyConfig) ClearCache() {
mc.usersCache = nil
}

func (mc *multitenancyConfig) UserExists(uid string) bool {
func (mc *MultitenancyConfig) UserExists(uid string) bool {
for _, id := range mc.usersCache {
if id == uid {
return true
Expand All @@ -65,7 +67,25 @@ func (mc *multitenancyConfig) UserExists(uid string) bool {
return false
}

func (mc *multitenancyConfig) CreateSecretForOIDC(uid string, sk string) error {
func (mc *MultitenancyConfig) CheckUsersInCache(uids []string) []string {
var notFoundUsers []string
var found bool
for _, uid := range uids {
found = false
for _, cacheUID := range mc.usersCache {
if uid == cacheUID {
found = true
break
}
}
if found == false {
notFoundUsers = append(notFoundUsers, uid)
}
}
return notFoundUsers
}

func (mc *MultitenancyConfig) CreateSecretForOIDC(uid string, sk string) error {

secret := &v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Expand All @@ -90,3 +110,12 @@ func (mc *multitenancyConfig) CreateSecretForOIDC(uid string, sk string) error {

return nil
}

func GenerateRandomKey(length int) (string, error) {
key := make([]byte, length)
_, err := rand.Read(key)
if err != nil {
return "", err
}
return base64.RawURLEncoding.EncodeToString(key), nil
}
30 changes: 15 additions & 15 deletions pkg/utils/auth/oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ import (
"log"
"os"

"crypto/rand"
"encoding/base64"
"net/http"
"strings"

Expand Down Expand Up @@ -109,13 +107,23 @@ func getOIDCMiddleware(kubeClientset *kubernetes.Clientset, minIOAdminClient *ut
// Check if exist MinIO user in cached users list
exists := mc.UserExists(uid)
if !exists {
sk, err := generateRandomKey(SecretKeyLength)
sk, err := GenerateRandomKey(SecretKeyLength)
if err != nil {
//TODO manage errr
oidcLogger.Println("Error generating random key for MinIO user")
}
// Create MinIO user and k8s secret with credentials
mc.CreateSecretForOIDC(uid, sk)
minIOAdminClient.CreateMinIOUser(uid, sk)
err = mc.CreateSecretForOIDC(uid, sk)
if err != nil {
oidcLogger.Println("Error creating secret for user: ", uid)
}
err = minIOAdminClient.CreateMinIOUser(uid, sk)
if err != nil {
oidcLogger.Println("Error creating MinIO user: ", uid)
}
oidcLogger.Printf("User %s already exists", uid)
c.Set("multitenancyConfig", &mc)
c.Set("uidOrigin", &uid)
c.Next()
}
}
}
Expand Down Expand Up @@ -170,6 +178,7 @@ func getGroups(urns []string) []string {
return groups
}

// UserHasVO checks if the user contained on the request token is enrolled on a specific VO
func (om *oidcManager) UserHasVO(rawToken string, vo string) (bool, error) {
ui, err := om.getUserInfo(rawToken)
if err != nil {
Expand Down Expand Up @@ -233,12 +242,3 @@ func (om *oidcManager) isAuthorised(rawToken string) bool {

return false
}

func generateRandomKey(length int) (string, error) {
key := make([]byte, length)
_, err := rand.Read(key)
if err != nil {
return "", err
}
return base64.RawURLEncoding.EncodeToString(key), nil
}

0 comments on commit 2d998cd

Please sign in to comment.