Skip to content

Commit

Permalink
https://github.com/DASISH/qddt-client/issues/770
Browse files Browse the repository at this point in the history
  • Loading branch information
StigNorland committed Jan 18, 2022
1 parent 41dfe58 commit 8217672
Show file tree
Hide file tree
Showing 27 changed files with 265 additions and 133 deletions.
6 changes: 5 additions & 1 deletion src/main/kotlin/no/nsd/qddt/config/SecurityConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.data.repository.query.ExtensionAwareQueryMethodEvaluationContextProvider
import org.springframework.data.spel.spi.EvaluationContextExtension
import org.springframework.http.HttpMethod
import org.springframework.security.access.PermissionEvaluator
Expand Down Expand Up @@ -66,6 +65,11 @@ class SecurityConfig : WebSecurityConfigurerAdapter() {
fun bCryptPasswordEncoderBean(): PasswordEncoder {
return BCryptPasswordEncoder()
}

// @Bean
// fun securityExtension(): EvaluationContextExtension? {
// return SecurityEvaluationContextExtension()
// }
//
// @Bean
// fun securityExtension(): EvaluationContextExtension? {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package no.nsd.qddt.config.exception

import net.logstash.logback.encoder.org.apache.commons.lang3.exception.ExceptionUtils.getRootCauseMessage
import org.apache.commons.lang3.exception.ExceptionUtils
import org.slf4j.LoggerFactory
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
Expand Down Expand Up @@ -35,7 +35,7 @@ class ControllerExceptionAdvice {
@ResponseBody
fun handleResourceNotFound(req: HttpServletRequest, e: Exception): ControllerAdviceExceptionMessage {
val message = ControllerAdviceExceptionMessage(
req.getRequestURL().toString(),
req.requestURL.toString(),
e.localizedMessage
)
logger.error("EntityModeL not found: $message")
Expand All @@ -56,7 +56,7 @@ class ControllerExceptionAdvice {
@ResponseBody
fun handleUserByEmailNotFound(req: HttpServletRequest, e: Exception): ControllerAdviceExceptionMessage {
val message = ControllerAdviceExceptionMessage(
req.getRequestURL().toString(),
req.requestURL.toString(),
e.localizedMessage
)
logger.error("User not found: $message")
Expand Down Expand Up @@ -96,8 +96,8 @@ class ControllerExceptionAdvice {
@ResponseBody
fun handleConcurencyCheckedFailed(req: HttpServletRequest, e: Exception): ControllerAdviceExceptionMessage {
val message = ControllerAdviceExceptionMessage(
req.getRequestURL().toString(),
(e as ObjectOptimisticLockingFailureException).getMostSpecificCause().message
req.requestURL.toString(),
(e as ObjectOptimisticLockingFailureException).mostSpecificCause.message
)
logger.error("ConcurencyCheckedFailed: $e")
return message
Expand All @@ -117,8 +117,8 @@ class ControllerExceptionAdvice {
@ResponseBody
fun handleRetrievalFailure(req: HttpServletRequest, e: Exception): ControllerAdviceExceptionMessage {
val message = ControllerAdviceExceptionMessage(
req.getRequestURL().toString(),
(e as JpaObjectRetrievalFailureException).getMostSpecificCause().message
req.requestURL.toString(),
(e as JpaObjectRetrievalFailureException).mostSpecificCause.message
)
if (message.exceptionMessage!!.contains("Category") && message.url.contains("responsedomain")) {
message.userfriendlyMessage =
Expand All @@ -145,7 +145,7 @@ class ControllerExceptionAdvice {
@ResponseBody
fun handleRefInUseFailure(req: HttpServletRequest, e: Exception): ControllerAdviceExceptionMessage {
val message = ControllerAdviceExceptionMessage(
req.getRequestURL().toString(),
req.requestURL.toString(),
e.message
)
message.userfriendlyMessage =
Expand All @@ -165,10 +165,10 @@ class ControllerExceptionAdvice {
@ResponseBody
fun handleAccessDeniedException(req: HttpServletRequest, e: Exception): ControllerAdviceExceptionMessage {
val message = ControllerAdviceExceptionMessage(
req.getRequestURL().toString(),
req.requestURL.toString(),
e.localizedMessage
)
message.userfriendlyMessage = getRootCauseMessage(e.cause)
message.userfriendlyMessage = ExceptionUtils.getRootCauseMessage(e.cause)
logger.error(e.javaClass.simpleName, e)
return message
}
Expand All @@ -185,10 +185,10 @@ class ControllerExceptionAdvice {
@ResponseBody
fun handleInvalidPasswordException(req: HttpServletRequest, e: Exception): ControllerAdviceExceptionMessage {
val message = ControllerAdviceExceptionMessage(
req.getRequestURL().toString(),
req.requestURL.toString(),
e.localizedMessage
)
message.userfriendlyMessage = getRootCauseMessage(e.cause)
message.userfriendlyMessage = ExceptionUtils.getRootCauseMessage(e.cause)
logger.error(e.javaClass.simpleName, e)
return message
}
Expand All @@ -205,10 +205,10 @@ class ControllerExceptionAdvice {
@ResponseBody
fun handleDescendantsArchivedException(req: HttpServletRequest, e: Exception): ControllerAdviceExceptionMessage {
val message = ControllerAdviceExceptionMessage(
req.getRequestURL().toString(),
req.requestURL.toString(),
e.localizedMessage
)
message.userfriendlyMessage = getRootCauseMessage(e.cause)
message.userfriendlyMessage = ExceptionUtils.getRootCauseMessage(e.cause)
return message
}

Expand All @@ -224,12 +224,12 @@ class ControllerExceptionAdvice {
@ResponseBody
fun defaultErrorHandler(req: HttpServletRequest, e: Exception): ControllerAdviceExceptionMessage {
val message = ControllerAdviceExceptionMessage(
req.getRequestURL().toString(),
req.requestURL.toString(),
e.localizedMessage
)
message.userfriendlyMessage = getRootCauseMessage(e.cause)
message.userfriendlyMessage = ExceptionUtils.getRootCauseMessage(e.cause)
logger.error(e.javaClass.simpleName, e)
logger.error(req.getRequestURI())
logger.error(req.requestURI)
logger.error("stacktrace", e.fillInStackTrace())
return message
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import org.springframework.data.domain.Sort
import org.springframework.data.history.Revision
import org.springframework.hateoas.*
import org.springframework.hateoas.mediatype.hal.HalModelBuilder
import org.springframework.hateoas.server.core.EmbeddedWrapper
import org.springframework.hateoas.server.mvc.BasicLinkBuilder
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.PathVariable
Expand Down Expand Up @@ -61,7 +62,7 @@ abstract class AbstractRestController<T : AbstractEntityAudit>( val repository:

logger.debug("getRevisions PagedModel: {}" , qPage)
val revisions = repository.findRevisions(uri, qPage).map { rev -> entityRevisionModelBuilder(rev) }
return PagedModel.wrap(revisions.content, pageMetadataBuilder(revisions))
return PagedModel.of(revisions.content, pageMetadataBuilder(revisions), Link.of("revisions"))
}

@ResponseBody
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import no.nsd.qddt.repository.ControlConstructRepository
import no.nsd.qddt.repository.PublicationStatusRepository
import no.nsd.qddt.service.OtherMaterialService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.rest.webmvc.BasePathAwareController
import org.springframework.data.rest.webmvc.RepositoryRestController
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
Expand All @@ -18,7 +19,7 @@ import java.io.IOException
import java.util.*


@RepositoryRestController
@BasePathAwareController
class ControlConstructController (@Autowired repository: ControlConstructRepository<ControlConstruct>): AbstractRestController<ControlConstruct>(repository) {

@Autowired
Expand Down
114 changes: 67 additions & 47 deletions src/main/kotlin/no/nsd/qddt/controller/PublicationController.kt
Original file line number Diff line number Diff line change
@@ -1,66 +1,32 @@
package no.nsd.qddt.controller

import no.nsd.qddt.model.Publication
import no.nsd.qddt.model.PublicationStatus
import no.nsd.qddt.model.Study
import no.nsd.qddt.model.SurveyProgram
import no.nsd.qddt.model.classes.UriId
import no.nsd.qddt.repository.PublicationRepository
import no.nsd.qddt.repository.PublicationStatusRepository
import no.nsd.qddt.repository.criteria.PublicationCriteria
import org.hibernate.Hibernate
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.data.domain.Sort
import org.springframework.data.rest.webmvc.BasePathAwareController
import org.springframework.hateoas.EntityModel
import org.springframework.hateoas.RepresentationModel
import org.springframework.data.web.PagedResourcesAssembler
import org.springframework.hateoas.*
import org.springframework.hateoas.mediatype.hal.HalModelBuilder
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.transaction.annotation.Propagation
import org.springframework.transaction.annotation.Transactional
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import java.security.Principal
import org.springframework.web.bind.annotation.*
import java.util.*


@BasePathAwareController
class PublicationController(@Autowired repository: PublicationRepository): AbstractRestController<Publication>(repository) {

@Autowired
lateinit var publicationStatusRepository: PublicationStatusRepository

@GetMapping("/publication/status",produces = ["application/json"])
fun getHierarchy(): ResponseEntity<MutableList<PublicationStatus>> {
val args = mutableListOf<Int>(0, 1, 2)

return ResponseEntity.ok(publicationStatusRepository.findAllById(args))
}

@GetMapping("/publication/status/flat",produces = ["application/json"])
fun getAllStatus(): ResponseEntity<MutableList<PublicationStatus>> {
return ResponseEntity.ok(publicationStatusRepository.findAll(Sort.by("id")))
}


@GetMapping("/publication/test",produces = ["application/hal+json"])
fun getAllByTest(user: Principal,
pageable: Pageable?): ResponseEntity<EntityModel<Page<Publication>>> {
val details = user as UsernamePasswordAuthenticationToken
logger.debug(details.principal.toString())
val page = repository.findAll(pageable?: Pageable.unpaged())
return ResponseEntity.ok(EntityModel.of(page))
}

// @GetMapping("/publication",produces = ["application/hal+json"])
// fun getAllBy(@CurrentSecurityContext(expression = "authentication") authentication: Authentication,
// pageable: Pageable?): ResponseEntity<EntityModel<Page<Publication>>> {
// val details = authentication.principal as User
// val page = repository.findAll(pageable?: Pageable.unpaged())
// return ResponseEntity.ok(EntityModel.of(page))
// }

// @GetMapping("/publication/{uri}",produces = ["application/hal+json"])
// override fun getById(@PathVariable uri: String): ResponseEntity<EntityModel<Publication>> {
// return super.getById(uri)
// }
// @Autowired
// private lateinit var pagedResourcesAssembler: PagedResourcesAssembler<RepresentationModel<EntityModel<Publication>>>

@Transactional(propagation = Propagation.REQUIRED)
@GetMapping("/publication/revision/{uri}", produces = ["application/hal+json"])
Expand All @@ -84,4 +50,58 @@ class PublicationController(@Autowired repository: PublicationRepository): Abstr
override fun getXml(@PathVariable uri: String): ResponseEntity<String> {
return super.getXml(uri)
}

@ResponseBody
@PostMapping("/publication", produces = ["application/hal+json"])
fun save(@RequestBody publication: Publication): ResponseEntity<RepresentationModel<EntityModel<Publication>>> {
return ResponseEntity.ok(entityModelBuilder(repository.save(publication)))
}

@ResponseBody
@Transactional(propagation = Propagation.REQUIRED)
@GetMapping("/publication/search/findByQuery", produces = ["application/hal+json"])
fun getByQuery(publicationCriteria: PublicationCriteria,pageable: Pageable?): RepresentationModel<*> {

if (publicationCriteria == null)
throw Exception("no criteria")

logger.debug(publicationCriteria.toString())
val entities = (repository as PublicationRepository).findByQuery(
publicationCriteria.publishedKind!!,
publicationCriteria.publicationStatus!!,
publicationCriteria.purpose!!,
publicationCriteria.xmlLang!!,
publicationCriteria.name!!,
publicationCriteria.getAngencyId(),pageable).map {
entityModelBuilder(it)
}

return PagedModel.of(entities.content,pageMetadataBuilder(entities), Link.of("publications"))
}

override fun entityModelBuilder(entity: Publication): RepresentationModel<EntityModel<Publication>> {
val uriId = UriId.fromAny("${entity.id}:${entity.version.rev}")
logger.debug("entityModelBuilder Publication : {}" , uriId)
val baseUrl = if(uriId.rev != null)
"${baseUri}/publication/revision/${uriId}"
else
"${baseUri}/publication/${uriId.id}"
entity.comments.size
entity.comments.forEach {
logger.debug("initialize(comments.modifiedBy)")
Hibernate.initialize(it.modifiedBy)
}
Hibernate.initialize(entity.agency)
Hibernate.initialize(entity.modifiedBy)
Hibernate.initialize(entity.status)
return HalModelBuilder.halModel()
.entity(entity)
.link(Link.of(baseUrl))
.embed(entity.agency,LinkRelation.of("agency"))
.embed(entity.modifiedBy,LinkRelation.of("modifiedBy"))
.embed(entity.comments,LinkRelation.of("comments"))
.embed(entity.status,LinkRelation.of("status"))
.build()
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import no.nsd.qddt.model.QuestionItem
import no.nsd.qddt.repository.QuestionItemRepository
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.domain.Pageable
import org.springframework.data.rest.webmvc.BasePathAwareController
import org.springframework.data.rest.webmvc.RepositoryRestController
import org.springframework.hateoas.RepresentationModel
import org.springframework.http.MediaType
Expand All @@ -14,7 +15,7 @@ import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import java.util.*

@RepositoryRestController
@BasePathAwareController
class QuestionItemController(@Autowired repository: QuestionItemRepository): AbstractRestController<QuestionItem>(repository) {

// @GetMapping("/questionitem/{uri}",produces = ["application/hal+json"])
Expand Down
24 changes: 18 additions & 6 deletions src/main/kotlin/no/nsd/qddt/controller/SurveyProgramController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import org.springframework.data.domain.Pageable
import org.springframework.data.rest.webmvc.BasePathAwareController
import org.springframework.hateoas.*
import org.springframework.hateoas.mediatype.hal.HalModelBuilder
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.security.core.context.SecurityContextHolder
Expand Down Expand Up @@ -57,10 +58,21 @@ class SurveyProgramController(@Autowired repository: SurveyProgramRepository): A
// @Transactional(propagation = Propagation.REQUIRED)
// @GetMapping("/surveyprogram", produces = ["application/json"])
// fun getAllByAgency(): ResponseEntity<List<SurveyProgram>> {
// val user = SecurityContextHolder.getContext().authentication.principal as no.nsd.qddt.model.User
// try {
// val user = SecurityContextHolder.getContext().authentication.principal as no.nsd.qddt.model.User
// val surveys = (repository as SurveyProgramRepository).findByAgency(user.agency)
// surveys.forEach {
// it.authors.size
// it.children.size
// it.comments.size
// }
//
// return ResponseEntity.ok((repository as SurveyProgramRepository).findByAgency(user.agency))
//// .map {entityModelBuilder(it)}
// return ResponseEntity.ok(surveys)
// //.map {entityModelBuilder(it)})
// } catch (ex: Exception) {
// logger.error(ex.localizedMessage)
// return ResponseEntity(HttpStatus.NO_CONTENT)
// }
// }


Expand All @@ -77,7 +89,7 @@ class SurveyProgramController(@Autowired repository: SurveyProgramRepository): A
}
private fun entityModelBuilder(entity: Study): RepresentationModel<EntityModel<Study>> {
logger.debug("entityModelBuilder SurveyProgram Study: {}" , entity.id)
entity.children.size
// entity.children.size
entity.authors.size
entity.comments.size
entity.instruments.size
Expand All @@ -104,7 +116,7 @@ class SurveyProgramController(@Autowired repository: SurveyProgramRepository): A
entity.authors.size
entity.comments.size
entity.comments.forEach {
logger.debug("initialize(it")
logger.debug("initialize(comments.modifiedBy)")
Hibernate.initialize(it.modifiedBy)
}
Hibernate.initialize(entity.agency)
Expand All @@ -118,7 +130,7 @@ class SurveyProgramController(@Autowired repository: SurveyProgramRepository): A
.embed(entity.authors,LinkRelation.of("authors"))
.embed(entity.children.map {
entityModelBuilder(it as Study)
}, LinkRelation.of("studies"))
}, LinkRelation.of("children"))
.build()
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/no/nsd/qddt/model/Comment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ data class Comment(
@Column(updatable = false, nullable = false)
var ownerIdx: Int? = 0,

@Column(updatable = false, nullable = false)
@Column(name = "OWNER_ID", updatable = false, nullable = false)
var ownerId: UUID? = null,

@OrderColumn(name = "ownerIdx")
Expand Down
Loading

0 comments on commit 8217672

Please sign in to comment.