Skip to content
Permalink
Browse files
refactor(admin): refactor projects & users value objects (DEV-240) (#…
…1976)

* refactor(userADM):  user create payload

* refactor(userADM): add error messages + update value objects

* refactor(userADM): move value objects to dedicated file

* refactor(userADM): add value objects unit tests + error messages

* refactor(userADM): remove old user value objects e2e aka unit tests

* refactor(userADM): remove bad method

* refactor(userADM): bring back ValueObjectsADMSpec config

* refactor(projectADM): rename files

* refactor(projectsADM): move ProjectIRI value object + add optional handling

* refactor(projectsADM): add error messages

* refactor(projectsADM): fix users and projects value objedcts names

* refactor(projectsADM): fix payload class name

* refactor(projectsADM): update value objects

* refactor(projectsADM): add value objects unit tests

* refactor(projectsADM): tests cleanup

* refactor(projectsADM): to trick sonar complains

* cleanup

* refactor filenames

* add missing types and licence

* review changes

* refactor(projectsADM): remove redundant validation and tests
  • Loading branch information
mpro7 committed Jan 14, 2022
1 parent 27b5c86 commit 563d25255d3621f8b2d803e5133a9974eb000c0a
Showing with 1,117 additions and 1,127 deletions.
  1. +5 −0 ...i/src/main/scala/org/knora/webapi/messages/admin/responder/groupsmessages/GroupsPayloadsADM.scala
  2. +0 −3 ...rc/main/scala/org/knora/webapi/messages/admin/responder/listsmessages/ListsErrorMessagesADM.scala
  3. +5 −0 ...ra/webapi/messages/admin/responder/listsmessages/{ListPayloadsADM.scala → ListsPayloadsADM.scala}
  4. +0 −28 ...in/scala/org/knora/webapi/messages/admin/responder/projectsmessages/ProjectCreatePayloadADM.scala
  5. +23 −0 ...n/scala/org/knora/webapi/messages/admin/responder/projectsmessages/ProjectsErrorMessagesADM.scala
  6. +4 −62 ...c/main/scala/org/knora/webapi/messages/admin/responder/projectsmessages/ProjectsMessagesADM.scala
  7. +23 −0 ...c/main/scala/org/knora/webapi/messages/admin/responder/projectsmessages/ProjectsPayloadsADM.scala
  8. +0 −61 webapi/src/main/scala/org/knora/webapi/messages/admin/responder/usersmessages/UserPayloadsADM.scala
  9. +23 −0 ...rc/main/scala/org/knora/webapi/messages/admin/responder/usersmessages/UsersErrorMessagesADM.scala
  10. +3 −3 webapi/src/main/scala/org/knora/webapi/messages/admin/responder/usersmessages/UsersMessagesADM.scala
  11. +23 −0 webapi/src/main/scala/org/knora/webapi/messages/admin/responder/usersmessages/UsersPayloadsADM.scala
  12. +4 −4 ...src/main/scala/org/knora/webapi/messages/admin/responder/valueObjects/GroupsValueObjectsADM.scala
  13. +0 −37 ...pi/src/main/scala/org/knora/webapi/messages/admin/responder/valueObjects/IriValueObjectsADM.scala
  14. +4 −4 .../src/main/scala/org/knora/webapi/messages/admin/responder/valueObjects/ListsValueObjectsADM.scala
  15. +194 −0 ...c/main/scala/org/knora/webapi/messages/admin/responder/valueObjects/ProjectsValueObjectsADM.scala
  16. +201 −0 .../src/main/scala/org/knora/webapi/messages/admin/responder/valueObjects/UsersValueObjectsADM.scala
  17. +0 −262 webapi/src/main/scala/org/knora/webapi/messages/admin/responder/valueObjects/ValueObjectsADM.scala
  18. +7 −35 webapi/src/main/scala/org/knora/webapi/responders/admin/ProjectsResponderADM.scala
  19. +23 −23 webapi/src/main/scala/org/knora/webapi/responders/admin/UsersResponderADM.scala
  20. +11 −10 webapi/src/main/scala/org/knora/webapi/routing/admin/GroupsRouteADM.scala
  21. +10 −24 webapi/src/main/scala/org/knora/webapi/routing/admin/ProjectsRouteADM.scala
  22. +47 −59 webapi/src/main/scala/org/knora/webapi/routing/admin/UsersRouteADM.scala
  23. +0 −33 webapi/src/test/scala/org/knora/webapi/e2e/admin/UsersADME2ESpec.scala
  24. +0 −107 ...st/scala/org/knora/webapi/messages/admin/responder/projectsmessages/ProjectsMessagesADMSpec.scala
  25. +2 −1 webapi/src/test/scala/org/knora/webapi/messages/admin/responder/valueObjects/BUILD.bazel
  26. +0 −44 ...rc/test/scala/org/knora/webapi/messages/admin/responder/valueObjects/IriValueObjectsADMSpec.scala
  27. +207 −0 ...st/scala/org/knora/webapi/messages/admin/responder/valueObjects/ProjectsValueObjectsADMSpec.scala
  28. +229 −0 .../test/scala/org/knora/webapi/messages/admin/responder/valueObjects/UsersValueObjectsADMSpec.scala
  29. +0 −202 ...i/src/test/scala/org/knora/webapi/messages/admin/responder/valueObjects/ValueObjectsADMSpec.scala
  30. +19 −45 webapi/src/test/scala/org/knora/webapi/responders/admin/ProjectsResponderADMSpec.scala
  31. +50 −80 webapi/src/test/scala/org/knora/webapi/responders/admin/UsersResponderADMSpec.scala
