1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-15 17:51:20 +00:00
kyverno/pkg/userinfo/roleRef.go

103 lines
2.9 KiB
Go
Raw Normal View History

2019-11-11 22:52:09 +00:00
package userinfo
import (
"fmt"
2020-07-10 22:23:07 +00:00
2019-11-11 22:52:09 +00:00
authenticationv1 "k8s.io/api/authentication/v1"
rbacv1 "k8s.io/api/rbac/v1"
labels "k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/sets"
2019-11-11 22:52:09 +00:00
)
2019-11-14 23:49:11 +00:00
const (
clusterroleKind = "ClusterRole"
roleKind = "Role"
2019-11-14 23:49:11 +00:00
)
type RoleBindingLister interface {
List(labels.Selector) ([]*rbacv1.RoleBinding, error)
}
type ClusterRoleBindingLister interface {
List(labels.Selector) ([]*rbacv1.ClusterRoleBinding, error)
}
// GetRoleRef gets the list of roles and cluster roles for the incoming api-request
func GetRoleRef(rbLister RoleBindingLister, crbLister ClusterRoleBindingLister, userInfo authenticationv1.UserInfo) ([]string, []string, error) {
// rolebindings
roleBindings, err := rbLister.List(labels.Everything())
2019-11-11 22:52:09 +00:00
if err != nil {
return nil, nil, fmt.Errorf("failed to list rolebindings: %v", err)
2019-11-11 22:52:09 +00:00
}
rs, crs := getRoleRefByRoleBindings(roleBindings, userInfo)
2019-11-11 22:52:09 +00:00
// clusterrolebindings
clusterroleBindings, err := crbLister.List(labels.Everything())
2019-11-11 22:52:09 +00:00
if err != nil {
return nil, nil, fmt.Errorf("failed to list clusterrolebindings: %v", err)
2019-11-11 22:52:09 +00:00
}
crs = append(crs, getRoleRefByClusterRoleBindings(clusterroleBindings, userInfo)...)
if rs != nil {
rs = sets.List(sets.New(rs...))
}
if crs != nil {
crs = sets.List(sets.New(crs...))
}
return rs, crs, nil
2019-11-11 22:52:09 +00:00
}
func getRoleRefByRoleBindings(roleBindings []*rbacv1.RoleBinding, userInfo authenticationv1.UserInfo) ([]string, []string) {
var roles, clusterRoles []string
for _, rolebinding := range roleBindings {
if matchBindingSubjects(rolebinding.Subjects, userInfo, rolebinding.Namespace) {
switch rolebinding.RoleRef.Kind {
case roleKind:
roles = append(roles, rolebinding.Namespace+":"+rolebinding.RoleRef.Name)
case clusterroleKind:
clusterRoles = append(clusterRoles, rolebinding.RoleRef.Name)
2019-11-11 22:52:09 +00:00
}
}
}
return roles, clusterRoles
2019-11-11 22:52:09 +00:00
}
func getRoleRefByClusterRoleBindings(clusterroleBindings []*rbacv1.ClusterRoleBinding, userInfo authenticationv1.UserInfo) []string {
var clusterRoles []string
for _, clusterRoleBinding := range clusterroleBindings {
if matchBindingSubjects(clusterRoleBinding.Subjects, userInfo, "") {
if clusterRoleBinding.RoleRef.Kind == clusterroleKind {
clusterRoles = append(clusterRoles, clusterRoleBinding.RoleRef.Name)
2019-11-11 22:52:09 +00:00
}
}
}
return clusterRoles
2019-11-11 22:52:09 +00:00
}
func matchBindingSubjects(subjects []rbacv1.Subject, userInfo authenticationv1.UserInfo, namespace string) bool {
for _, subject := range subjects {
switch subject.Kind {
case rbacv1.ServiceAccountKind:
ns := subject.Namespace
if ns == "" {
ns = namespace
}
if ns != "" {
username := "system:serviceaccount:" + ns + ":" + subject.Name
if userInfo.Username == username {
return true
}
}
case rbacv1.GroupKind:
for _, group := range userInfo.Groups {
if group == subject.Name {
return true
}
}
case rbacv1.UserKind:
if userInfo.Username == subject.Name {
return true
}
2019-11-11 22:52:09 +00:00
}
}
return false
}