Files
kubesphere/pkg/apis/v1alpha/iam/iam_handler.go
2018-06-06 17:04:15 +08:00

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)
}