@@ -1,3 +1,8 @@
/*
* Copyright © 2021 Data and Service Center for the Humanities and/or DaSCH Service Platform contributors.
* SPDX-License-Identifier: Apache-2.0
*/

package org.knora.webapi.messages.admin.responder.groupsmessages

import org.knora.webapi.messages.admin.responder.valueObjects._
@@ -10,9 +10,6 @@ object ListsErrorMessagesADM {
val LIST_IRI_INVALID_ERROR = "List IRI cannot be empty."
val LIST_NODE_IRI_MISSING_ERROR = "List node IRI cannot be empty."
val LIST_NODE_IRI_INVALID_ERROR = "List node IRI is invalid."
// TODO-mpro: move project messages
val PROJECT_IRI_MISSING_ERROR = "Project IRI cannot be empty."
val PROJECT_IRI_INVALID_ERROR = "Project IRI is invalid."
val LIST_NAME_MISSING_ERROR = "List name cannot be empty."
val LIST_NAME_INVALID_ERROR = "List name is invalid."
val LABEL_MISSING_ERROR = "At least one label needs to be supplied."
@@ -1,3 +1,8 @@
/*
* Copyright © 2021 Data and Service Center for the Humanities and/or DaSCH Service Platform contributors.
* SPDX-License-Identifier: Apache-2.0
*/

package org.knora.webapi.messages.admin.responder.listsmessages

import org.knora.webapi.messages.admin.responder.valueObjects._

This file was deleted.

@@ -0,0 +1,23 @@
/*
* Copyright © 2021 Data and Service Center for the Humanities and/or DaSCH Service Platform contributors.
* SPDX-License-Identifier: Apache-2.0
*/

package org.knora.webapi.messages.admin.responder.projectsmessages

object ProjectsErrorMessagesADM {
val PROJECT_IRI_MISSING_ERROR = "Project IRI cannot be empty."
val PROJECT_IRI_INVALID_ERROR = "Project IRI is invalid."
val SHORTCODE_MISSING_ERROR = "Shortcode cannot be empty."
val SHORTCODE_INVALID_ERROR = "Shortcode is invalid."
val SHORTNAME_MISSING_ERROR = "Shortname cannot be empty."
val SHORTNAME_INVALID_ERROR = "Shortname is invalid."
val LONGNAME_MISSING_ERROR = "Longname cannot be empty."
val LONGNAME_INVALID_ERROR = "Longname is invalid."
val PROJECT_DESCRIPTION_MISSING_ERROR = "Description cannot be empty."
val PROJECT_DESCRIPTION_INVALID_ERROR = "Description is invalid."
val KEYWORDS_MISSING_ERROR = "Keywords cannot be empty."
val KEYWORDS_INVALID_ERROR = "Keywords are invalid."
val LOGO_MISSING_ERROR = "Logo cannot be empty."
val LOGO_INVALID_ERROR = "Logo is invalid."
}
@@ -5,8 +5,6 @@

package org.knora.webapi.messages.admin.responder.projectsmessages

import java.nio.file.Path
import java.util.UUID
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import org.apache.commons.lang3.builder.HashCodeBuilder
import org.knora.webapi.IRI
@@ -20,6 +18,9 @@ import org.knora.webapi.messages.store.triplestoremessages.{StringLiteralV2, Tri
import org.knora.webapi.messages.v1.responder.projectmessages.ProjectInfoV1
import spray.json.{DefaultJsonProtocol, JsValue, JsonFormat, RootJsonFormat}

import java.nio.file.Path
import java.util.UUID

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// API requests

@@ -47,67 +48,8 @@ case class CreateProjectApiRequestADM(
status: Boolean,
selfjoin: Boolean
) extends ProjectsADMJsonProtocol {
implicit protected val stringFormatter: StringFormatter = StringFormatter.getGeneralInstance

// Check that collection parameters are not empty.
if (description.isEmpty) throw BadRequestException("Project description needs to be supplied.")
if (keywords.isEmpty) throw BadRequestException("At least one keyword must be supplied for a new project.")
if (shortcode.isEmpty) throw BadRequestException("Project shortcode must be supplied.")
if (shortname.isEmpty) throw BadRequestException("Project shortname must be supplied.")

/* Convert to Json */
def toJsValue: JsValue = createProjectApiRequestADMFormat.write(this)

/* validates and escapes the given values.*/
def validateAndEscape: CreateProjectApiRequestADM = {
val maybeProjectIri =
stringFormatter.validateAndEscapeOptionalProjectIri(id, throw BadRequestException(s"Invalid project IRI"))
val validatedShortcode = stringFormatter.validateAndEscapeProjectShortcode(
shortcode,
errorFun = throw BadRequestException(s"The supplied short code: '$shortcode' is not valid.")
)

val validatedShortname = stringFormatter.validateAndEscapeProjectShortname(
shortname,
errorFun = throw BadRequestException(s"The supplied short name: '$shortname' is not valid.")
)

val validatedLongName = stringFormatter.escapeOptionalString(
longname,
errorFun = throw BadRequestException(s"The supplied longname: '$longname' is not valid.")
)

val validatedLogo = stringFormatter.escapeOptionalString(
logo,
errorFun = throw BadRequestException(s"The supplied logo: '$logo' is not valid.")
)

val validatedDescriptions: Seq[StringLiteralV2] = description.map { des =>
val escapedValue =
stringFormatter.toSparqlEncodedString(
des.value,
errorFun = throw BadRequestException(s"The supplied description: '${des.value}' is not valid.")
)
StringLiteralV2(value = escapedValue, language = des.language)
}

val validatedKeywords = keywords.map(keyword =>
stringFormatter.toSparqlEncodedString(
keyword,
errorFun = throw BadRequestException(s"The supplied keyword: '$keyword' is not valid.")
)
)
copy(
id = maybeProjectIri,
shortcode = validatedShortcode,
shortname = validatedShortname,
longname = validatedLongName,
description = validatedDescriptions,
keywords = validatedKeywords,
logo = validatedLogo
)
}

}

/**
@@ -350,7 +292,7 @@ case class ProjectDataGetRequestADM(
/**
* Requests the creation of a new project.
*
* @param createRequest the [[ProjectCreatePayloadADM]] information for creation a new project.
* @param createRequest the [[ProjectCreatePayloadADM]] information for the creation of a new project.
* @param featureFactoryConfig the feature factory configuration.
* @param requestingUser the user making the request.
* @param apiRequestID the ID of the API request.
@@ -0,0 +1,23 @@
/*
* Copyright © 2021 Data and Service Center for the Humanities and/or DaSCH Service Platform contributors.
* SPDX-License-Identifier: Apache-2.0
*/

package org.knora.webapi.messages.admin.responder.projectsmessages

import org.knora.webapi.messages.admin.responder.valueObjects._

/**
* Project creation payload
*/
final case class ProjectCreatePayloadADM(
id: Option[ProjectIRI] = None,
shortname: Shortname,
shortcode: Shortcode,
longname: Option[Longname] = None,
description: ProjectDescription,
keywords: Keywords,
logo: Option[Logo] = None,
status: ProjectStatus,
selfjoin: ProjectSelfJoin
)

This file was deleted.

@@ -0,0 +1,23 @@
/*
* Copyright © 2021 Data and Service Center for the Humanities and/or DaSCH Service Platform contributors.
* SPDX-License-Identifier: Apache-2.0
*/

package org.knora.webapi.messages.admin.responder.usersmessages

object UsersErrorMessagesADM {
val USER_IRI_MISSING_ERROR = "User IRI cannot be empty."
val USER_IRI_INVALID_ERROR = "User IRI is invalid."
val USERNAME_MISSING_ERROR = "Username cannot be empty."
val USERNAME_INVALID_ERROR = "Username is invalid."
val EMAIL_MISSING_ERROR = "Email cannot be empty."
val EMAIL_INVALID_ERROR = "Email is invalid."
val PASSWORD_MISSING_ERROR = "Password cannot be empty."
val PASSWORD_INVALID_ERROR = "Password is invalid."
val GIVEN_NAME_MISSING_ERROR = "GivenName cannot be empty."
val GIVEN_NAME_INVALID_ERROR = "GivenName is invalid."
val FAMILY_NAME_MISSING_ERROR = "FamilyName cannot be empty."
val FAMILY_NAME_INVALID_ERROR = "FamilyName is invalid."
val LANGUAGE_CODE_MISSING_ERROR = "LanguageCode cannot be empty."
val LANGUAGE_CODE_INVALID_ERROR = "LanguageCode is invalid."
}
@@ -21,7 +21,7 @@ import org.knora.webapi.messages.admin.responder.valueObjects.{
GivenName,
FamilyName,
Password,
Status,
UserStatus,
LanguageCode,
SystemAdmin
}
@@ -244,7 +244,7 @@ case class UserChangePasswordRequestADM(
*/
case class UserChangeStatusRequestADM(
userIri: IRI,
status: Status,
status: UserStatus,
featureFactoryConfig: FeatureFactoryConfig,
requestingUser: UserADM,
apiRequestID: UUID
@@ -839,7 +839,7 @@ case class UserChangeRequestADM(
email: Option[Email] = None,
givenName: Option[GivenName] = None,
familyName: Option[FamilyName] = None,
status: Option[Status] = None,
status: Option[UserStatus] = None,
lang: Option[LanguageCode] = None,
projects: Option[Seq[IRI]] = None,
projectsAdmin: Option[Seq[IRI]] = None,
@@ -0,0 +1,23 @@
/*
* Copyright © 2021 Data and Service Center for the Humanities and/or DaSCH Service Platform contributors.
* SPDX-License-Identifier: Apache-2.0
*/

package org.knora.webapi.messages.admin.responder.usersmessages

import org.knora.webapi.messages.admin.responder.valueObjects._

/**
* User creation payload
*/
final case class UserCreatePayloadADM(
id: Option[UserIRI] = None,
username: Username,
email: Email,
givenName: GivenName,
familyName: FamilyName,
password: Password,
status: UserStatus,
lang: LanguageCode,
systemAdmin: SystemAdmin
)
@@ -16,13 +16,13 @@ import zio.prelude.Validation
*/
sealed abstract case class GroupIRI private (value: String)
object GroupIRI { self =>
private val sf = StringFormatter.getGeneralInstance
private val sf: StringFormatter = StringFormatter.getGeneralInstance

def make(value: String): Validation[Throwable, GroupIRI] =
if (value.isEmpty) {
Validation.fail(BadRequestException(GROUP_IRI_MISSING_ERROR))
} else {
if (value.nonEmpty && !sf.isKnoraGroupIriStr(value)) {
if (!sf.isKnoraGroupIriStr(value)) {
Validation.fail(BadRequestException(GROUP_IRI_INVALID_ERROR))
} else {
val validatedValue = Validation(
@@ -45,7 +45,7 @@ object GroupIRI { self =>
*/
sealed abstract case class GroupName private (value: String)
object GroupName { self =>
private val sf = StringFormatter.getGeneralInstance
private val sf: StringFormatter = StringFormatter.getGeneralInstance

def make(value: String): Validation[Throwable, GroupName] =
if (value.isEmpty) {
@@ -70,7 +70,7 @@ object GroupName { self =>
*/
sealed abstract case class GroupDescriptions private (value: Seq[StringLiteralV2])
object GroupDescriptions { self =>
private val sf = StringFormatter.getGeneralInstance
private val sf: StringFormatter = StringFormatter.getGeneralInstance

def make(value: Seq[StringLiteralV2]): Validation[Throwable, GroupDescriptions] =
if (value.isEmpty) {

0 comments on commit 563d252

Please sign in to comment.