Adding approvable field to indicate if current user can approve a particular step
Signed-off-by: rick <rick@jenkins-zh.cn>
This commit is contained in:
@@ -209,24 +209,49 @@ func (h *ProjectPipelineHandler) GetPipelineRunNodes(req *restful.Request, resp
|
|||||||
resp.WriteAsJson(res)
|
resp.WriteAsJson(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *ProjectPipelineHandler) hasSubmitPermission(req *restful.Request) (hasPermit bool, err error) {
|
func (h *ProjectPipelineHandler) approvableCheck(nodes []clientDevOps.NodesDetail, req *restful.Request) {
|
||||||
var currentUserName string
|
currentUserName, roleName := h.getCurrentUser(req)
|
||||||
|
// check if current user belong to the admin group, grant it if it's true
|
||||||
|
isAdmin := roleName == iamv1alpha2.PlatformAdmin
|
||||||
|
|
||||||
|
for i, node := range nodes {
|
||||||
|
if node.State != clientDevOps.StatePaused {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for j, step := range node.Steps {
|
||||||
|
if step.State != clientDevOps.StatePaused || step.Input == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes[i].Steps[j].Approvable = isAdmin || step.Input.Approvable(currentUserName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *ProjectPipelineHandler) getCurrentUser(req *restful.Request) (username, roleName string) {
|
||||||
var userInfo user.Info
|
var userInfo user.Info
|
||||||
var ok bool
|
var ok bool
|
||||||
|
var err error
|
||||||
|
|
||||||
ctx := req.Request.Context()
|
ctx := req.Request.Context()
|
||||||
if userInfo, ok = request.UserFrom(ctx); ok {
|
if userInfo, ok = request.UserFrom(ctx); ok {
|
||||||
// check if current user belong to the admin group, grant it if it's true
|
|
||||||
var role *iamv1alpha2.GlobalRole
|
var role *iamv1alpha2.GlobalRole
|
||||||
currentUserName = userInfo.GetName()
|
username = userInfo.GetName()
|
||||||
if role, err = h.abc.GetGlobalRoleOfUser(currentUserName); err == nil {
|
if role, err = h.abc.GetGlobalRoleOfUser(username); err == nil {
|
||||||
if role.Name == iamv1alpha2.PlatformAdmin {
|
roleName = role.Name
|
||||||
hasPermit = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *ProjectPipelineHandler) hasSubmitPermission(req *restful.Request) (hasPermit bool, err error) {
|
||||||
|
currentUserName, roleName := h.getCurrentUser(req)
|
||||||
|
// check if current user belong to the admin group, grant it if it's true
|
||||||
|
if roleName == iamv1alpha2.PlatformAdmin {
|
||||||
|
hasPermit = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// step 2, check if current user if was addressed
|
// step 2, check if current user if was addressed
|
||||||
httpReq := &http.Request{
|
httpReq := &http.Request{
|
||||||
@@ -242,8 +267,7 @@ func (h *ProjectPipelineHandler) hasSubmitPermission(req *restful.Request) (hasP
|
|||||||
nodeId := req.PathParameter("node")
|
nodeId := req.PathParameter("node")
|
||||||
stepId := req.PathParameter("step")
|
stepId := req.PathParameter("step")
|
||||||
|
|
||||||
// find the expected submitter list which separated by common
|
// check if current user can approve this input
|
||||||
var expectedSubmitter string
|
|
||||||
var res []clientDevOps.NodesDetail
|
var res []clientDevOps.NodesDetail
|
||||||
if res, err = h.devopsOperator.GetNodesDetail(projectName, pipelineName, runId, httpReq); err == nil {
|
if res, err = h.devopsOperator.GetNodesDetail(projectName, pipelineName, runId, httpReq); err == nil {
|
||||||
for _, node := range res {
|
for _, node := range res {
|
||||||
@@ -256,7 +280,7 @@ func (h *ProjectPipelineHandler) hasSubmitPermission(req *restful.Request) (hasP
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedSubmitter = fmt.Sprintf("%v", step.Input.Submitter)
|
hasPermit = step.Input.Approvable(currentUserName)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
@@ -266,18 +290,6 @@ func (h *ProjectPipelineHandler) hasSubmitPermission(req *restful.Request) (hasP
|
|||||||
err = errors.New("cannot get the submitters of current pipeline run")
|
err = errors.New("cannot get the submitters of current pipeline run")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// grant all users if there's no specific one
|
|
||||||
if expectedSubmitter == "" {
|
|
||||||
hasPermit = true
|
|
||||||
} else {
|
|
||||||
for _, submitter := range strings.Split(expectedSubmitter, ",") {
|
|
||||||
if strings.TrimSpace(submitter) == currentUserName {
|
|
||||||
hasPermit = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,6 +333,8 @@ func (h *ProjectPipelineHandler) GetNodesDetail(req *restful.Request, resp *rest
|
|||||||
parseErr(err, resp)
|
parseErr(err, resp)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
h.approvableCheck(res, req)
|
||||||
|
|
||||||
resp.WriteAsJson(res)
|
resp.WriteAsJson(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -548,6 +562,7 @@ func (h *ProjectPipelineHandler) GetBranchNodesDetail(req *restful.Request, resp
|
|||||||
parseErr(err, resp)
|
parseErr(err, resp)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
h.approvableCheck(res, req)
|
||||||
resp.WriteAsJson(res)
|
resp.WriteAsJson(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,9 +17,11 @@ limitations under the License.
|
|||||||
package devops
|
package devops
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PipelineList struct {
|
type PipelineList struct {
|
||||||
@@ -979,6 +981,8 @@ type NodeSteps struct {
|
|||||||
StartTime string `json:"startTime,omitempty" description:"the time of starts"`
|
StartTime string `json:"startTime,omitempty" description:"the time of starts"`
|
||||||
State string `json:"state,omitempty" description:"run state. e.g. SKIPPED"`
|
State string `json:"state,omitempty" description:"run state. e.g. SKIPPED"`
|
||||||
Type string `json:"type,omitempty" description:"type"`
|
Type string `json:"type,omitempty" description:"type"`
|
||||||
|
// Approvable indicates if this step can be approved by current user
|
||||||
|
Approvable bool `json:"aprovable" description:"indicate if this step can be approved by current user"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckScriptCompile
|
// CheckScriptCompile
|
||||||
@@ -1075,6 +1079,11 @@ type NodesDetail struct {
|
|||||||
Steps []NodeSteps `json:"steps,omitempty" description:"steps"`
|
Steps []NodeSteps `json:"steps,omitempty" description:"steps"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// StatePaused indicates a node or a step was paused, for example it's waiting for an iput
|
||||||
|
StatePaused = "PAUSED"
|
||||||
|
)
|
||||||
|
|
||||||
type NodesStepsIndex struct {
|
type NodesStepsIndex struct {
|
||||||
Id int `json:"id,omitempty" description:"id"`
|
Id int `json:"id,omitempty" description:"id"`
|
||||||
Steps []NodeSteps `json:"steps,omitempty" description:"steps"`
|
Steps []NodeSteps `json:"steps,omitempty" description:"steps"`
|
||||||
@@ -1095,6 +1104,37 @@ type Input struct {
|
|||||||
Submitter interface{} `json:"submitter,omitempty" description:"check submitter"`
|
Submitter interface{} `json:"submitter,omitempty" description:"check submitter"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetSubmitters returns the all submitters related to this input
|
||||||
|
func (i *Input) GetSubmitters() (submitters []string) {
|
||||||
|
if i.Submitter == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
submitterArray := strings.Split(fmt.Sprintf("%v", i.Submitter), ",")
|
||||||
|
submitters = make([]string, len(submitterArray))
|
||||||
|
for i, submitter := range submitterArray {
|
||||||
|
submitters[i] = strings.TrimSpace(submitter)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Approvable returns the result if the given identify (username or group name) can approve this input
|
||||||
|
func (i *Input) Approvable(identify string) (ok bool) {
|
||||||
|
submitters := i.GetSubmitters()
|
||||||
|
|
||||||
|
// it means anyone can approve this if there's no specific one
|
||||||
|
if len(submitters) == 0 {
|
||||||
|
ok = true
|
||||||
|
} else {
|
||||||
|
for _, submitter := range submitters {
|
||||||
|
if submitter == identify {
|
||||||
|
ok = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
type HttpParameters struct {
|
type HttpParameters struct {
|
||||||
Method string `json:"method,omitempty"`
|
Method string `json:"method,omitempty"`
|
||||||
Header http.Header `json:"header,omitempty"`
|
Header http.Header `json:"header,omitempty"`
|
||||||
@@ -1105,7 +1145,6 @@ type HttpParameters struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PipelineOperator interface {
|
type PipelineOperator interface {
|
||||||
|
|
||||||
// Pipelinne operator interface
|
// Pipelinne operator interface
|
||||||
GetPipeline(projectName, pipelineName string, httpParameters *HttpParameters) (*Pipeline, error)
|
GetPipeline(projectName, pipelineName string, httpParameters *HttpParameters) (*Pipeline, error)
|
||||||
ListPipelines(httpParameters *HttpParameters) (*PipelineList, error)
|
ListPipelines(httpParameters *HttpParameters) (*PipelineList, error)
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ func generateSwaggerJson() []byte {
|
|||||||
urlruntime.Must(oauth.AddToContainer(container, nil, nil, nil, nil, nil))
|
urlruntime.Must(oauth.AddToContainer(container, nil, nil, nil, nil, nil))
|
||||||
urlruntime.Must(clusterkapisv1alpha1.AddToContainer(container, informerFactory.KubernetesSharedInformerFactory(),
|
urlruntime.Must(clusterkapisv1alpha1.AddToContainer(container, informerFactory.KubernetesSharedInformerFactory(),
|
||||||
informerFactory.KubeSphereSharedInformerFactory(), "", "", ""))
|
informerFactory.KubeSphereSharedInformerFactory(), "", "", ""))
|
||||||
urlruntime.Must(devopsv1alpha2.AddToContainer(container, informerFactory.KubeSphereSharedInformerFactory(), &fakedevops.Devops{}, nil, clientsets.KubeSphere(), fakes3.NewFakeS3(), ""))
|
urlruntime.Must(devopsv1alpha2.AddToContainer(container, informerFactory.KubeSphereSharedInformerFactory(), &fakedevops.Devops{}, nil, clientsets.KubeSphere(), fakes3.NewFakeS3(), "", am.NewReadOnlyOperator(informerFactory)))
|
||||||
urlruntime.Must(devopsv1alpha3.AddToContainer(container, &fakedevops.Devops{}, clientsets.Kubernetes(), clientsets.KubeSphere(), informerFactory.KubeSphereSharedInformerFactory(), informerFactory.KubernetesSharedInformerFactory()))
|
urlruntime.Must(devopsv1alpha3.AddToContainer(container, &fakedevops.Devops{}, clientsets.Kubernetes(), clientsets.KubeSphere(), informerFactory.KubeSphereSharedInformerFactory(), informerFactory.KubernetesSharedInformerFactory()))
|
||||||
urlruntime.Must(iamv1alpha2.AddToContainer(container, im.NewOperator(clientsets.KubeSphere(), informerFactory, nil), am.NewReadOnlyOperator(informerFactory), group.New(informerFactory, clientsets.KubeSphere(), clientsets.Kubernetes()), authoptions.NewAuthenticateOptions()))
|
urlruntime.Must(iamv1alpha2.AddToContainer(container, im.NewOperator(clientsets.KubeSphere(), informerFactory, nil), am.NewReadOnlyOperator(informerFactory), group.New(informerFactory, clientsets.KubeSphere(), clientsets.Kubernetes()), authoptions.NewAuthenticateOptions()))
|
||||||
urlruntime.Must(monitoringv1alpha3.AddToContainer(container, clientsets.Kubernetes(), nil, informerFactory, nil))
|
urlruntime.Must(monitoringv1alpha3.AddToContainer(container, clientsets.Kubernetes(), nil, informerFactory, nil))
|
||||||
|
|||||||
Reference in New Issue
Block a user