231 lines
6.5 KiB
Go
231 lines
6.5 KiB
Go
/*
|
|
Copyright 2018 The KubeSphere Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
package iam
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/emicklei/go-restful"
|
|
"k8s.io/api/rbac/v1"
|
|
|
|
"k8s.io/kubernetes/pkg/util/slice"
|
|
|
|
"kubesphere.io/kubesphere/pkg/constants"
|
|
"kubesphere.io/kubesphere/pkg/filter/route"
|
|
"kubesphere.io/kubesphere/pkg/models"
|
|
)
|
|
|
|
func Register(ws *restful.WebService) {
|
|
//roles
|
|
ws.Route(ws.GET("/users/{username}/roles").To(userRolesHandler).Filter(route.RouteLogging)).Produces(restful.MIME_JSON)
|
|
//rules define
|
|
ws.Route(ws.GET("/roles/rules").To(roleRulesHandler).Filter(route.RouteLogging)).Produces(restful.MIME_JSON)
|
|
ws.Route(ws.GET("/clusterroles/rules").To(clusterRoleRulesHandler).Filter(route.RouteLogging)).Produces(restful.MIME_JSON)
|
|
//user->rules
|
|
ws.Route(ws.GET("/rules").To(usersRulesHandler).Filter(route.RouteLogging)).Produces(restful.MIME_JSON)
|
|
ws.Route(ws.GET("/users/{username}/rules").To(userRulesHandler).Filter(route.RouteLogging)).Produces(restful.MIME_JSON)
|
|
//role->rules
|
|
ws.Route(ws.GET("/clusterroles/{name}/rules").To(clusterRoleRulesHandler).Filter(route.RouteLogging)).Produces(restful.MIME_JSON)
|
|
ws.Route(ws.GET("/namespaces/{namespace}/roles/{name}/rules").To(roleRulesHandler).Filter(route.RouteLogging)).Produces(restful.MIME_JSON)
|
|
//role->users
|
|
ws.Route(ws.GET("/namespaces/{namespace}/roles/{name}/users").To(roleUsersHandler).Filter(route.RouteLogging)).Produces(restful.MIME_JSON)
|
|
ws.Route(ws.GET("/clusterroles/{name}/users").To(clusterRoleUsersHandler).Filter(route.RouteLogging)).Produces(restful.MIME_JSON)
|
|
}
|
|
|
|
// username -> roles
|
|
func userRolesHandler(req *restful.Request, resp *restful.Response) {
|
|
|
|
username := req.PathParameter("username")
|
|
|
|
roles, err := models.GetRoles(username)
|
|
|
|
if err != nil {
|
|
resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
|
|
return
|
|
}
|
|
|
|
clusterRoles, err := models.GetClusterRoles(username)
|
|
|
|
if err != nil {
|
|
resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
|
|
return
|
|
}
|
|
|
|
roleList := roleList{}
|
|
roleList.Roles = roles
|
|
roleList.ClusterRoles = clusterRoles
|
|
|
|
resp.WriteEntity(roleList)
|
|
}
|
|
|
|
// namespaces + role name -> users
|
|
func roleUsersHandler(req *restful.Request, resp *restful.Response) {
|
|
name := req.PathParameter("name")
|
|
namespace := req.PathParameter("namespace")
|
|
|
|
roleBindings, err := models.GetRoleBindings(namespace, name)
|
|
|
|
if err != nil {
|
|
resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
|
|
return
|
|
}
|
|
|
|
users := make([]string, 0)
|
|
|
|
for _, roleBinding := range roleBindings {
|
|
for _, subject := range roleBinding.Subjects {
|
|
if subject.Kind == v1.UserKind &&
|
|
!strings.HasPrefix(subject.Name, "system") &&
|
|
!slice.ContainsString(users, subject.Name, nil) {
|
|
users = append(users, subject.Name)
|
|
}
|
|
}
|
|
}
|
|
|
|
resp.WriteEntity(users)
|
|
}
|
|
|
|
// cluster role name -> users
|
|
func clusterRoleUsersHandler(req *restful.Request, resp *restful.Response) {
|
|
name := req.PathParameter("name")
|
|
|
|
roleBindings, err := models.GetClusterRoleBindings(name)
|
|
|
|
if err != nil {
|
|
resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
|
|
return
|
|
}
|
|
|
|
users := make([]string, 0)
|
|
|
|
for _, roleBinding := range roleBindings {
|
|
for _, subject := range roleBinding.Subjects {
|
|
if subject.Kind == v1.UserKind && !strings.HasPrefix(subject.Name, "system") &&
|
|
!slice.ContainsString(users, subject.Name, nil) {
|
|
users = append(users, subject.Name)
|
|
}
|
|
}
|
|
}
|
|
|
|
resp.WriteEntity(users)
|
|
}
|
|
|
|
// username -> rules
|
|
func usersRulesHandler(req *restful.Request, resp *restful.Response) {
|
|
users := strings.Split(req.QueryParameter("users"), ",")
|
|
|
|
usersRules := make(map[string]userRuleList, 0)
|
|
|
|
for _, username := range users {
|
|
_, contains := usersRules[username]
|
|
if username != "" && !contains {
|
|
|
|
userRuleList := userRuleList{}
|
|
|
|
clusterRules, err := getUserClusterRules(username)
|
|
|
|
if err != nil {
|
|
resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
|
|
return
|
|
}
|
|
|
|
rules, err := getUserRules(username)
|
|
|
|
if err != nil {
|
|
resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
|
|
return
|
|
}
|
|
|
|
userRuleList.ClusterRules = clusterRules
|
|
userRuleList.Rules = rules
|
|
|
|
usersRules[username] = userRuleList
|
|
}
|
|
}
|
|
|
|
resp.WriteEntity(usersRules)
|
|
}
|
|
|
|
// username -> rules
|
|
func userRulesHandler(req *restful.Request, resp *restful.Response) {
|
|
username := req.PathParameter("username")
|
|
|
|
userRuleList := userRuleList{}
|
|
|
|
clusterRules, err := getUserClusterRules(username)
|
|
|
|
if err != nil {
|
|
resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
|
|
return
|
|
}
|
|
|
|
rules, err := getUserRules(username)
|
|
|
|
if err != nil {
|
|
resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
|
|
return
|
|
}
|
|
|
|
userRuleList.ClusterRules = clusterRules
|
|
userRuleList.Rules = rules
|
|
|
|
resp.WriteEntity(userRuleList)
|
|
}
|
|
|
|
// cluster role name -> rules
|
|
func clusterRoleRulesHandler(req *restful.Request, resp *restful.Response) {
|
|
|
|
name := req.PathParameter("name")
|
|
|
|
var rules []rule
|
|
|
|
if name == "" {
|
|
rules = clusterRoleRuleGroup
|
|
} else {
|
|
var err error
|
|
rules, err = getClusterRoleRules(name)
|
|
if err != nil {
|
|
resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
|
|
return
|
|
}
|
|
}
|
|
|
|
resp.WriteEntity(rules)
|
|
}
|
|
|
|
// role name -> rules
|
|
func roleRulesHandler(req *restful.Request, resp *restful.Response) {
|
|
name := req.PathParameter("name")
|
|
namespace := req.PathParameter("namespace")
|
|
|
|
var rules []rule
|
|
|
|
if namespace == "" && name == "" {
|
|
rules = roleRuleGroup
|
|
} else {
|
|
var err error
|
|
rules, err = getRoleRules(namespace, name)
|
|
if err != nil {
|
|
resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
|
|
return
|
|
}
|
|
}
|
|
resp.WriteEntity(rules)
|
|
}
|