diff --git a/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/domain/secrets/Secret.scala b/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/domain/secrets/Secret.scala
index 79c75d4e219..5c80584188d 100644
--- a/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/domain/secrets/Secret.scala
+++ b/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/domain/secrets/Secret.scala
@@ -39,13 +39,12 @@ package com.normation.rudder.domain.secrets
import net.liftweb.json.JsonAST.JValue
import net.liftweb.json.JsonDSL._
-final case class Secret(name: String, value: String)
+final case class Secret(name: String, value: String, description: String)
object Secret {
-
- def serializeSecret(secret : Secret): JValue = {
- ( ("name" -> secret.name)
- ~ ("value" -> secret.value)
- )
+ def serializeSecretInfo(secret : Secret): JValue = {
+ ( ("name" -> secret.name)
+ ~ ("description" -> secret.description)
+ )
}
}
diff --git a/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/domain/secrets/SecretDiff.scala b/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/domain/secrets/SecretDiff.scala
index 30ffd7cd61c..a541b4efb17 100644
--- a/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/domain/secrets/SecretDiff.scala
+++ b/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/domain/secrets/SecretDiff.scala
@@ -46,8 +46,9 @@ final case class AddSecretDiff(secret: Secret) extends SecretDiff
final case class DeleteSecretDiff(secret: Secret) extends SecretDiff
final case class ModifySecretDiff(
- name : String
- , value : String
- , modValue : Option[SimpleDiff[String]] = None
+ name : String
+ , description : String
+ , modValue : Boolean
+ , modDescription : Option[SimpleDiff[String]] = None
) extends SecretDiff
diff --git a/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/repository/jdbc/EventLogJdbcRepository.scala b/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/repository/jdbc/EventLogJdbcRepository.scala
index 9d7e76698fd..6bd6e7c3b52 100644
--- a/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/repository/jdbc/EventLogJdbcRepository.scala
+++ b/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/repository/jdbc/EventLogJdbcRepository.scala
@@ -114,7 +114,6 @@ class EventLogJdbcRepository(
) match {
case Right(log) => log
case Left(error) =>
- println(error)
logEffect.warn(s"Error when trying to get the event type, recorded type was: '${eventType}'")
UnspecializedEventLog(eventLogDetails)
}
diff --git a/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/services/eventlog/EventLogDetailsService.scala b/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/services/eventlog/EventLogDetailsService.scala
index 17c98de934b..1384d8b195c 100644
--- a/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/services/eventlog/EventLogDetailsService.scala
+++ b/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/services/eventlog/EventLogDetailsService.scala
@@ -855,15 +855,17 @@ class EventLogDetailsServiceImpl(
(s"Entry type is not a Secret: ${entry}")
name <- (secret \ "name").headOption.map( _.text ) ?~!
(s"Missing attribute 'name' in entry type Secret: ${entry}")
- value <- (secret \ "value").headOption.map( _.text ) ?~!
- (s"Missing attribute 'value' in entry type Secret: ${entry}")
- modValue <- getFromToString((secret \ "diffValue").headOption)
+ description <- (secret \ "description").headOption.map( _.text ) ?~!
+ (s"Missing attribute 'description' in entry type Secret: ${entry}")
+ modValue <- tryo{(secret \ "valueHasChanged").text.toBoolean}
+ modDescription <- getFromToString((secret \ "diffDescription").headOption)
fileFormatOk <- TestFileFormat(secret)
} yield {
ModifySecretDiff(
name = name
- , value = value
+ , description = description
, modValue = (modValue)
+ , modDescription = (modDescription)
)
}
}
diff --git a/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/services/eventlog/EventLogFactory.scala b/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/services/eventlog/EventLogFactory.scala
index 8106c1ea06e..75099d0b3ee 100644
--- a/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/services/eventlog/EventLogFactory.scala
+++ b/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/services/eventlog/EventLogFactory.scala
@@ -768,7 +768,7 @@ class EventLogFactoryImpl(
) : AddSecret = {
val details = EventLog.withContent(secretXmlSerializer.serialise(secret) % ("changeType" -> "add"))
AddSecret(EventLogDetails(
- id = id
+ id = id
, modificationId = modificationId
, principal = principal
, details = details
@@ -789,7 +789,7 @@ class EventLogFactoryImpl(
val details = EventLog.withContent(secretXmlSerializer.serialise(secret) % ("changeType" -> "delete"))
DeleteSecret(EventLogDetails(
- id = id
+ id = id
, modificationId = modificationId
, principal = principal
, details = details
@@ -809,13 +809,25 @@ class EventLogFactoryImpl(
, reason : Option[String]
) : ModifySecret = {
- val diffValue = SimpleDiff.stringToXml(, SimpleDiff(oldSecret.value, newSecret.value) )
+ val diffValue = {
+ if(oldSecret.value != newSecret.value)
+ True
+ else
+ False
+ }
+
+ val diffDescription = {
+ if(oldSecret.description != newSecret.description)
+ Some(SimpleDiff.stringToXml(, SimpleDiff(oldSecret.description, newSecret.description) ))
+ else
+ None
+ }
val details = EventLog.withContent{
scala.xml.Utility.trim(
{oldSecret.name}
- {oldSecret.value}
- {diffValue}
+ {oldSecret.description}
+ {diffValue ++ diffDescription}
)
}
ModifySecret(EventLogDetails(
diff --git a/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/services/marshalling/XmlSerialisationImpl.scala b/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/services/marshalling/XmlSerialisationImpl.scala
index 391a213df16..5512c6e2d68 100644
--- a/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/services/marshalling/XmlSerialisationImpl.scala
+++ b/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/services/marshalling/XmlSerialisationImpl.scala
@@ -292,7 +292,7 @@ class SecretSerialisationImpl(xmlVersion:String) extends SecretSerialisation {
def serialise(secret:Secret): Elem = {
createTrimedElem(XML_TAG_SECRET, xmlVersion) (
{secret.name}
- {secret.value}
+ {secret.description}
)
}
}
diff --git a/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/services/marshalling/XmlUnserialisationImpl.scala b/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/services/marshalling/XmlUnserialisationImpl.scala
index 093a621a2cd..4839eceb1f3 100644
--- a/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/services/marshalling/XmlUnserialisationImpl.scala
+++ b/webapp/sources/rudder/rudder-core/src/main/scala/com/normation/rudder/services/marshalling/XmlUnserialisationImpl.scala
@@ -663,10 +663,11 @@ class SecretUnserialisationImpl extends SecretUnserialisation {
}
fileFormatOk <- TestFileFormat(secret)
- name <- (secret \ "name").headOption.map( _.text ) ?~! ("Missing attribute 'name' in entry type globalParameter : " + entry)
- value <- (secret \ "value").headOption.map( _.text ) ?~! ("Missing attribute 'value' in entry type globalParameter : " + entry)
+ name <- (secret \ "name").headOption.map( _.text ) ?~! ("Missing attribute 'name' in entry type secret : " + entry)
+// value <- (secret \ "value").headOption.map( _.text ) ?~! ("Missing attribute 'value' in entry type secret : " + entry)
+ description <- (secret \ "description").headOption.map( _.text ) ?~! ("Missing attribute 'description' in entry type secret : " + entry)
} yield {
- Secret(name, value)
+ Secret(name, "", description)
}
}
}
diff --git a/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/rest/EndpointsDefinition.scala b/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/rest/EndpointsDefinition.scala
index 198568f1bc8..71fef8b5905 100644
--- a/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/rest/EndpointsDefinition.scala
+++ b/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/rest/EndpointsDefinition.scala
@@ -754,29 +754,34 @@ object UserApi extends ApiModuleProvider[UserApi] {
}
-sealed trait SecretVaultApi extends EndpointSchema with GeneralApi with SortIndex
-object SecretVaultApi extends ApiModuleProvider[SecretVaultApi] {
- final case object GetSecrets extends SecretVaultApi with ZeroParam with StartsAtVersion13 with SortIndex { val z = implicitly[Line].value
- val description = "Get the list of key-value pair secret"
+sealed trait SecretApi extends EndpointSchema with GeneralApi with SortIndex
+object SecretApi extends ApiModuleProvider[SecretApi] {
+ final case object GetAllSecret extends SecretApi with ZeroParam with StartsAtVersion13 with SortIndex { val z = implicitly[Line].value
+ val description = "Get the list of key-value pair secret"
val (action, path) = GET / "secret"
}
- final case object AddSecret extends SecretVaultApi with ZeroParam with StartsAtVersion13 with SortIndex { val z = implicitly[Line].value
- val description = "Add a key-value pair secret"
+ final case object GetSecret extends SecretApi with OneParam with StartsAtVersion13 with SortIndex { val z = implicitly[Line].value
+ val description = "Get one key-value pair secret"
+ val (action, path) = GET / "secret" / "{id}"
+ }
+
+ final case object AddSecret extends SecretApi with ZeroParam with StartsAtVersion13 with SortIndex { val z = implicitly[Line].value
+ val description = "Add a key-value pair secret"
val (action, path) = PUT / "secret"
}
- final case object UpdateSecret extends SecretVaultApi with ZeroParam with StartsAtVersion13 with SortIndex { val z = implicitly[Line].value
- val description = "Update an existing key-value pair secret"
+ final case object UpdateSecret extends SecretApi with ZeroParam with StartsAtVersion13 with SortIndex { val z = implicitly[Line].value
+ val description = "Update an existing key-value pair secret"
val (action, path) = POST / "secret"
}
- final case object DeleteSecret extends SecretVaultApi with OneParam with StartsAtVersion13 with SortIndex { val z = implicitly[Line].value
- val description = "Delete a secret"
+ final case object DeleteSecret extends SecretApi with OneParam with StartsAtVersion13 with SortIndex { val z = implicitly[Line].value
+ val description = "Delete a secret"
val (action, path) = DELETE / "secret" / "{id}"
}
- def endpoints = ca.mrvisser.sealerate.values[SecretVaultApi].toList.sortBy( _.z )
+ def endpoints = ca.mrvisser.sealerate.values[SecretApi].toList.sortBy( _.z )
}
@@ -797,7 +802,7 @@ object AllApi {
RuleApi.endpoints :::
InventoryApi.endpoints :::
InfoApi.endpoints :::
- SecretVaultApi.endpoints :::
+ SecretApi.endpoints :::
// UserApi is not declared here, it will be contributed by plugin
Nil
}
diff --git a/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/rest/RestExtractorService.scala b/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/rest/RestExtractorService.scala
index b791b781295..76edb8c144d 100644
--- a/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/rest/RestExtractorService.scala
+++ b/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/rest/RestExtractorService.scala
@@ -1315,10 +1315,12 @@ final case class RestExtractorService (
for {
name <- extractJsonString(json,"name")
value <- extractJsonString(json, "value")
- s <- (name, value) match {
- case (None, v) => Failure(s"Missing name parameter for secret entry when parsing request")
- case (n, None) => Failure(s"Missing value parameter for secret entry when parsing request")
- case (Some(n), Some(v)) => Full(Secret(n,v))
+ description <- extractJsonString(json, "description")
+ s <- (name, value, description) match {
+ case (None, v, d) => Failure(s"Missing `name` parameter for secret entry when parsing request")
+ case (n, None, d) => Failure(s"Missing `value` parameter for secret entry when parsing request")
+ case (n, v, None) => Failure(s"Missing `description` parameter for secret entry when parsing request")
+ case (Some(n), Some(v), Some(d)) => Full(Secret(n,v,d))
}
} yield s
}
diff --git a/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/rest/RoleApiMapping.scala b/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/rest/RoleApiMapping.scala
index ed4c52da808..4e8b22b1148 100644
--- a/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/rest/RoleApiMapping.scala
+++ b/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/rest/RoleApiMapping.scala
@@ -106,8 +106,8 @@ final case object OnlyAdmin extends AuthorizationApiMapping {
SystemApi.ArchivesFullList.x :: SystemApi.ArchivesGroupsList.x :: SystemApi.ArchivesRulesList.x ::
SystemApi.GetAllZipArchive.x :: SystemApi.GetDirectivesZipArchive.x :: SystemApi.GetGroupsZipArchive.x ::
SystemApi.GetRulesZipArchive.x :: SystemApi.Info.x :: SystemApi.Status.x :: SystemApi.ArchivesParametersList.x ::
- SystemApi.GetParametersZipArchive.x :: SystemApi.GetHealthcheckResult.x :: SecretVaultApi.GetSecrets.x ::
- SecretVaultApi.AddSecret.x :: SecretVaultApi.DeleteSecret.x :: SecretVaultApi.UpdateSecret.x :: Nil
+ SystemApi.GetParametersZipArchive.x :: SystemApi.GetHealthcheckResult.x :: SecretApi.GetAllSecret.x ::
+ SecretApi.GetSecret.x :: SecretApi.AddSecret.x :: SecretApi.DeleteSecret.x :: SecretApi.UpdateSecret.x :: Nil
case Administration.Write => SettingsApi.ModifySettings.x :: SettingsApi.ModifySetting.x :: SystemApi.endpoints.map(_.x)
case Administration.Edit => SettingsApi.ModifySettings.x :: SettingsApi.ModifySetting.x :: SystemApi.endpoints.map(_.x)
diff --git a/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/rest/lift/SecretApi.scala b/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/rest/lift/SecretApi.scala
index 8fc270ce2e7..5c8f774b6ea 100644
--- a/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/rest/lift/SecretApi.scala
+++ b/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/rest/lift/SecretApi.scala
@@ -37,19 +37,19 @@
package com.normation.rudder.rest.lift
import com.normation.box._
+import com.normation.errors.IOResult
import com.normation.rudder.domain.secrets.Secret
import com.normation.rudder.rest.ApiPath
import com.normation.rudder.rest.ApiVersion
import com.normation.rudder.rest.AuthzToken
import com.normation.rudder.rest.RestExtractorService
import com.normation.rudder.rest.RestUtils
-import com.normation.rudder.rest.{SecretVaultApi => API}
+import com.normation.rudder.rest.{SecretApi => API}
import com.normation.rudder.web.services.SecretService
-import net.liftweb.common._
import net.liftweb.http.LiftResponse
import net.liftweb.http.Req
import net.liftweb.json.JArray
-import net.liftweb.json.JsonDSL._
+import net.liftweb.json.JString
class SecretApi(
@@ -62,7 +62,8 @@ class SecretApi(
def getLiftEndpoints(): List[LiftApiModule] = {
API.endpoints.map(
e => e match {
- case API.GetSecrets => GetSecrets
+ case API.GetAllSecret => GetAllSecret
+ case API.GetSecret => GetSecret
case API.AddSecret => AddSecret
case API.UpdateSecret => UpdateSecret
case API.DeleteSecret => DeleteSecret
@@ -70,27 +71,39 @@ class SecretApi(
)
}
- object GetSecrets extends LiftApiModule0 {
- val schema = API.GetSecrets
+ object GetAllSecret extends LiftApiModule0 {
+ val schema = API.GetAllSecret
val restExtractor = restExtractorService
def process0(version: ApiVersion, path: ApiPath, req: Req, params: DefaultParams, authzToken: AuthzToken): LiftResponse = {
implicit val prettify = params.prettify
- implicit val action = schema.name
+ implicit val action = schema.name
val res = for {
- secrets <- secretService.getSecrets
+ secrets <- secretService.getAllSecret.toBox
} yield {
- secrets.map(Secret.serializeSecret)
+ JArray(secrets.map(Secret.serializeSecretInfo))
}
- res.toBox match {
- case Full(json) =>
- RestUtils.toJsonResponse(None, JArray(json))
- case eb: EmptyBox =>
- val message = (eb ?~ s"Error when trying get secret from file").messageChain
- RestUtils.toJsonError(None, message)(action, true)
+ RestUtils.response(restExtractor, "secrets", None)(res, req, "Error when trying to get all secrets")
+ }
+ }
+
+ object GetSecret extends LiftApiModule {
+ val schema = API.GetSecret
+ val restExtractor = restExtractorService
+
+ def process(version: ApiVersion, path: ApiPath, id: String, req: Req, params: DefaultParams, authzToken: AuthzToken): LiftResponse = {
+ implicit val prettify = params.prettify
+ implicit val action = schema.name
+
+ val res = for {
+ secret <- secretService.getSecretById(id).notOptional(s"Could not find secret with `${id}` name").toBox
+ } yield {
+ JArray(List(Secret.serializeSecretInfo(secret)))
}
+
+ RestUtils.response(restExtractor, "secrets", None)(res, req, s"Error when trying to get secret `${id}` value")
}
}
@@ -104,18 +117,12 @@ class SecretApi(
val res = for {
secret <- restExtractorService.extractSecret(req)
- _ <- secretService.addSecret(secret).toBox
+ _ <- secretService.addSecret(secret, "Add a secret").toBox
} yield {
- Secret.serializeSecret(secret)
+ JArray(List(Secret.serializeSecretInfo(secret)))
}
- res match {
- case Full(json) =>
- RestUtils.toJsonResponse(None, json)
- case eb: EmptyBox =>
- val message = (eb ?~ s"Error when trying add a secret entry").messageChain
- RestUtils.toJsonError(None, message)(action, true)
- }
+ RestUtils.response(restExtractor, "secrets", None)(res, req, "Error when trying to add a secret")
}
}
@@ -128,18 +135,16 @@ class SecretApi(
implicit val action = schema.name
val res = for {
- _ <- secretService.deleteSecret(id).toBox
+ toDelete <- secretService.getSecretById(id).toBox
+ _ <- secretService.deleteSecret(id, "Delete a secret").toBox
} yield {
- id
+ toDelete match {
+ case Some(s) => JArray(List(Secret.serializeSecretInfo(s)))
+ case None => JArray(List(Secret.serializeSecretInfo(Secret(id, "", "")))) // don't know what to do here
+ }
}
- res match {
- case Full(secretId) =>
- RestUtils.toJsonResponse(None, secretId)
- case eb: EmptyBox =>
- val message = (eb ?~ s"Error when trying delete a secret entry").messageChain
- RestUtils.toJsonError(None, message)(action, true)
- }
+ RestUtils.response(restExtractor, "secrets", None)(res, req, "Error when trying to delete a secret")
}
}
@@ -153,17 +158,12 @@ class SecretApi(
val res = for {
secret <- restExtractorService.extractSecret(req)
- _ <- secretService.updateSecret(secret).toBox
+ _ <- secretService.updateSecret(secret, "Update a secret").toBox
} yield {
- Secret.serializeSecret(secret)
- }
- res match {
- case Full(json) =>
- RestUtils.toJsonResponse(None, json)
- case eb: EmptyBox =>
- val message = (eb ?~ s"Error when trying update a secret entry").messageChain
- RestUtils.toJsonError(None, message)(action, true)
+ JArray(List(Secret.serializeSecretInfo(secret)))
}
+
+ RestUtils.response(restExtractor, "secrets", None)(res, req, s"Error when trying to update a secret")
}
}
diff --git a/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/web/services/EventLogDetailsGenerator.scala b/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/web/services/EventLogDetailsGenerator.scala
index 8c13ec0e321..bd8d73b712a 100644
--- a/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/web/services/EventLogDetailsGenerator.scala
+++ b/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/web/services/EventLogDetailsGenerator.scala
@@ -827,15 +827,23 @@ class EventLogDetailsGenerator(
case mod:ModifySecret =>
"*" #> { logDetailsService.getSecretModifyDetails(mod.details) match {
case Full(modDiff) =>
+ val hasChanged = {
+ if(modDiff.modValue)
+ Some(
The value has been changed
)
+ else
+ None
+ }
Secret overview:
- Secret name: { modDiff.name }
+ - Secret description: { modDiff.description }
{(
"#name" #> modDiff.name &
- "#value" #> mapSimpleDiff(modDiff.modValue)
+ "#value" #> hasChanged &
+ "#description" #> mapSimpleDiff(modDiff.modDescription)
)(secretModDetailsXML)
}
{ reasonHtml }
@@ -1188,9 +1196,7 @@ class EventLogDetailsGenerator(
private[this] def secretDetails(xml: NodeSeq, secret: Secret) = (
"#name" #> secret.name &
- "#value" #> secret.value
-// &
-// "#description" #> globalParameter.description
+ "#description" #> secret.description
)(xml)
private[this] def apiAccountDetails(xml: NodeSeq, apiAccount: ApiAccount) = (
@@ -1328,7 +1334,7 @@ class EventLogDetailsGenerator(
Secret overview:
- Name:
- - Value:
+ - Description:
@@ -1428,6 +1434,7 @@ class EventLogDetailsGenerator(
{liModDetailsXML("name", "Name")}
{liModDetailsXML("value", "Value")}
+ {liModDetailsXML("description", "Description")}
diff --git a/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/web/services/SecretService.scala b/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/web/services/SecretService.scala
index b100ccca1e7..c743a113c02 100644
--- a/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/web/services/SecretService.scala
+++ b/webapp/sources/rudder/rudder-rest/src/main/scala/com/normation/rudder/web/services/SecretService.scala
@@ -38,12 +38,17 @@ package com.normation.rudder.web.services
import better.files.File
import com.normation.NamedZioLogger
+import com.normation.cfclerk.services.GitRepositoryProvider
import com.normation.errors.IOResult
import com.normation.errors.Inconsistency
import com.normation.eventlog.ModificationId
+import com.normation.rudder.domain.eventlog.RudderEventActor
import com.normation.rudder.domain.secrets._
import com.normation.rudder.repository.EventLogRepository
+import com.normation.rudder.repository.GitModificationRepository
import com.normation.rudder.web.services.CurrentUserService.actor
+import com.normation.rudder.repository.xml._
+import com.normation.rudder.services.user.PersonIdentService
import com.normation.utils.StringUuidGenerator
import net.liftweb.json.JsonAST.JValue
import net.liftweb.json.JsonDSL._
@@ -55,19 +60,28 @@ import zio.syntax._
import java.nio.charset.StandardCharsets
trait SecretService {
- def getSecrets: IOResult[List[Secret]]
- def addSecret(s: Secret): IOResult[Unit]
- def deleteSecret(secretId: String): IOResult[Unit]
- def updateSecret(newSecret: Secret): IOResult[Unit]
+ def getAllSecret: IOResult[List[Secret]]
+ def getSecretById(secretId: String): IOResult[Option[Secret]]
+ def addSecret(s: Secret, reason: String): IOResult[Unit]
+ def deleteSecret(secretId: String, reason: String): IOResult[Unit]
+ def updateSecret(newSecret: Secret, reason: String): IOResult[Unit]
}
class FileSystemSecretRepository(
- jsonDbPath : String
- , actionLogger : EventLogRepository
- , uuidGen : StringUuidGenerator
-) extends SecretService {
+ jsonDbPath : String
+ , actionLogger : EventLogRepository
+ , uuidGen : StringUuidGenerator
+ , personIdentService : PersonIdentService
+ , override val gitRepo : GitRepositoryProvider
+ , override val gitRootDirectory : java.io.File
+ , override val xmlPrettyPrinter : RudderPrettyPrinter
+ , override val gitModificationRepository: GitModificationRepository
+ , override val encoding : String
+ , override val groupOwner : String
+) extends SecretService with GitArchiverUtils {
- private val secretsFile = File(jsonDbPath)
+ override val relativePath = "secrets"
+ private val secretsFile = File(s"/var/rudder/configuration-repository/${jsonDbPath}")
val logger = NamedZioLogger(this.getClass.getName)
private[this] def parseVersion1(json: JValue): IOResult[List[Secret]] = {
@@ -90,6 +104,8 @@ class FileSystemSecretRepository(
}
def init(version: String): IOResult[Unit] = {
+ val modId = ModificationId(uuidGen.newUuid)
+
val json =
s"""
| {
@@ -100,35 +116,43 @@ class FileSystemSecretRepository(
| }
|
|""".stripMargin
- for {
- _ <- ZIO.when(secretsFile.notExists){
- IOResult.effect{
- val f = secretsFile.createFileIfNotExists(createParents = true)
- f.write(json)
- }
- }
- } yield ()
+
+ ZIO.when(secretsFile.notExists) {
+ IOResult.effect {
+ val f = secretsFile.createFileIfNotExists(createParents = true)
+ f.write(json)
+ for {
+ ident <- personIdentService.getPersonIdentOrDefault(RudderEventActor.name)
+ _ <- commitAddFile(modId, ident, secretsFile.canonicalPath, "Create secrets file")
+ } yield ()
+ }
+ }
}
- override def getSecrets: IOResult[List[Secret]] = {
+ override def getAllSecret: IOResult[List[Secret]] = {
for {
s <- getSecretJsonContent
} yield s
}
+ override def getSecretById(id: String): IOResult[Option[Secret]] = {
+ for {
+ s <- getSecretJsonContent
+ } yield s.find(_.name == id)
+ }
+
private[this] def replaceInFile(formatVersion: String, secrets: List[Secret]): IOResult[Unit] = {
IOResult.effect{
secretsFile.clear()
val json =
( ("formatVersion" -> formatVersion)
- ~ ("secrets" -> secrets.map(Secret.serializeSecret))
+ ~ ("secrets" -> secrets.map(serializeSecret))
)
secretsFile.write(net.liftweb.json.prettyRender(json))
}
}
- override def addSecret(secToAdd: Secret): IOResult[Unit] = {
- val reason = "Add a secret"
+ override def addSecret(secToAdd: Secret, reason: String): IOResult[Unit] = {
val modId = ModificationId(uuidGen.newUuid)
val formatVersion = "1.0"
@@ -150,13 +174,15 @@ class FileSystemSecretRepository(
_ <- actionLogger.saveAddSecret(modId, actor, secToAdd, Some(reason)).catchAll { e =>
logger.error(s"Error when trying to create event log `${modId.value}` for adding secret `${secToAdd.name}`, cause : ${e.fullMsg}")
}
+ ident <- personIdentService.getPersonIdentOrDefault(RudderEventActor.name)
+ _ <- commitAddFile(modId, ident, secretsFile.canonicalPath, "Saving added Secret")
+
} yield ()
}
} yield ()
}
- override def deleteSecret(secretId: String): IOResult[Unit] = {
- val reason = "Delete a secret"
+ override def deleteSecret(secretId: String, reason: String): IOResult[Unit] = {
val modId = ModificationId(uuidGen.newUuid)
val formatVersion = "1.0"
for {
@@ -171,15 +197,16 @@ class FileSystemSecretRepository(
_ <- actionLogger.saveDeleteSecret(modId, actor, secToDel, Some(reason)).catchAll { e =>
logger.error(s"Error when trying to create event log `${modId.value}` for deleting secret `${secToDel.name}`, cause : ${e.fullMsg}")
}
+ ident <- personIdentService.getPersonIdentOrDefault(RudderEventActor.name)
+ _ <- commitAddFile(modId, ident, secretsFile.canonicalPath, "Saving deleted Secret")
} yield ()
case None =>
- logger.warn(s"Trying to delete secret ${secretId} but it doesn't exists")
+ logger.warn(s"Trying to delete secret ${secretId} but it doesn't exist")
}
} yield ()
}
- override def updateSecret(newSecret: Secret): IOResult[Unit] = {
- val reason = "Update a secret"
+ override def updateSecret(newSecret: Secret, reason: String): IOResult[Unit] = {
val modId = ModificationId(uuidGen.newUuid)
val formatVersion = "1.0"
for {
@@ -188,8 +215,8 @@ class FileSystemSecretRepository(
oldSecret = secrets.find(_.name == newSecret.name)
_ <- oldSecret match {
case Some(oldSec) =>
- if(oldSec.value == newSecret.value) {
- logger.warn(s"Trying to update secret `${oldSec.name}` with the same value")
+ if(oldSec.value == newSecret.value && oldSec.description == newSecret.description) {
+ UIO.unit
} else {
// Only one secret should be replaced here
val newSecrets = secrets.map( s => if(s.name == newSecret.name) newSecret else s)
@@ -198,11 +225,21 @@ class FileSystemSecretRepository(
_ <- actionLogger.saveModifySecret(modId, actor, oldSec, newSecret, Some(reason)).catchAll { e =>
logger.error(s"Error when trying to update event log `${modId.value}` for updating secret `${oldSec.name}`, cause : ${e.fullMsg}")
}
+ ident <- personIdentService.getPersonIdentOrDefault(RudderEventActor.name)
+ _ <- commitAddFile(modId, ident, secretsFile.canonicalPath, "Saving updated Secret")
+
} yield ()
}
case None =>
- Inconsistency(s"Error when trying to update secret `${newSecret.name}`, this secret doesn't exists").fail
+ Inconsistency(s"Error when trying to update secret `${newSecret.name}`, this secret doesn't exist").fail
}
} yield ()
}
+
+ private[this] def serializeSecret(secret : Secret): JValue = {
+ ( ("name" -> secret.name)
+ ~ ("description" -> secret.description)
+ ~ ("value" -> secret.value)
+ )
+ }
}
diff --git a/webapp/sources/rudder/rudder-web/src/main/scala/bootstrap/liftweb/RudderConfig.scala b/webapp/sources/rudder/rudder-web/src/main/scala/bootstrap/liftweb/RudderConfig.scala
index bacd1cab8a5..29e504ca4e3 100644
--- a/webapp/sources/rudder/rudder-web/src/main/scala/bootstrap/liftweb/RudderConfig.scala
+++ b/webapp/sources/rudder/rudder-web/src/main/scala/bootstrap/liftweb/RudderConfig.scala
@@ -841,9 +841,16 @@ object RudderConfig extends Loggable {
val restCompletion = new RestCompletion(new RestCompletionService(roDirectiveRepository, roRuleRepository))
val secretVaultService = new FileSystemSecretRepository(
- "/var/rudder/configuration-repository/secrets.json"
+ "secrets/secrets.json"
, eventLogRepository
, stringUuidGenerator
+ , personIdentService
+ , gitRepo
+ , new File(RUDDER_DIR_GITROOT)
+ , prettyPrinter
+ , gitModificationRepository
+ , RUDDER_CHARSET.name
+ , RUDDER_GROUP_OWNER_CONFIG_REPO
)
val ruleApiService2 =