Skip to content

Commit

Permalink
Merge pull request #179 from VinceMacBuche/ust_3500/implem_3501/Preve…
Browse files Browse the repository at this point in the history
…nt_Self_Validation

Fixes #3501 : Prevent Self Validation
  • Loading branch information
fanf committed Apr 23, 2013
2 parents 212682a + eba0a70 commit 797abd9
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,18 @@ trait WorkflowService {

val stepsValue :List[WorkflowNodeId]

def findNextSteps(currentUserRights:Seq[String],currentStep:WorkflowNodeId) : WorkflowAction
def findBackSteps(currentUserRights:Seq[String],currentStep:WorkflowNodeId) : Seq[(WorkflowNodeId,(ChangeRequestId,EventActor, Option[String]) => Box[WorkflowNodeId])]
def findNextSteps(
currentUserRights : Seq[String]
, currentStep : WorkflowNodeId
, isCreator : Boolean
) : WorkflowAction

def findBackSteps(
currentUserRights : Seq[String]
, currentStep : WorkflowNodeId
, isCreator : Boolean
) : Seq[(WorkflowNodeId,(ChangeRequestId,EventActor, Option[String]) => Box[WorkflowNodeId])]

def findStep(changeRequestId: ChangeRequestId) : Box[WorkflowNodeId]
def isEditable(currentUserRights:Seq[String],currentStep:WorkflowNodeId, isCreator : Boolean): Boolean
def isPending(currentStep:WorkflowNodeId): Boolean
Expand Down Expand Up @@ -112,9 +122,17 @@ class NoWorkflowServiceImpl(

val noWorfkflow = WorkflowNodeId("No Workflow")

def findNextSteps(currentUserRights:Seq[String],currentStep:WorkflowNodeId) : WorkflowAction = NoWorkflowAction
def findNextSteps(
currentUserRights : Seq[String]
, currentStep : WorkflowNodeId
, isCreator : Boolean
) : WorkflowAction = NoWorkflowAction

def findBackSteps(currentUserRights:Seq[String],currentStep:WorkflowNodeId) = Seq()
def findBackSteps(
currentUserRights : Seq[String]
, currentStep : WorkflowNodeId
, isCreator : Boolean
) : Seq[(WorkflowNodeId,(ChangeRequestId,EventActor, Option[String]) => Box[WorkflowNodeId])] = Seq()

def findStep(changeRequestId: ChangeRequestId) : Box[WorkflowNodeId] = Failure("No state when no workflow")

Expand Down Expand Up @@ -157,6 +175,8 @@ class TwoValidationStepsWorkflowServiceImpl(
, roWorkflowRepo : RoWorkflowRepository
, woWorkflowRepo : WoWorkflowRepository
, workflowComet : AsyncWorkflowInfo
, selfValidation : Boolean
, selfDeployment : Boolean
) extends WorkflowService with Loggable {

case object Validation extends WorkflowNode {
Expand All @@ -181,14 +201,20 @@ class TwoValidationStepsWorkflowServiceImpl(

val stepsValue = steps.map(_.id)

def findNextSteps(currentUserRights:Seq[String],currentStep:WorkflowNodeId) = {
def findNextSteps(
currentUserRights : Seq[String]
, currentStep : WorkflowNodeId
, isCreator : Boolean
) : WorkflowAction = {
val authorizedRoles = currentUserRights.filter(role => (role == "validator" || role == "deployer"))
val canValid = selfValidation || !isCreator
val canDeploy = selfDeployment || !isCreator
currentStep match {
case Validation.id =>
val validatorActions =
if (authorizedRoles.contains("validator"))
if (authorizedRoles.contains("validator") && canValid)
Seq((Deployment.id,stepValidationToDeployment _)) ++ {
if(authorizedRoles.contains("deployer"))
if(authorizedRoles.contains("deployer") && canDeploy)
Seq((Deployed.id,stepValidationToDeployed _))
else Seq()
}
Expand All @@ -198,7 +224,7 @@ class TwoValidationStepsWorkflowServiceImpl(

case Deployment.id =>
val actions =
if(authorizedRoles.contains("deployer"))
if(authorizedRoles.contains("deployer") && canDeploy)
Seq((Deployed.id,stepDeploymentToDeployed _))
else Seq()
WorkflowAction("Deploy",actions)
Expand All @@ -207,11 +233,18 @@ class TwoValidationStepsWorkflowServiceImpl(
}
}

def findBackSteps(currentUserRights:Seq[String],currentStep:WorkflowNodeId): Seq[(WorkflowNodeId,(ChangeRequestId,EventActor, Option[String]) => Box[WorkflowNodeId])] = {
def findBackSteps(
currentUserRights : Seq[String]
, currentStep : WorkflowNodeId
, isCreator : Boolean
) : Seq[(WorkflowNodeId,(ChangeRequestId,EventActor, Option[String]) => Box[WorkflowNodeId])] = {
val authorizedRoles = currentUserRights.filter(role => (role == "validator" || role == "deployer"))
val canValid = selfValidation || !isCreator
val canDeploy = selfDeployment || !isCreator
currentStep match {
case Validation.id => if (authorizedRoles.contains("validator")) Seq((Cancelled.id,stepValidationToCancelled _)) else Seq()
case Deployment.id => if (authorizedRoles.contains("deployer")) Seq((Cancelled.id,stepDeploymentToCancelled _)) else Seq()
case Validation.id =>
if (authorizedRoles.contains("validator") && canValid) Seq((Cancelled.id,stepValidationToCancelled _)) else Seq()
case Deployment.id => if (authorizedRoles.contains("deployer") && canDeploy) Seq((Cancelled.id,stepDeploymentToCancelled _)) else Seq()
case Deployed.id => Seq()
case Cancelled.id => Seq()
}
Expand Down
20 changes: 20 additions & 0 deletions rudder-web/src/main/resources/configuration.properties.sample
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,26 @@ rudder.batch.reports.logInterval=1

rudder.workflow.enabled=false

# Enable self validation (default false)
#
# If false, no change request can be validated by it's creator
# So every change request will need to be reviewed by someone different from
# who requested this changed
#
# Boolean, defaults to false.

rudder.workflow.self.validation=false

# Enable self deployment (default true)
#
# If false, no change request can be deployed by it's creator
# So every change request will need to be reviewed by someone different from
# who requested this changed
#
# Boolean, defaults to true.

rudder.workflow.self.deployment=true

#########################
# DEPRECATED properties #############################################################
#########################
Expand Down
4 changes: 4 additions & 0 deletions rudder-web/src/main/scala/bootstrap/liftweb/AppConfig.scala
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ object RudderConfig extends Loggable {

//workflows configuration
val RUDDER_ENABLE_APPROVAL_WORKFLOWS = config.getBoolean("rudder.workflow.enabled") // false
val RUDDER_ENABLE_SELF_VALIDATION = config.getBoolean("rudder.workflow.self.validation") // false
val RUDDER_ENABLE_SELF_DEPLOYMENT = config.getBoolean("rudder.workflow.self.deployment") // true

val licensesConfiguration = "licenses.xml"
val logentries = "logentries.xml"
Expand Down Expand Up @@ -363,6 +365,8 @@ object RudderConfig extends Loggable {
, roWorkflowRepository
, woWorkflowRepository
, asyncWorkflowInfo
, RUDDER_ENABLE_SELF_VALIDATION
, RUDDER_ENABLE_SELF_DEPLOYMENT
)
case false => new NoWorkflowServiceImpl(
commitAndDeployChangeRequest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,9 @@ class ChangeRequestDetails extends DispatchSnippet with Loggable {

def displayActionButton(cr:ChangeRequest,step:WorkflowNodeId):NodeSeq = {
val authz = CurrentUser.getRights.authorizationTypes.toSeq.collect{case Edit(right) => right}
val isOwner = cr.owner == CurrentUser.getActor.name
( "#backStep" #> {
workflowService.findBackSteps(authz, step) match {
workflowService.findBackSteps(authz, step,isOwner) match {
case Nil => NodeSeq.Empty
case steps =>
SHtml.ajaxButton(
Expand All @@ -194,7 +195,7 @@ class ChangeRequestDetails extends DispatchSnippet with Loggable {
) } } &
"#nextStep" #> {
if(commitAndDeployChangeRequest.isMergeable(cr.id)) {
workflowService.findNextSteps(authz,step) match {
workflowService.findNextSteps(authz,step,isOwner) match {
case NoWorkflowAction => NodeSeq.Empty
case WorkflowAction(actionName,emptyList) if emptyList.size == 0 => NodeSeq.Empty
case WorkflowAction(actionName,steps) =>
Expand Down

0 comments on commit 797abd9

Please sign in to comment.