github.com/oam-dev/kubevela@v1.9.11/pkg/auth/userinfo.go (about) 1 /* 2 Copyright 2022 The KubeVela Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package auth 18 19 import ( 20 "context" 21 "fmt" 22 "regexp" 23 "strings" 24 25 authv1 "k8s.io/api/authentication/v1" 26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 "k8s.io/apiserver/pkg/authentication/user" 28 "k8s.io/apiserver/pkg/endpoints/request" 29 utilfeature "k8s.io/apiserver/pkg/util/feature" 30 "k8s.io/utils/strings/slices" 31 32 monitorContext "github.com/kubevela/pkg/monitor/context" 33 34 "github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1" 35 "github.com/oam-dev/kubevela/pkg/features" 36 "github.com/oam-dev/kubevela/pkg/oam" 37 ) 38 39 const ( 40 groupSeparator = "," 41 ) 42 43 // ContextWithUserInfo inject username & group from app annotations into context 44 // If serviceAccount is set and username is empty, identity will user the serviceAccount 45 func ContextWithUserInfo(ctx context.Context, app *v1beta1.Application) context.Context { 46 if app == nil { 47 return ctx 48 } 49 return request.WithUser(ctx, GetUserInfoInAnnotation(&app.ObjectMeta)) 50 } 51 52 // MonitorContextWithUserInfo inject username & group from app annotations into monitor context 53 func MonitorContextWithUserInfo(ctx monitorContext.Context, app *v1beta1.Application) monitorContext.Context { 54 _ctx := ctx.GetContext() 55 authCtx := ContextWithUserInfo(_ctx, app) 56 ctx.SetContext(authCtx) 57 return ctx 58 } 59 60 // ContextClearUserInfo clear user info in context 61 func ContextClearUserInfo(ctx context.Context) context.Context { 62 return request.WithUser(ctx, nil) 63 } 64 65 // SetUserInfoInAnnotation set username and group from userInfo into annotations 66 // it will clear the existing service account annotation in avoid of permission leak 67 func SetUserInfoInAnnotation(obj *metav1.ObjectMeta, userInfo authv1.UserInfo) { 68 if AuthenticationWithUser { 69 metav1.SetMetaDataAnnotation(obj, oam.AnnotationApplicationUsername, userInfo.Username) 70 } 71 re := regexp.MustCompile(strings.ReplaceAll(AuthenticationGroupPattern, "*", ".*")) 72 var groups []string 73 for _, group := range userInfo.Groups { 74 if re.MatchString(group) { 75 groups = append(groups, group) 76 } 77 } 78 metav1.SetMetaDataAnnotation(obj, oam.AnnotationApplicationGroup, strings.Join(groups, groupSeparator)) 79 } 80 81 // GetUserInfoInAnnotation extract user info from annotations 82 // support compatibility for serviceAccount when name is empty 83 func GetUserInfoInAnnotation(obj *metav1.ObjectMeta) user.Info { 84 annotations := obj.GetAnnotations() 85 if annotations == nil { 86 annotations = map[string]string{} 87 } 88 89 name := annotations[oam.AnnotationApplicationUsername] 90 if serviceAccountName := annotations[oam.AnnotationApplicationServiceAccountName]; serviceAccountName != "" && name == "" { 91 name = fmt.Sprintf("system:serviceaccount:%s:%s", obj.GetNamespace(), serviceAccountName) 92 } 93 94 if name == "" && utilfeature.DefaultMutableFeatureGate.Enabled(features.AuthenticateApplication) { 95 name = AuthenticationDefaultUser 96 } 97 98 return &user.DefaultInfo{ 99 Name: name, 100 Groups: slices.Filter( 101 []string{}, 102 strings.Split(annotations[oam.AnnotationApplicationGroup], groupSeparator), 103 func(s string) bool { 104 return len(strings.TrimSpace(s)) > 0 105 }), 106 } 107 }