Skip to content

Commit

Permalink
Merge branch 'bug_12355/tags_in_directives_are_ignored_in_post_api_pr…
Browse files Browse the repository at this point in the history
…' into branches/rudder/4.1
  • Loading branch information
VinceMacBuche committed Jun 19, 2018
2 parents 457e5a2 + 95cca05 commit 426bbba
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,25 +88,23 @@ trait JsonTagExtractor[M[_]] extends JsonExctractorUtils[M] {
import net.liftweb.json._

def unserializeTags(value:String): Box[M[Tags]] = {

parseOpt(value) match {
case Some(json) => extractTags(json)
case _ => Failure(s"Invalid JSON serialization for Tags ${value}")
}
}


def convertToTag(jsonTag : JValue): Box[M[Tag]] = {
for {
tagName <- extractJsonString(jsonTag, "key", s => Full(TagName(s)))
tagValue <- extractJsonString(jsonTag, "value", s => Full(TagValue(s)))
} yield {
monad.apply2(tagName, tagValue)( (k,v) => Tag(k,v))
}
for {
tagName <- extractJsonString(jsonTag, "key", s => Full(TagName(s)))
tagValue <- extractJsonString(jsonTag, "value", s => Full(TagValue(s)))
} yield {
monad.apply2(tagName, tagValue)( (k,v) => Tag(k,v))
}
}

def extractTags(value:JValue): Box[M[Tags]] = {

extractJsonArray(value)(convertToTag).map(monad.apply(_)(tags => Tags(tags.toSet))) ?~! s"Invalid JSON serialization for Tags ${value}"
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -63,21 +63,16 @@ import com.normation.rudder.web.rest.changeRequest.APIChangeRequestInfo
import com.normation.rudder.web.rest.directive.RestDirective
import com.normation.rudder.web.rest.group.RestGroup
import com.normation.rudder.web.rest.node._
import com.normation.rudder.web.rest.parameter.RestParameter
import com.normation.rudder.web.rest.rule.RestRule
import com.normation.rudder.web.services.ReasonBehavior.Disabled
import com.normation.rudder.web.services.ReasonBehavior.Mandatory
import com.normation.rudder.web.services.ReasonBehavior.Optionnal
import com.normation.rudder.web.services.UserPropertyService
import com.normation.utils.Control._

import net.liftweb.common._
import net.liftweb.http.Req
import net.liftweb.json._
import net.liftweb.json.JsonAST.JObject
import net.liftweb.json.{JObject, _}
import net.liftweb.json.JsonDSL._
import com.normation.rudder.domain.nodes.NodePropertyProvider
import com.normation.rudder.web.rest.parameter.RestParameter
import com.normation.utils.Control

case class RestExtractorService (
readRule : RoRuleRepository
Expand All @@ -93,6 +88,7 @@ case class RestExtractorService (
/*
* Params Extractors
*/

private[this] def extractOneValue[T] (params : Map[String,List[String]], key : String)( to : (String) => Box[T] = ( (value:String) => Full(value))) = {
params.get(key) match {
case None => Full(None)
Expand Down Expand Up @@ -732,6 +728,29 @@ case class RestExtractorService (
}
}

// this extractTagsFromJson is exclusively used when updating TAG in the POST API request. We want to extract tags as a List
// of {key1,value1 ... keyN,valueN}

private[this] def extractTagsFromJson(value:JValue): Box[Option[Tags]] = {
implicit val formats = DefaultFormats
for {
jobjects <- Box(value.extractOpt[List[JObject]]) ?~! s"Invalid JSON serialization for Tags ${value}"
// be careful, we need to use JObject.obj to get the list even if there is duplicated keys,
// which would be removed with JObject.values
pairs <- Control.sequence(jobjects) { o => Control.sequence(o.obj) { case JField(key, v) =>
v match {
case JString(s) if(s.nonEmpty) => Full((key, s))
case _ => Failure(s"Cannot parse value '${v}' as a valid tag value for tag with name '${key}'")

}
}}
} yield {
val tags = pairs.flatten
Some(Tags(tags.map{case(k,v) => Tag(TagName(k),TagValue(v))}.toSet))
}
}


def extractDirectiveFromJSON (json : JValue) : Box[RestDirective] = {
for {
name <- (extractJsonString(json, "name", toMinimalSizeString(3)), extractJsonString(json, "displayName", toMinimalSizeString(3))) match {
Expand All @@ -749,7 +768,7 @@ case class RestExtractorService (
techniqueName <- extractJsonString(json, "techniqueName", x => Full(TechniqueName(x)))
techniqueVersion <- extractJsonString(json, "techniqueVersion", x => Full(TechniqueVersion(x)))
policyMode <- extractJsonString(json, "policyMode", PolicyMode.parseDefault)
tags <- extractTags(json \ "tags") ?~! "Error when extracting Directive tags"
tags <- extractTagsFromJson(json \ "tags") ?~! "Error when extracting Directive tags"
} yield {
RestDirective(name,shortDescription,longDescription,enabled,parameters,priority,techniqueName,techniqueVersion,policyMode,tags)
}
Expand Down

0 comments on commit 426bbba

Please sign in to comment.