From d6a0d2747eb7e39ad26b34648505ada15b7fc32b Mon Sep 17 00:00:00 2001 From: Ivan Subotic <400790+subotic@users.noreply.github.com> Date: Wed, 6 Oct 2021 16:49:59 +0200 Subject: [PATCH] fix(authenticator): improve performance (#1914) --- third_party/dependencies.bzl | 2 +- .../PermissionsMessagesADM.scala | 110 +++++------ .../usersmessages/UsersMessagesADM.scala | 183 +++++++----------- .../messages/util/PermissionUtilADM.scala | 6 +- .../webapi/messages/util/UserUtilADM.scala | 2 +- .../AuthenticationMessagesV2.scala | 48 +++-- .../responders/admin/GroupsResponderADM.scala | 2 +- .../admin/ProjectsResponderADM.scala | 4 +- .../responders/admin/UsersResponderADM.scala | 58 +++--- .../knora/webapi/routing/Authenticator.scala | 93 ++++----- .../webapi/routing/admin/UsersRouteADM.scala | 6 +- .../routing/v2/AuthenticationRouteV2.scala | 2 +- .../cacheservice/CacheServiceManager.scala | 10 +- .../inmem/CacheServiceInMemImpl.scala | 6 +- .../redis/CacheServiceRedisImpl.scala | 6 +- webapi/src/test/resources/logback-test.xml | 7 +- .../usersmessages/UsersMessagesADMSpec.scala | 12 +- .../usermessages/UserMessagesV1Spec.scala | 4 +- .../webapi/other/v1/DrawingsGodsV1Spec.scala | 6 +- .../admin/GroupsResponderADMSpec.scala | 4 +- .../admin/ProjectsResponderADMSpec.scala | 36 ++-- .../admin/UsersResponderADMSpec.scala | 44 ++--- .../webapi/routing/AuthenticatorSpec.scala | 13 +- 23 files changed, 302 insertions(+), 362 deletions(-) diff --git a/third_party/dependencies.bzl b/third_party/dependencies.bzl index f7514a1693..eeb82d3117 100644 --- a/third_party/dependencies.bzl +++ b/third_party/dependencies.bzl @@ -130,7 +130,7 @@ def dependencies(): "org.scalatest:scalatest-matchers-core_2.13:3.2.2", "org.scalatest:scalatest-shouldmatchers_2.13:3.2.2", "org.scalatest:scalatest-compatible:3.2.2", - "org.testcontainers:testcontainers:1.15.3", + "org.testcontainers:testcontainers:1.16.0", "junit:junit:4.13.2", "io.gatling.highcharts:gatling-charts-highcharts:3.2.1", "io.gatling:gatling-test-framework:3.2.1", diff --git a/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/permissionsmessages/PermissionsMessagesADM.scala b/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/permissionsmessages/PermissionsMessagesADM.scala index 7bac5d584e..dd2df78e95 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/permissionsmessages/PermissionsMessagesADM.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/permissionsmessages/PermissionsMessagesADM.scala @@ -19,22 +19,21 @@ package org.knora.webapi.messages.admin.responder.permissionsmessages -import java.util.UUID import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport import org.knora.webapi._ -import org.knora.webapi.exceptions.{BadRequestException, ForbiddenException, InconsistentRepositoryDataException} +import org.knora.webapi.exceptions.{BadRequestException, ForbiddenException} import org.knora.webapi.feature.FeatureFactoryConfig -import org.knora.webapi.messages.OntologyConstants.KnoraBase.EntityPermissionAbbreviations -import org.knora.webapi.messages.{OntologyConstants, StringFormatter} -import org.knora.webapi.messages.admin.responder.permissionsmessages.PermissionDataType.PermissionProfileType -import org.knora.webapi.messages.admin.responder.permissionsmessages.PermissionsMessagesUtilADM.PermissionTypeAndCodes +import org.knora.webapi.messages.admin.responder.permissionsmessages.PermissionProfileType.Restricted import org.knora.webapi.messages.admin.responder.projectsmessages.ProjectsADMJsonProtocol import org.knora.webapi.messages.admin.responder.usersmessages.UserADM import org.knora.webapi.messages.admin.responder.{KnoraRequestADM, KnoraResponseADM} import org.knora.webapi.messages.store.triplestoremessages.TriplestoreJsonProtocol import org.knora.webapi.messages.traits.Jsonable +import org.knora.webapi.messages.{OntologyConstants, StringFormatter} import spray.json._ +import java.util.UUID + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // API requests @@ -778,7 +777,7 @@ case class PermissionDeleteRequestADM(permissionIri: IRI, requestingUser: UserAD case class PermissionsForProjectGetResponseADM(allPermissions: Set[PermissionInfoADM]) extends KnoraResponseADM with PermissionsADMJsonProtocol { - def toJsValue = permissionsForProjectGetResponseADMFormat.write(this) + def toJsValue: JsValue = permissionsForProjectGetResponseADMFormat.write(this) } // All administrative Permissions for project @@ -791,7 +790,7 @@ case class AdministrativePermissionsForProjectGetResponseADM( administrativePermissions: Seq[AdministrativePermissionADM] ) extends KnoraResponseADM with PermissionsADMJsonProtocol { - def toJsValue = administrativePermissionsForProjectGetResponseADMFormat.write(this) + def toJsValue: JsValue = administrativePermissionsForProjectGetResponseADMFormat.write(this) } // All Default Object Access Permissions for project @@ -804,7 +803,7 @@ case class DefaultObjectAccessPermissionsForProjectGetResponseADM( defaultObjectAccessPermissions: Seq[DefaultObjectAccessPermissionADM] ) extends KnoraResponseADM with PermissionsADMJsonProtocol { - def toJsValue = defaultObjectAccessPermissionsForProjectGetResponseADMFormat.write(this) + def toJsValue: JsValue = defaultObjectAccessPermissionsForProjectGetResponseADMFormat.write(this) } abstract class PermissionGetResponseADM(permissionItem: PermissionItemADM) @@ -818,7 +817,7 @@ abstract class PermissionGetResponseADM(permissionItem: PermissionItemADM) */ case class DefaultObjectAccessPermissionGetResponseADM(defaultObjectAccessPermission: DefaultObjectAccessPermissionADM) extends PermissionGetResponseADM(defaultObjectAccessPermission) { - def toJsValue = defaultObjectAccessPermissionGetResponseADMFormat.write(this) + def toJsValue: JsValue = defaultObjectAccessPermissionGetResponseADMFormat.write(this) } /** @@ -828,7 +827,7 @@ case class DefaultObjectAccessPermissionGetResponseADM(defaultObjectAccessPermis */ case class AdministrativePermissionGetResponseADM(administrativePermission: AdministrativePermissionADM) extends PermissionGetResponseADM(administrativePermission) { - def toJsValue = administrativePermissionGetResponseADMFormat.write(this) + def toJsValue: JsValue = administrativePermissionGetResponseADMFormat.write(this) } /** @@ -851,7 +850,7 @@ case class DefaultObjectAccessPermissionCreateResponseADM( defaultObjectAccessPermission: DefaultObjectAccessPermissionADM ) extends KnoraResponseADM with PermissionsADMJsonProtocol { - def toJsValue = defaultObjectAccessPermissionCreateResponseADMFormat.write(this) + def toJsValue: JsValue = defaultObjectAccessPermissionCreateResponseADMFormat.write(this) } /** @@ -871,7 +870,7 @@ case class PermissionDeleteResponseADM(permissionIri: IRI, deleted: Boolean) extends KnoraResponseADM with PermissionsADMJsonProtocol { - def toJsValue = permissionDeleteResponseADMFormat.write(this) + def toJsValue: JsValue = permissionDeleteResponseADMFormat.write(this) } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -897,14 +896,14 @@ case class PermissionsDataADM( def ofType(permissionProfileType: PermissionProfileType): PermissionsDataADM = permissionProfileType match { - case PermissionDataType.RESTRICTED => + case PermissionProfileType.Restricted => PermissionsDataADM( groupsPerProject = groupsPerProject, administrativePermissionsPerProject = Map.empty[IRI, Set[PermissionADM]] // remove administrative permission information ) - case PermissionDataType.FULL => + case PermissionProfileType.Full => PermissionsDataADM( groupsPerProject = groupsPerProject, administrativePermissionsPerProject = administrativePermissionsPerProject @@ -953,19 +952,17 @@ case class PermissionsDataADM( true } else { operation match { - case ResourceCreateOperation(resourceClassIri) => { + case ResourceCreateOperation(resourceClassIri) => this.administrativePermissionsPerProject.get(insideProject) match { - case Some(set) => { + case Some(set) => set(PermissionADM.ProjectResourceCreateAllPermission) || set( PermissionADM.projectResourceCreateRestrictedPermission(resourceClassIri) ) - } case None => { // println("FALSE: No administrative permissions defined for this project.") false } } - } } } @@ -1018,7 +1015,7 @@ case class PermissionsDataADM( */ case class PermissionInfoADM(iri: IRI, permissionType: IRI) extends Jsonable with PermissionsADMJsonProtocol { - def toJsValue = permissionInfoADMFormat.write(this) + def toJsValue: JsValue = permissionInfoADMFormat.write(this) } abstract class PermissionItemADM extends Jsonable with PermissionsADMJsonProtocol @@ -1037,7 +1034,7 @@ case class ObjectAccessPermissionADM( hasPermissions: Set[PermissionADM] ) extends PermissionItemADM { - def toJsValue = objectAccessPermissionADMFormat.write(this) + def toJsValue: JsValue = objectAccessPermissionADMFormat.write(this) } /** @@ -1051,7 +1048,7 @@ case class ObjectAccessPermissionADM( case class AdministrativePermissionADM(iri: IRI, forProject: IRI, forGroup: IRI, hasPermissions: Set[PermissionADM]) extends PermissionItemADM { - def toJsValue = administrativePermissionADMFormat.write(this) + def toJsValue: JsValue = administrativePermissionADMFormat.write(this) } /** @@ -1084,7 +1081,7 @@ case class DefaultObjectAccessPermissionADM( forProperty ) - def toJsValue = defaultObjectAccessPermissionADMFormat.write(this) + def toJsValue: JsValue = defaultObjectAccessPermissionADMFormat.write(this) } /** @@ -1097,7 +1094,7 @@ case class PermissionADM(name: String, additionalInformation: Option[IRI] = None extends Jsonable with PermissionsADMJsonProtocol { - def toJsValue = permissionADMFormat.write(this) + def toJsValue: JsValue = permissionADMFormat.write(this) override def toString: String = name } @@ -1213,41 +1210,26 @@ case class ResourceCreateOperation(resourceClass: IRI) extends OperationADM * * Used in the 'ofType' method. */ -object PermissionDataType extends Enumeration { - /* TODO: Extend to incorporate user privacy wishes */ - - type PermissionProfileType = Value - - val RESTRICTED: PermissionProfileType = Value(0, "restricted") - // only group memberships - val FULL: PermissionProfileType = Value(1, "full") // everything - - val valueMap: Map[String, Value] = values.map(v => (v.toString, v)).toMap - - /** - * Given the name of a value in this enumeration, returns the value. If the value is not found, throws an - * [[InconsistentRepositoryDataException]]. - * - * @param name the name of the value. - * @return the requested value. - */ - def lookup(name: String): Value = - valueMap.get(name) match { - case Some(value) => value - case None => throw InconsistentRepositoryDataException(s"Permission profile type not supported: $name") - } +sealed trait PermissionProfileType +object PermissionProfileType { + case object Restricted extends PermissionProfileType + case object Full extends PermissionProfileType } /** * The permission type. */ -object PermissionType extends Enumeration { - - type PermissionType = Value - - val OAP: PermissionType = Value(0, "ObjectAccessPermission") - val AP: PermissionType = Value(1, "AdministrativePermission") - val DOAP: PermissionType = Value(2, "DefaultObjectAccessPermission") +sealed trait PermissionType +object PermissionType { + case object OAP extends PermissionType { + override def toString: String = "ObjectAccessPermission" + } + case object AP extends PermissionType { + override def toString: String = "AdministrativePermission" + } + case object DOAP extends PermissionType { + override def toString: String = "DefaultObjectAccessPermission" + } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1260,20 +1242,30 @@ trait PermissionsADMJsonProtocol with TriplestoreJsonProtocol { implicit object PermissionProfileTypeFormat extends JsonFormat[PermissionProfileType] { + import PermissionProfileType._ /** * Not implemented. */ - def read(jsonVal: JsValue) = ??? + def read(jsonVal: JsValue): PermissionProfileType = ??? /** - * Converts a [[PermissionDataType]] into [[JsValue]] for formatting as JSON. + * Converts a [[PermissionProfileType]] into [[JsValue]] for formatting as JSON. * - * @param permissionProfileType the [[PermissionDataType]] to be converted. + * @param permissionProfileType the [[PermissionProfileType]] to be converted. * @return a [[JsValue]]. */ - def write(permissionProfileType: PermissionDataType.Value): JsValue = - JsObject(Map("permission_profile_type" -> permissionProfileType.toString.toJson)) + def write(permissionProfileType: PermissionProfileType): JsValue = + permissionProfileType match { + case Full => + JsObject { + Map("permission_profile_type" -> "full".toJson) + } + case Restricted => + JsObject { + Map("permission_profile_type" -> "restricted".toJson) + } + } } implicit val permissionADMFormat: JsonFormat[PermissionADM] = diff --git a/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/usersmessages/UsersMessagesADM.scala b/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/usersmessages/UsersMessagesADM.scala index dad322c6e5..b0c530ff24 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/usersmessages/UsersMessagesADM.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/usersmessages/UsersMessagesADM.scala @@ -21,12 +21,11 @@ package org.knora.webapi.messages.admin.responder.usersmessages import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport import org.knora.webapi._ -import org.knora.webapi.exceptions.{BadRequestException, DataConversionException, InconsistentRepositoryDataException} +import org.knora.webapi.exceptions.{BadRequestException, DataConversionException} import org.knora.webapi.feature.FeatureFactoryConfig import org.knora.webapi.messages.admin.responder.groupsmessages.{GroupADM, GroupsADMJsonProtocol} import org.knora.webapi.messages.admin.responder.permissionsmessages.{PermissionsADMJsonProtocol, PermissionsDataADM} import org.knora.webapi.messages.admin.responder.projectsmessages.{ProjectADM, ProjectsADMJsonProtocol} -import org.knora.webapi.messages.admin.responder.usersmessages.UserInformationTypeADM.UserInformationTypeADM import org.knora.webapi.messages.admin.responder.{KnoraRequestADM, KnoraResponseADM} import org.knora.webapi.messages.v1.responder.projectmessages.ProjectInfoV1 import org.knora.webapi.messages.v1.responder.usermessages._ @@ -140,7 +139,7 @@ sealed trait UsersResponderRequestADM extends KnoraRequestADM * @param requestingUser the user that is making the request. */ case class UsersGetADM( - userInformationTypeADM: UserInformationTypeADM = UserInformationTypeADM.SHORT, + userInformationTypeADM: UserInformationTypeADM = UserInformationTypeADM.Short, featureFactoryConfig: FeatureFactoryConfig, requestingUser: UserADM ) extends UsersResponderRequestADM @@ -154,7 +153,7 @@ case class UsersGetADM( * @param requestingUser the user initiating the request. */ case class UsersGetRequestADM( - userInformationTypeADM: UserInformationTypeADM = UserInformationTypeADM.SHORT, + userInformationTypeADM: UserInformationTypeADM = UserInformationTypeADM.Short, featureFactoryConfig: FeatureFactoryConfig, requestingUser: UserADM ) extends UsersResponderRequestADM @@ -169,7 +168,7 @@ case class UsersGetRequestADM( */ case class UserGetADM( identifier: UserIdentifierADM, - userInformationTypeADM: UserInformationTypeADM = UserInformationTypeADM.SHORT, + userInformationTypeADM: UserInformationTypeADM = UserInformationTypeADM.Short, featureFactoryConfig: FeatureFactoryConfig, requestingUser: UserADM ) extends UsersResponderRequestADM {} @@ -184,7 +183,7 @@ case class UserGetADM( */ case class UserGetRequestADM( identifier: UserIdentifierADM, - userInformationTypeADM: UserInformationTypeADM = UserInformationTypeADM.SHORT, + userInformationTypeADM: UserInformationTypeADM = UserInformationTypeADM.Short, featureFactoryConfig: FeatureFactoryConfig, requestingUser: UserADM ) extends UsersResponderRequestADM {} @@ -505,7 +504,7 @@ case class UserADM( projects: Seq[ProjectADM] = Seq.empty[ProjectADM], sessionId: Option[String] = None, permissions: PermissionsDataADM = PermissionsDataADM() -) extends Ordered[UserADM] { +) extends Ordered[UserADM] { self => /** * Allows to sort collections of UserADM. Sorting is done by the id. @@ -546,15 +545,12 @@ case class UserADM( */ def ofType(userTemplateType: UserInformationTypeADM): UserADM = userTemplateType match { - case UserInformationTypeADM.PUBLIC => - UserADM( - id = id, + case UserInformationTypeADM.Public => + self.copy( username = "", email = "", password = None, token = None, - givenName = givenName, - familyName = familyName, status = false, lang = "", groups = Seq.empty[GroupADM], @@ -562,54 +558,23 @@ case class UserADM( sessionId = None, permissions = PermissionsDataADM() ) - case UserInformationTypeADM.SHORT => - UserADM( - id = id, - username = username, - email = email, + case UserInformationTypeADM.Short => + self.copy( password = None, token = None, - givenName = givenName, - familyName = familyName, - status = status, - lang = lang, groups = Seq.empty[GroupADM], projects = Seq.empty[ProjectADM], sessionId = None, permissions = PermissionsDataADM() ) - case UserInformationTypeADM.RESTRICTED => - UserADM( - id = id, - username = username, - email = email, + case UserInformationTypeADM.Restricted => + self.copy( password = None, token = None, - givenName = givenName, - familyName = familyName, - status = status, - lang = lang, - groups = groups, - projects = projects, - sessionId = None, - permissions = permissions - ) - case UserInformationTypeADM.FULL => - UserADM( - id = id, - username = username, - email = email, - password = password, - token = token, - givenName = givenName, - familyName = familyName, - status = status, - lang = lang, - groups = groups, - projects = projects, - sessionId = sessionId, - permissions = permissions + sessionId = None ) + case UserInformationTypeADM.Full => + self case _ => throw BadRequestException(s"The requested userTemplateType: $userTemplateType is invalid.") } @@ -725,75 +690,24 @@ case class UserADM( * sensitive information to the outside world. Since in API Admin [[UserADM]] is returned with some responses, * we use 'restricted' in those cases. */ -object UserInformationTypeADM extends Enumeration { - /* TODO: Extend to incorporate user privacy wishes */ - - type UserInformationTypeADM = Value - - val PUBLIC: Value = Value(0, "public") // a temporary type which only returns firstname and lastname - val SHORT: Value = Value(1, "short") // only basic user information (restricted and additionally without groups - val RESTRICTED: Value = Value(2, "restricted") // without sensitive information - val FULL: Value = Value(3, "full") // everything, including sensitive information - - val valueMap: Map[String, Value] = values.map(v => (v.toString, v)).toMap +sealed trait UserInformationTypeADM +object UserInformationTypeADM { + case object Public extends UserInformationTypeADM + case object Short extends UserInformationTypeADM + case object Restricted extends UserInformationTypeADM + case object Full extends UserInformationTypeADM - /** - * Given the name of a value in this enumeration, returns the value. If the value is not found, throws an - * [[InconsistentRepositoryDataException]]. - * - * @param name the name of the value. - * @return the requested value. - */ - def lookup(name: String): Value = - valueMap.get(name) match { - case Some(value) => value - case None => throw InconsistentRepositoryDataException(s"User profile type not supported: $name") - } + // throw InconsistentRepositoryDataException(s"User profile type not supported: $name") } /** * Represents the type of a user identifier. */ -object UserIdentifierType extends Enumeration { - - type UserIdentifierType - - val IRI: Value = Value(0, "iri") - val EMAIL: Value = Value(1, "email") - val USERNAME: Value = Value(3, "username") -} - -/** - * The UserIdentifierADM factory object, making sure that all necessary checks are performed and all inputs - * validated and escaped. - */ -object UserIdentifierADM { - def apply(maybeIri: Option[String] = None, maybeEmail: Option[String] = None, maybeUsername: Option[String] = None)( - implicit sf: StringFormatter - ): UserIdentifierADM = { - - val parametersCount: Int = List( - maybeIri, - maybeEmail, - maybeUsername - ).flatten.size - - // something needs to be set - if (parametersCount == 0) throw BadRequestException("Empty user identifier is not allowed.") - - if (parametersCount > 1) throw BadRequestException("Only one option allowed for user identifier.") - - new UserIdentifierADM( - maybeIri = - sf.validateAndEscapeOptionalUserIri(maybeIri, throw BadRequestException(s"Invalid user IRI $maybeIri")), - maybeEmail = - sf.validateAndEscapeOptionalEmail(maybeEmail, throw BadRequestException(s"Invalid email $maybeEmail")), - maybeUsername = sf.validateAndEscapeOptionalUsername( - maybeUsername, - throw BadRequestException(s"Invalid username $maybeUsername") - ) - ) - } +sealed trait UserIdentifierType +object UserIdentifierType { + case object Iri extends UserIdentifierType + case object Email extends UserIdentifierType + case object Username extends UserIdentifierType } /** @@ -803,7 +717,7 @@ object UserIdentifierADM { * @param maybeEmail the user's email. * @param maybeUsername the user's username. */ -class UserIdentifierADM private ( +sealed abstract case class UserIdentifierADM private ( maybeIri: Option[IRI] = None, maybeEmail: Option[String] = None, maybeUsername: Option[String] = None @@ -818,13 +732,13 @@ class UserIdentifierADM private ( // validate and escape - def hasType: UserIdentifierType.Value = + def hasType: UserIdentifierType = if (maybeIri.isDefined) { - UserIdentifierType.IRI + UserIdentifierType.Iri } else if (maybeEmail.isDefined) { - UserIdentifierType.EMAIL + UserIdentifierType.Email } else { - UserIdentifierType.USERNAME + UserIdentifierType.Username } /** @@ -877,6 +791,39 @@ class UserIdentifierADM private ( } +/** + * The UserIdentifierADM factory object, making sure that all necessary checks are performed and all inputs + * validated and escaped. + */ +object UserIdentifierADM { + def apply(maybeIri: Option[String] = None, maybeEmail: Option[String] = None, maybeUsername: Option[String] = None)( + implicit sf: StringFormatter + ): UserIdentifierADM = { + + val parametersCount: Int = List( + maybeIri, + maybeEmail, + maybeUsername + ).flatten.size + + // something needs to be set + if (parametersCount == 0) throw BadRequestException("Empty user identifier is not allowed.") + + if (parametersCount > 1) throw BadRequestException("Only one option allowed for user identifier.") + + new UserIdentifierADM( + maybeIri = + sf.validateAndEscapeOptionalUserIri(maybeIri, throw BadRequestException(s"Invalid user IRI $maybeIri")), + maybeEmail = + sf.validateAndEscapeOptionalEmail(maybeEmail, throw BadRequestException(s"Invalid email $maybeEmail")), + maybeUsername = sf.validateAndEscapeOptionalUsername( + maybeUsername, + throw BadRequestException(s"Invalid username $maybeUsername") + ) + ) {} + } +} + /** * Payload used for updating an existing user. * diff --git a/webapi/src/main/scala/org/knora/webapi/messages/util/PermissionUtilADM.scala b/webapi/src/main/scala/org/knora/webapi/messages/util/PermissionUtilADM.scala index f34ca791fd..6f4ea46cd2 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/util/PermissionUtilADM.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/util/PermissionUtilADM.scala @@ -27,7 +27,6 @@ import org.knora.webapi.IRI import org.knora.webapi.exceptions.{BadRequestException, InconsistentRepositoryDataException} import org.knora.webapi.feature.FeatureFactoryConfig import org.knora.webapi.messages.admin.responder.groupsmessages.{GroupGetResponseADM, MultipleGroupsGetRequestADM} -import org.knora.webapi.messages.admin.responder.permissionsmessages.PermissionType.PermissionType import org.knora.webapi.messages.admin.responder.permissionsmessages.{PermissionADM, PermissionType} import org.knora.webapi.messages.admin.responder.usersmessages.UserADM import org.knora.webapi.messages.store.triplestoremessages.SparqlExtendedConstructResponse.ConstructPredicateObjects @@ -539,6 +538,7 @@ object PermissionUtilADM extends LazyLogging { ) .toSet buildPermissionObject(abbreviation, groups) + case PermissionType.DOAP => ??? } } }.toSet @@ -653,7 +653,8 @@ object PermissionUtilADM extends LazyLogging { Set.empty[PermissionADM] } - case PermissionType.AP => ??? + case PermissionType.AP => ??? + case PermissionType.DOAP => ??? } /** @@ -722,6 +723,7 @@ object PermissionUtilADM extends LazyLogging { } else { throw InconsistentRepositoryDataException("Permissions cannot be empty") } + case PermissionType.DOAP => ??? } /** diff --git a/webapi/src/main/scala/org/knora/webapi/messages/util/UserUtilADM.scala b/webapi/src/main/scala/org/knora/webapi/messages/util/UserUtilADM.scala index 9df27f055d..a88da1f773 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/util/UserUtilADM.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/util/UserUtilADM.scala @@ -69,7 +69,7 @@ object UserUtilADM { for { userResponse: UserResponseADM <- (responderManager ? UserGetRequestADM( identifier = UserIdentifierADM(maybeIri = Some(requestedUserIri)), - userInformationTypeADM = UserInformationTypeADM.FULL, + userInformationTypeADM = UserInformationTypeADM.Full, featureFactoryConfig = featureFactoryConfig, requestingUser = KnoraSystemInstances.Users.SystemUser )).mapTo[UserResponseADM] diff --git a/webapi/src/main/scala/org/knora/webapi/messages/v2/routing/authenticationmessages/AuthenticationMessagesV2.scala b/webapi/src/main/scala/org/knora/webapi/messages/v2/routing/authenticationmessages/AuthenticationMessagesV2.scala index 1b8384e6b1..5a9baf54dc 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/v2/routing/authenticationmessages/AuthenticationMessagesV2.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/v2/routing/authenticationmessages/AuthenticationMessagesV2.scala @@ -60,31 +60,37 @@ case class LoginApiRequestPayloadV2( } /** - * An abstract knora credentials class. + * Sum type representing the different credential types */ -sealed abstract class KnoraCredentialsV2() +sealed trait KnoraCredentialsV2 -/** - * Represents id/password credentials that a user can supply within the authorization header or as URL parameters. - * - * @param identifier the supplied id. - * @param password the supplied password. - */ -case class KnoraPasswordCredentialsV2(identifier: UserIdentifierADM, password: String) extends KnoraCredentialsV2 +object KnoraCredentialsV2 { -/** - * Represents token credentials that a user can supply withing the authorization header or as URL parameters. - * - * @param token the supplied json web token. - */ -case class KnoraTokenCredentialsV2(token: String) extends KnoraCredentialsV2 + /** + * Represents id/password credentials that a user can supply within the authorization header or as URL parameters. + * + * @param identifier the supplied id. + * @param password the supplied password. + */ + final case class KnoraPasswordCredentialsV2(identifier: UserIdentifierADM, password: String) + extends KnoraCredentialsV2 -/** - * Represents session credentials that a user can supply within the cookie header. - * - * @param token the supplied session token. - */ -case class KnoraSessionCredentialsV2(token: String) extends KnoraCredentialsV2 + /** + * Represents JWT token credentials that a user can supply withing the authorization header or as URL parameters. + * + * @param jwtToken the supplied json web token. + */ + case class KnoraJWTTokenCredentialsV2(jwtToken: String) extends KnoraCredentialsV2 + + /** + * Represents session credentials that a user can supply within the cookie header. + * The session token is contents wise the same as the jwt token. The session ID + * equals the JWT token. + * + * @param sessionToken the supplied session token. + */ + case class KnoraSessionCredentialsV2(sessionToken: String) extends KnoraCredentialsV2 +} /** * Represents a response Knora returns when communicating with the 'v2/authentication' route during the 'login' operation. diff --git a/webapi/src/main/scala/org/knora/webapi/responders/admin/GroupsResponderADM.scala b/webapi/src/main/scala/org/knora/webapi/responders/admin/GroupsResponderADM.scala index 62ce6a65dd..cb417383af 100644 --- a/webapi/src/main/scala/org/knora/webapi/responders/admin/GroupsResponderADM.scala +++ b/webapi/src/main/scala/org/knora/webapi/responders/admin/GroupsResponderADM.scala @@ -361,7 +361,7 @@ class GroupsResponderADM(responderData: ResponderData) extends Responder(respond maybeUsersFutures: Seq[Future[Option[UserADM]]] = groupMemberIris.map { userIri => (responderManager ? UserGetADM( UserIdentifierADM(maybeIri = Some(userIri)), - userInformationTypeADM = UserInformationTypeADM.RESTRICTED, + userInformationTypeADM = UserInformationTypeADM.Restricted, featureFactoryConfig = featureFactoryConfig, requestingUser = KnoraSystemInstances.Users.SystemUser )).mapTo[Option[UserADM]] diff --git a/webapi/src/main/scala/org/knora/webapi/responders/admin/ProjectsResponderADM.scala b/webapi/src/main/scala/org/knora/webapi/responders/admin/ProjectsResponderADM.scala index ae475cb46d..297616aa4b 100644 --- a/webapi/src/main/scala/org/knora/webapi/responders/admin/ProjectsResponderADM.scala +++ b/webapi/src/main/scala/org/knora/webapi/responders/admin/ProjectsResponderADM.scala @@ -363,7 +363,7 @@ class ProjectsResponderADM(responderData: ResponderData) extends Responder(respo maybeUserFutures: Seq[Future[Option[UserADM]]] = userIris.map { userIri => (responderManager ? UserGetADM( identifier = UserIdentifierADM(maybeIri = Some(userIri)), - userInformationTypeADM = UserInformationTypeADM.RESTRICTED, + userInformationTypeADM = UserInformationTypeADM.Restricted, featureFactoryConfig = featureFactoryConfig, requestingUser = KnoraSystemInstances.Users.SystemUser )).mapTo[Option[UserADM]] @@ -438,7 +438,7 @@ class ProjectsResponderADM(responderData: ResponderData) extends Responder(respo maybeUserFutures: Seq[Future[Option[UserADM]]] = userIris.map { userIri => (responderManager ? UserGetADM( identifier = UserIdentifierADM(maybeIri = Some(userIri)), - userInformationTypeADM = UserInformationTypeADM.RESTRICTED, + userInformationTypeADM = UserInformationTypeADM.Restricted, featureFactoryConfig = featureFactoryConfig, requestingUser = KnoraSystemInstances.Users.SystemUser )).mapTo[Option[UserADM]] diff --git a/webapi/src/main/scala/org/knora/webapi/responders/admin/UsersResponderADM.scala b/webapi/src/main/scala/org/knora/webapi/responders/admin/UsersResponderADM.scala index 05ecde9770..c148660d3f 100644 --- a/webapi/src/main/scala/org/knora/webapi/responders/admin/UsersResponderADM.scala +++ b/webapi/src/main/scala/org/knora/webapi/responders/admin/UsersResponderADM.scala @@ -29,7 +29,6 @@ import org.knora.webapi.messages.IriConversions._ import org.knora.webapi.messages.admin.responder.groupsmessages.{GroupADM, GroupGetADM} import org.knora.webapi.messages.admin.responder.permissionsmessages.{PermissionDataGetADM, PermissionsDataADM} import org.knora.webapi.messages.admin.responder.projectsmessages.{ProjectADM, ProjectGetADM, ProjectIdentifierADM} -import org.knora.webapi.messages.admin.responder.usersmessages.UserInformationTypeADM.UserInformationTypeADM import org.knora.webapi.messages.admin.responder.usersmessages.{Password, UserChangeRequestADM, _} import org.knora.webapi.messages.store.cacheservicemessages.{ CacheServiceGetUserADM, @@ -59,7 +58,7 @@ class UsersResponderADM(responderData: ResponderData) extends Responder(responde /** * Receives a message extending [[UsersResponderRequestADM]], and returns an appropriate message. */ - def receive(msg: UsersResponderRequestADM) = msg match { + def receive(msg: UsersResponderRequestADM): Future[Equals] = msg match { case UsersGetADM(userInformationTypeADM, featureFactoryConfig, requestingUser) => getAllUserADM(userInformationTypeADM, featureFactoryConfig, requestingUser) case UsersGetRequestADM(userInformationTypeADM, featureFactoryConfig, requestingUser) => @@ -310,7 +309,7 @@ class UsersResponderADM(responderData: ResponderData) extends Responder(responde featureFactoryConfig: FeatureFactoryConfig, requestingUser: UserADM, skipCache: Boolean = false - ): Future[Option[UserADM]] = tracedFuture("admin-get-user") { + ): Future[Option[UserADM]] = tracedFuture("admin-user-get-single-user") { log.debug( s"getSingleUserADM - id: {}, type: {}, requester: {}, skipCache: {}", @@ -340,7 +339,7 @@ class UsersResponderADM(responderData: ResponderData) extends Responder(responde maybeUserADM.map(user => user.ofType(userInformationType)) } else { // return only public information - maybeUserADM.map(user => user.ofType(UserInformationTypeADM.PUBLIC)) + maybeUserADM.map(user => user.ofType(UserInformationTypeADM.Public)) } _ = @@ -426,7 +425,7 @@ class UsersResponderADM(responderData: ResponderData) extends Responder(responde // get current user information currentUserInformation: Option[UserADM] <- getSingleUserADM( identifier = UserIdentifierADM(maybeIri = Some(userIri)), - userInformationType = UserInformationTypeADM.FULL, + userInformationType = UserInformationTypeADM.Full, featureFactoryConfig = featureFactoryConfig, requestingUser = KnoraSystemInstances.Users.SystemUser ) @@ -685,7 +684,7 @@ class UsersResponderADM(responderData: ResponderData) extends Responder(responde for { maybeUser <- getSingleUserADM( identifier = UserIdentifierADM(maybeIri = Some(userIri)), - userInformationType = UserInformationTypeADM.FULL, + userInformationType = UserInformationTypeADM.Full, featureFactoryConfig = featureFactoryConfig, requestingUser = KnoraSystemInstances.Users.SystemUser ) @@ -1169,7 +1168,7 @@ class UsersResponderADM(responderData: ResponderData) extends Responder(responde for { maybeUserADM: Option[UserADM] <- getSingleUserADM( identifier = UserIdentifierADM(maybeIri = Some(userIri)), - userInformationType = UserInformationTypeADM.FULL, + userInformationType = UserInformationTypeADM.Full, featureFactoryConfig = featureFactoryConfig, requestingUser = KnoraSystemInstances.Users.SystemUser ) @@ -1240,7 +1239,7 @@ class UsersResponderADM(responderData: ResponderData) extends Responder(responde // check if user exists maybeUser <- getSingleUserADM( UserIdentifierADM(maybeIri = Some(userIri)), - UserInformationTypeADM.FULL, + UserInformationTypeADM.Full, featureFactoryConfig = featureFactoryConfig, KnoraSystemInstances.Users.SystemUser, skipCache = true @@ -1428,7 +1427,7 @@ class UsersResponderADM(responderData: ResponderData) extends Responder(responde identifier = UserIdentifierADM(maybeIri = Some(userIri)), featureFactoryConfig = featureFactoryConfig, requestingUser = requestingUser, - userInformationType = UserInformationTypeADM.FULL, + userInformationType = UserInformationTypeADM.Full, skipCache = true ) @@ -1523,7 +1522,7 @@ class UsersResponderADM(responderData: ResponderData) extends Responder(responde identifier = UserIdentifierADM(maybeIri = Some(userIri)), featureFactoryConfig = featureFactoryConfig, requestingUser = requestingUser, - userInformationType = UserInformationTypeADM.FULL, + userInformationType = UserInformationTypeADM.Full, skipCache = true ) @@ -1591,7 +1590,7 @@ class UsersResponderADM(responderData: ResponderData) extends Responder(responde ) } - } yield UserOperationResponseADM(updatedUserADM.ofType(UserInformationTypeADM.RESTRICTED)) + } yield UserOperationResponseADM(updatedUserADM.ofType(UserInformationTypeADM.Restricted)) } /** @@ -1628,7 +1627,7 @@ class UsersResponderADM(responderData: ResponderData) extends Responder(responde identifier = UserIdentifierADM(maybeIri = Some(userIri)), featureFactoryConfig = featureFactoryConfig, requestingUser = requestingUser, - userInformationType = UserInformationTypeADM.FULL, + userInformationType = UserInformationTypeADM.Full, skipCache = true ) @@ -1657,7 +1656,7 @@ class UsersResponderADM(responderData: ResponderData) extends Responder(responde identifier = UserIdentifierADM(maybeIri = Some(userIri)), featureFactoryConfig = featureFactoryConfig, requestingUser = requestingUser, - userInformationType = UserInformationTypeADM.FULL, + userInformationType = UserInformationTypeADM.Full, skipCache = true ) @@ -1669,7 +1668,7 @@ class UsersResponderADM(responderData: ResponderData) extends Responder(responde _ = if (updatedUserADM.password.get != password.value) throw UpdateNotPerformedException("User's password was not updated. Please report this as a possible bug.") - } yield UserOperationResponseADM(updatedUserADM.ofType(UserInformationTypeADM.RESTRICTED)) + } yield UserOperationResponseADM(updatedUserADM.ofType(UserInformationTypeADM.Restricted)) } /** @@ -1776,7 +1775,7 @@ class UsersResponderADM(responderData: ResponderData) extends Responder(responde identifier = UserIdentifierADM(maybeIri = Some(userIri)), featureFactoryConfig = featureFactoryConfig, requestingUser = KnoraSystemInstances.Users.SystemUser, - userInformationType = UserInformationTypeADM.FULL, + userInformationType = UserInformationTypeADM.Full, skipCache = true ) @@ -1788,7 +1787,7 @@ class UsersResponderADM(responderData: ResponderData) extends Responder(responde // create the user operation response _ = log.debug("createNewUserADM - created new user: {}", newUserADM) - userOperationResponseADM = UserOperationResponseADM(newUserADM.ofType(UserInformationTypeADM.RESTRICTED)) + userOperationResponseADM = UserOperationResponseADM(newUserADM.ofType(UserInformationTypeADM.Restricted)) } yield userOperationResponseADM for { @@ -1812,7 +1811,7 @@ class UsersResponderADM(responderData: ResponderData) extends Responder(responde private def getUserFromCacheOrTriplestore( identifier: UserIdentifierADM, featureFactoryConfig: FeatureFactoryConfig - ): Future[Option[UserADM]] = + ): Future[Option[UserADM]] = tracedFuture("admin-user-get-user-from-cache-or-triplestore") { if (cacheServiceSettings.cacheServiceEnabled) { // caching enabled getUserFromCache(identifier).flatMap { @@ -1829,7 +1828,8 @@ class UsersResponderADM(responderData: ResponderData) extends Responder(responde "getUserFromCacheOrTriplestore - not found in cache but found in triplestore. need to write to cache." ) // writing user to cache and afterwards returning the user found in the triplestore - writeUserADMToCache(user).map(res => Some(user)) + writeUserADMToCache(user) + FastFuture.successful(Some(user)) } case Some(user) => log.debug("getUserFromCacheOrTriplestore - found in cache. returning user.") @@ -1840,6 +1840,7 @@ class UsersResponderADM(responderData: ResponderData) extends Responder(responde log.debug("getUserFromCacheOrTriplestore - caching disabled. getting from triplestore.") getUserFromTriplestore(identifier = identifier, featureFactoryConfig = featureFactoryConfig) } + } /** * Tries to retrieve a [[UserADM]] from the triplestore. @@ -2158,17 +2159,18 @@ class UsersResponderADM(responderData: ResponderData) extends Responder(responde /** * Tries to retrieve a [[UserADM]] from the cache. */ - private def getUserFromCache(identifier: UserIdentifierADM): Future[Option[UserADM]] = { - val result = (storeManager ? CacheServiceGetUserADM(identifier)).mapTo[Option[UserADM]] - result.map { - case Some(user) => - log.debug("getUserFromCache - cache hit for: {}", identifier) - Some(user) - case None => - log.debug("getUserFromCache - no cache hit for: {}", identifier) - None + private def getUserFromCache(identifier: UserIdentifierADM): Future[Option[UserADM]] = + tracedFuture("admin-user-get-user-from-cache") { + val result = (storeManager ? CacheServiceGetUserADM(identifier)).mapTo[Option[UserADM]] + result.map { + case Some(user) => + log.debug("getUserFromCache - cache hit for: {}", identifier) + Some(user) + case None => + log.debug("getUserFromCache - no cache hit for: {}", identifier) + None + } } - } /** * Writes the user profile to cache. diff --git a/webapi/src/main/scala/org/knora/webapi/routing/Authenticator.scala b/webapi/src/main/scala/org/knora/webapi/routing/Authenticator.scala index 306ffe820a..575c8b0a85 100644 --- a/webapi/src/main/scala/org/knora/webapi/routing/Authenticator.scala +++ b/webapi/src/main/scala/org/knora/webapi/routing/Authenticator.scala @@ -20,7 +20,6 @@ package org.knora.webapi.routing import java.util.{Base64, UUID} - import akka.actor.{ActorRef, ActorSystem} import akka.http.scaladsl.model.headers.{HttpCookie, HttpCookiePair} import akka.http.scaladsl.model.{headers, _} @@ -32,10 +31,16 @@ import com.typesafe.scalalogging.Logger import org.knora.webapi.IRI import org.knora.webapi.exceptions.{AuthenticationException, BadCredentialsException, BadRequestException} import org.knora.webapi.feature.FeatureFactoryConfig +import org.knora.webapi.instrumentation.InstrumentationSupport import org.knora.webapi.messages.StringFormatter import org.knora.webapi.messages.admin.responder.usersmessages._ import org.knora.webapi.messages.util.KnoraSystemInstances import org.knora.webapi.messages.v1.responder.usermessages._ +import org.knora.webapi.messages.v2.routing.authenticationmessages.KnoraCredentialsV2.{ + KnoraJWTTokenCredentialsV2, + KnoraPasswordCredentialsV2, + KnoraSessionCredentialsV2 +} import org.knora.webapi.messages.v2.routing.authenticationmessages._ import org.knora.webapi.settings.KnoraSettings import org.knora.webapi.util.cache.CacheUtil @@ -52,7 +57,7 @@ import scala.util.{Failure, Success, Try} * to extract credentials, authenticate provided credentials, and look up cached credentials through the use of the * session id. All private methods used in this trait can be found in the companion object. */ -trait Authenticator { +trait Authenticator extends InstrumentationSupport { // Import companion object @@ -141,7 +146,7 @@ trait Authenticator { for { // will throw exception if not valid and thus trigger the correct response - authenticated <- authenticateCredentialsV2( + _ <- authenticateCredentialsV2( credentials = Some(credentials), featureFactoryConfig = featureFactoryConfig ) @@ -194,7 +199,7 @@ trait Authenticator { |
|
|

Knora Login

- |
+ | |

| |

@@ -288,7 +293,7 @@ trait Authenticator { for { // will throw exception if not valid - authenticated <- authenticateCredentialsV2( + _ <- authenticateCredentialsV2( credentials = credentials, featureFactoryConfig = featureFactoryConfig ) @@ -324,8 +329,8 @@ trait Authenticator { val cookieDomain = Some(settings.cookieDomain) credentials match { - case Some(sessionCreds: KnoraSessionCredentialsV2) => { - CacheUtil.put(AUTHENTICATION_INVALIDATION_CACHE_NAME, sessionCreds.token, sessionCreds.token) + case Some(KnoraSessionCredentialsV2(sessionToken)) => + CacheUtil.put(AUTHENTICATION_INVALIDATION_CACHE_NAME, sessionToken, sessionToken) HttpResponse( headers = List( @@ -349,10 +354,8 @@ trait Authenticator { ).compactPrint ) ) - - } - case Some(tokenCreds: KnoraTokenCredentialsV2) => { - CacheUtil.put(AUTHENTICATION_INVALIDATION_CACHE_NAME, tokenCreds.token, tokenCreds.token) + case Some(KnoraJWTTokenCredentialsV2(jwtToken)) => + CacheUtil.put(AUTHENTICATION_INVALIDATION_CACHE_NAME, jwtToken, jwtToken) HttpResponse( headers = List( @@ -376,8 +379,7 @@ trait Authenticator { ).compactPrint ) ) - } - case _ => { + case _ => // nothing to do HttpResponse( status = StatusCodes.OK, @@ -389,7 +391,6 @@ trait Authenticator { ).compactPrint ) ) - } } } @@ -481,7 +482,7 @@ trait Authenticator { _ = log.debug("Authenticator - getUserADM - user: {}", user) /* we return the complete UserADM */ - } yield user.ofType(UserInformationTypeADM.FULL) + } yield user.ofType(UserInformationTypeADM.Full) } } } @@ -491,7 +492,7 @@ trait Authenticator { * the private methods directly with scalatest as described in [[https://groups.google.com/forum/#!topic/scalatest-users/FeaO\_\_f1dN4]] * and [[http://doc.scalatest.org/2.2.6/index.html#org.scalatest.PrivateMethodTester]] */ -object Authenticator { +object Authenticator extends InstrumentationSupport { val BAD_CRED_PASSWORD_MISMATCH = "bad credentials: user found, but password did not match" val BAD_CRED_USER_NOT_FOUND = "bad credentials: user not found" @@ -505,7 +506,7 @@ object Authenticator { val sessionStore: scala.collection.mutable.Map[String, UserADM] = scala.collection.mutable.Map() implicit val timeout: Timeout = Duration(5, SECONDS) - val log = Logger(LoggerFactory.getLogger(this.getClass)) + val log: Logger = Logger(LoggerFactory.getLogger(this.getClass)) private implicit val stringFormatter: StringFormatter = StringFormatter.getGeneralInstance @@ -531,7 +532,7 @@ object Authenticator { settings <- FastFuture.successful(KnoraSettings(system)) result <- credentials match { - case Some(passCreds: KnoraPasswordCredentialsV2) => { + case Some(passCreds: KnoraPasswordCredentialsV2) => for { user <- getUserByIdentifier( identifier = passCreds.identifier, @@ -549,25 +550,21 @@ object Authenticator { throw BadCredentialsException(BAD_CRED_NOT_VALID) } } yield true - } - case Some(tokenCreds: KnoraTokenCredentialsV2) => { - if (!JWTHelper.validateToken(tokenCreds.token, settings.jwtSecretKey)) { + case Some(KnoraJWTTokenCredentialsV2(jwtToken)) => + if (!JWTHelper.validateToken(jwtToken, settings.jwtSecretKey)) { log.debug("authenticateCredentialsV2 - token was not valid") throw BadCredentialsException(BAD_CRED_NOT_VALID) } FastFuture.successful(true) - } - case Some(sessionCreds: KnoraSessionCredentialsV2) => { - if (!JWTHelper.validateToken(sessionCreds.token, settings.jwtSecretKey)) { + case Some(KnoraSessionCredentialsV2(sessionToken)) => + if (!JWTHelper.validateToken(sessionToken, settings.jwtSecretKey)) { log.debug("authenticateCredentialsV2 - session token was not valid") throw BadCredentialsException(BAD_CRED_NOT_VALID) } FastFuture.successful(true) - } - case None => { + case None => log.debug("authenticateCredentialsV2 - no credentials supplied") throw BadCredentialsException(BAD_CRED_NONE_SUPPLIED) - } } } yield result @@ -643,8 +640,8 @@ object Authenticator { val maybeToken: Option[String] = params get "token" map (_.head) - val maybeTokenCreds: Option[KnoraTokenCredentialsV2] = if (maybeToken.nonEmpty) { - Some(KnoraTokenCredentialsV2(maybeToken.get)) + val maybeTokenCreds: Option[KnoraJWTTokenCredentialsV2] = if (maybeToken.nonEmpty) { + Some(KnoraJWTTokenCredentialsV2(maybeToken.get)) } else { None } @@ -722,8 +719,8 @@ object Authenticator { None } - val maybeTokenCreds: Option[KnoraTokenCredentialsV2] = if (maybeToken.nonEmpty) { - Some(KnoraTokenCredentialsV2(maybeToken.get)) + val maybeTokenCreds: Option[KnoraJWTTokenCredentialsV2] = if (maybeToken.nonEmpty) { + Some(KnoraJWTTokenCredentialsV2(maybeToken.get)) } else { None } @@ -765,45 +762,39 @@ object Authenticator { authenticated <- authenticateCredentialsV2(credentials = credentials, featureFactoryConfig = featureFactoryConfig) user: UserADM <- credentials match { - case Some(passCreds: KnoraPasswordCredentialsV2) => { + case Some(passCreds: KnoraPasswordCredentialsV2) => // log.debug("getUserADMThroughCredentialsV2 - used identifier: {}", passCreds.identifier) getUserByIdentifier( identifier = passCreds.identifier, featureFactoryConfig = featureFactoryConfig ) - } - case Some(tokenCreds: KnoraTokenCredentialsV2) => { - val userIri: IRI = JWTHelper.extractUserIriFromToken(tokenCreds.token, settings.jwtSecretKey) match { + case Some(KnoraJWTTokenCredentialsV2(jwtToken)) => + val userIri: IRI = JWTHelper.extractUserIriFromToken(jwtToken, settings.jwtSecretKey) match { case Some(iri) => iri - case None => { + case None => // should not happen, as the token is already validated throw AuthenticationException("No IRI found inside token. Please report this as a possible bug.") - } } // log.debug("getUserADMThroughCredentialsV2 - used token") getUserByIdentifier( identifier = UserIdentifierADM(maybeIri = Some(userIri)), featureFactoryConfig = featureFactoryConfig ) - } - case Some(sessionCreds: KnoraSessionCredentialsV2) => { - val userIri: IRI = JWTHelper.extractUserIriFromToken(sessionCreds.token, settings.jwtSecretKey) match { + case Some(KnoraSessionCredentialsV2(sessionToken)) => + val userIri: IRI = JWTHelper.extractUserIriFromToken(sessionToken, settings.jwtSecretKey) match { case Some(iri) => iri - case None => { + case None => // should not happen, as the token is already validated throw AuthenticationException("No IRI found inside token. Please report this as a possible bug.") - } } // log.debug("getUserADMThroughCredentialsV2 - used session token") getUserByIdentifier( identifier = UserIdentifierADM(maybeIri = Some(userIri)), featureFactoryConfig = featureFactoryConfig ) - } - case None => { + case None => // log.debug("getUserADMThroughCredentialsV2 - no credentials supplied") throw BadCredentialsException(BAD_CRED_NONE_SUPPLIED) - } } } yield user @@ -829,27 +820,23 @@ object Authenticator { responderManager: ActorRef, timeout: Timeout, executionContext: ExecutionContext - ): Future[UserADM] = { - - val userADMFuture = for { + ): Future[UserADM] = tracedFuture("authenticator-get-user-by-identifier") { + for { maybeUserADM <- (responderManager ? UserGetADM( identifier = identifier, - userInformationTypeADM = UserInformationTypeADM.FULL, + userInformationTypeADM = UserInformationTypeADM.Full, featureFactoryConfig = featureFactoryConfig, requestingUser = KnoraSystemInstances.Users.SystemUser )).mapTo[Option[UserADM]] user = maybeUserADM match { case Some(u) => u - case None => { + case None => log.debug(s"getUserByIdentifier - supplied identifier not found - throwing exception") throw BadCredentialsException(s"$BAD_CRED_USER_NOT_FOUND") - } } // _ = log.debug(s"getUserByIdentifier - user: $user") } yield user - - userADMFuture } } diff --git a/webapi/src/main/scala/org/knora/webapi/routing/admin/UsersRouteADM.scala b/webapi/src/main/scala/org/knora/webapi/routing/admin/UsersRouteADM.scala index cf7ed7c5f8..d72e4411f3 100644 --- a/webapi/src/main/scala/org/knora/webapi/routing/admin/UsersRouteADM.scala +++ b/webapi/src/main/scala/org/knora/webapi/routing/admin/UsersRouteADM.scala @@ -176,7 +176,7 @@ class UsersRouteADM(routeData: KnoraRouteData) extends KnoraRoute(routeData) wit ) } yield UserGetRequestADM( identifier = UserIdentifierADM(maybeIri = Some(userIri)), - userInformationTypeADM = UserInformationTypeADM.RESTRICTED, + userInformationTypeADM = UserInformationTypeADM.Restricted, featureFactoryConfig = featureFactoryConfig, requestingUser = requestingUser ) @@ -205,7 +205,7 @@ class UsersRouteADM(routeData: KnoraRouteData) extends KnoraRoute(routeData) wit ) } yield UserGetRequestADM( identifier = UserIdentifierADM(maybeEmail = Some(userIri)), - userInformationTypeADM = UserInformationTypeADM.RESTRICTED, + userInformationTypeADM = UserInformationTypeADM.Restricted, featureFactoryConfig = featureFactoryConfig, requestingUser = requestingUser ) @@ -234,7 +234,7 @@ class UsersRouteADM(routeData: KnoraRouteData) extends KnoraRoute(routeData) wit ) } yield UserGetRequestADM( identifier = UserIdentifierADM(maybeUsername = Some(userIri)), - userInformationTypeADM = UserInformationTypeADM.RESTRICTED, + userInformationTypeADM = UserInformationTypeADM.Restricted, featureFactoryConfig = featureFactoryConfig, requestingUser = requestingUser ) diff --git a/webapi/src/main/scala/org/knora/webapi/routing/v2/AuthenticationRouteV2.scala b/webapi/src/main/scala/org/knora/webapi/routing/v2/AuthenticationRouteV2.scala index cd2e5ee099..7ce686c862 100644 --- a/webapi/src/main/scala/org/knora/webapi/routing/v2/AuthenticationRouteV2.scala +++ b/webapi/src/main/scala/org/knora/webapi/routing/v2/AuthenticationRouteV2.scala @@ -23,9 +23,9 @@ import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.Route import org.knora.webapi.feature.FeatureFactoryConfig import org.knora.webapi.messages.admin.responder.usersmessages.UserIdentifierADM +import org.knora.webapi.messages.v2.routing.authenticationmessages.KnoraCredentialsV2.KnoraPasswordCredentialsV2 import org.knora.webapi.messages.v2.routing.authenticationmessages.{ AuthenticationV2JsonProtocol, - KnoraPasswordCredentialsV2, LoginApiRequestPayloadV2 } import org.knora.webapi.routing.{Authenticator, KnoraRoute, KnoraRouteData} diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/CacheServiceManager.scala b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/CacheServiceManager.scala index a3a9764ca7..d108ab2ff1 100644 --- a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/CacheServiceManager.scala +++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/CacheServiceManager.scala @@ -47,7 +47,7 @@ class CacheServiceManager(cs: CacheService) */ protected implicit val ec: ExecutionContext = context.system.dispatchers.lookup(KnoraDispatchers.KnoraActorDispatcher) - def receive = { + def receive: Receive = { case CacheServicePutUserADM(value) => future2Message(sender(), putUserADM(value), log) case CacheServiceGetUserADM(identifier) => future2Message(sender(), getUserADM(identifier), log) case CacheServicePutProjectADM(value) => future2Message(sender(), putProjectADM(value), log) @@ -82,7 +82,7 @@ class CacheServiceManager(cs: CacheService) * @param identifier the project identifier. */ private def getUserADM(identifier: UserIdentifierADM): Future[Option[UserADM]] = - tracedFuture("cache-service-read-user") { + tracedFuture("cache-service-get-user") { cs.getUserADM(identifier) } @@ -109,7 +109,7 @@ class CacheServiceManager(cs: CacheService) private def getProjectADM( identifier: ProjectIdentifierADM )(implicit ec: ExecutionContext): Future[Option[ProjectADM]] = - tracedFuture("redis-read-project") { + tracedFuture("cache-read-project") { cs.getProjectADM(identifier) } @@ -140,7 +140,7 @@ class CacheServiceManager(cs: CacheService) * @param keys the keys. */ private def removeValues(keys: Set[String]): Future[Boolean] = - tracedFuture("redis-remove-values") { + tracedFuture("cache-remove-values") { cs.removeValues(keys) } @@ -148,7 +148,7 @@ class CacheServiceManager(cs: CacheService) * Flushes (removes) all stored content from the Redis store. */ private def flushDB(requestingUser: UserADM): Future[CacheServiceFlushDBACK] = - tracedFuture("redis-flush-db") { + tracedFuture("cache-flush") { cs.flushDB(requestingUser) } diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/inmem/CacheServiceInMemImpl.scala b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/inmem/CacheServiceInMemImpl.scala index b6ea1ba12b..dc2338ca93 100644 --- a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/inmem/CacheServiceInMemImpl.scala +++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/inmem/CacheServiceInMemImpl.scala @@ -69,14 +69,14 @@ object CacheServiceInMemImpl extends CacheService with LazyLogging { // The data is stored under the IRI key. // Additionally, the USERNAME and EMAIL keys point to the IRI key val resultFuture: Future[Option[UserADM]] = identifier.hasType match { - case UserIdentifierType.IRI => FastFuture.successful(cache.get(identifier.toIri).map(_.asInstanceOf[UserADM])) - case UserIdentifierType.USERNAME => { + case UserIdentifierType.Iri => FastFuture.successful(cache.get(identifier.toIri).map(_.asInstanceOf[UserADM])) + case UserIdentifierType.Username => { cache.get(identifier.toUsername) match { case Some(iriKey) => FastFuture.successful(cache.get(iriKey).map(_.asInstanceOf[UserADM])) case None => FastFuture.successful(None) } } - case UserIdentifierType.EMAIL => + case UserIdentifierType.Email => cache.get(identifier.toEmail) match { case Some(iriKey) => FastFuture.successful(cache.get(iriKey).map(_.asInstanceOf[UserADM])) case None => FastFuture.successful(None) diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImpl.scala b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImpl.scala index 79298e7b62..5ddeb95d9b 100644 --- a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImpl.scala +++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImpl.scala @@ -90,7 +90,7 @@ class CacheServiceRedisImpl(s: CacheServiceSettings) extends CacheService with L // The data is stored under the IRI key. // Additionally, the USERNAME and EMAIL keys point to the IRI key val resultFuture: Future[Option[UserADM]] = identifier.hasType match { - case UserIdentifierType.IRI => + case UserIdentifierType.Iri => for { maybeBytes: Option[Array[Byte]] <- getBytesValue(identifier.toIriOption) maybeUser: Option[UserADM] <- maybeBytes match { @@ -99,7 +99,7 @@ class CacheServiceRedisImpl(s: CacheServiceSettings) extends CacheService with L } } yield maybeUser - case UserIdentifierType.USERNAME => + case UserIdentifierType.Username => for { maybeIriKey: Option[String] <- getStringValue(identifier.toUsernameOption) maybeBytes: Option[Array[Byte]] <- getBytesValue(maybeIriKey) @@ -109,7 +109,7 @@ class CacheServiceRedisImpl(s: CacheServiceSettings) extends CacheService with L } } yield maybeUser - case UserIdentifierType.EMAIL => + case UserIdentifierType.Email => for { maybeIriKey: Option[String] <- getStringValue(identifier.toEmailOption) maybeBytes: Option[Array[Byte]] <- getBytesValue(maybeIriKey) diff --git a/webapi/src/test/resources/logback-test.xml b/webapi/src/test/resources/logback-test.xml index 6ec17e8183..11795ec826 100644 --- a/webapi/src/test/resources/logback-test.xml +++ b/webapi/src/test/resources/logback-test.xml @@ -146,9 +146,10 @@ - - - + + + + diff --git a/webapi/src/test/scala/org/knora/webapi/messages/admin/responder/usersmessages/UsersMessagesADMSpec.scala b/webapi/src/test/scala/org/knora/webapi/messages/admin/responder/usersmessages/UsersMessagesADMSpec.scala index 622eccc105..1104e3911c 100644 --- a/webapi/src/test/scala/org/knora/webapi/messages/admin/responder/usersmessages/UsersMessagesADMSpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/messages/admin/responder/usersmessages/UsersMessagesADMSpec.scala @@ -23,7 +23,7 @@ import com.typesafe.config.{Config, ConfigFactory} import org.knora.webapi._ import org.knora.webapi.exceptions.BadRequestException import org.knora.webapi.messages.StringFormatter -import org.knora.webapi.messages.admin.responder.permissionsmessages.{PermissionDataType, PermissionsDataADM} +import org.knora.webapi.messages.admin.responder.permissionsmessages.{PermissionProfileType, PermissionsDataADM} import org.knora.webapi.sharedtestdata.SharedTestDataADM import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder @@ -86,10 +86,10 @@ class UsersMessagesADMSpec extends CoreSpec(UsersMessagesADMSpec.config) { groups = groups, projects = projects, sessionId = sessionId, - permissions = permissions.ofType(PermissionDataType.RESTRICTED) + permissions = permissions.ofType(PermissionProfileType.Restricted) ) - assert(rootUser.ofType(UserInformationTypeADM.RESTRICTED) === rootUserRestricted) + assert(rootUser.ofType(UserInformationTypeADM.Restricted) === rootUserRestricted) } "return true if user is ProjectAdmin in any project " in { @@ -180,13 +180,13 @@ class UsersMessagesADMSpec extends CoreSpec(UsersMessagesADMSpec.config) { "return the identifier type" in { val iriIdentifier = UserIdentifierADM(maybeIri = Some("http://rdfh.ch/users/root")) - iriIdentifier.hasType should be(UserIdentifierType.IRI) + iriIdentifier.hasType should be(UserIdentifierType.Iri) val emailIdentifier = UserIdentifierADM(maybeEmail = Some("root@example.com")) - emailIdentifier.hasType should be(UserIdentifierType.EMAIL) + emailIdentifier.hasType should be(UserIdentifierType.Email) val usernameIdentifier = UserIdentifierADM(maybeUsername = Some("root")) - usernameIdentifier.hasType should be(UserIdentifierType.USERNAME) + usernameIdentifier.hasType should be(UserIdentifierType.Username) } "check whether a user identified by email is the same as a user identified by username" in { diff --git a/webapi/src/test/scala/org/knora/webapi/messages/v1/responder/usermessages/UserMessagesV1Spec.scala b/webapi/src/test/scala/org/knora/webapi/messages/v1/responder/usermessages/UserMessagesV1Spec.scala index cd4e9ec43c..15e72c40fc 100644 --- a/webapi/src/test/scala/org/knora/webapi/messages/v1/responder/usermessages/UserMessagesV1Spec.scala +++ b/webapi/src/test/scala/org/knora/webapi/messages/v1/responder/usermessages/UserMessagesV1Spec.scala @@ -20,7 +20,7 @@ package org.knora.webapi.messages.v1.responder.usermessages import org.knora.webapi.messages.admin.responder.permissionsmessages -import org.knora.webapi.messages.admin.responder.permissionsmessages.PermissionDataType +import org.knora.webapi.messages.admin.responder.permissionsmessages.PermissionProfileType import org.knora.webapi.sharedtestdata.SharedTestDataV1 import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpecLike @@ -73,7 +73,7 @@ class UserMessagesV1Spec extends AnyWordSpecLike with Matchers { ), groups = groups, projects_info = projects_info, - permissionData = permissionData.ofType(PermissionDataType.RESTRICTED), + permissionData = permissionData.ofType(PermissionProfileType.Restricted), sessionId = sessionId ) diff --git a/webapi/src/test/scala/org/knora/webapi/other/v1/DrawingsGodsV1Spec.scala b/webapi/src/test/scala/org/knora/webapi/other/v1/DrawingsGodsV1Spec.scala index 2ab27fed06..27b8d75ad4 100644 --- a/webapi/src/test/scala/org/knora/webapi/other/v1/DrawingsGodsV1Spec.scala +++ b/webapi/src/test/scala/org/knora/webapi/other/v1/DrawingsGodsV1Spec.scala @@ -84,7 +84,7 @@ class DrawingsGodsV1Spec extends CoreSpec(DrawingsGodsV1Spec.config) with Triple "retrieve the drawings gods user's profile" in { responderManager ! UserGetADM( identifier = UserIdentifierADM(maybeIri = Some(rootUserIri)), - userInformationTypeADM = UserInformationTypeADM.FULL, + userInformationTypeADM = UserInformationTypeADM.Full, featureFactoryConfig = defaultFeatureFactoryConfig, requestingUser = KnoraSystemInstances.Users.SystemUser ) @@ -93,7 +93,7 @@ class DrawingsGodsV1Spec extends CoreSpec(DrawingsGodsV1Spec.config) with Triple responderManager ! UserGetADM( identifier = UserIdentifierADM(maybeIri = Some(ddd1UserIri)), - userInformationTypeADM = UserInformationTypeADM.FULL, + userInformationTypeADM = UserInformationTypeADM.Full, featureFactoryConfig = defaultFeatureFactoryConfig, requestingUser = KnoraSystemInstances.Users.SystemUser ) @@ -102,7 +102,7 @@ class DrawingsGodsV1Spec extends CoreSpec(DrawingsGodsV1Spec.config) with Triple responderManager ! UserGetADM( UserIdentifierADM(maybeIri = Some(ddd2UserIri)), - userInformationTypeADM = UserInformationTypeADM.FULL, + userInformationTypeADM = UserInformationTypeADM.Full, featureFactoryConfig = defaultFeatureFactoryConfig, requestingUser = KnoraSystemInstances.Users.SystemUser ) diff --git a/webapi/src/test/scala/org/knora/webapi/responders/admin/GroupsResponderADMSpec.scala b/webapi/src/test/scala/org/knora/webapi/responders/admin/GroupsResponderADMSpec.scala index b4839a602b..cb14ec4656 100644 --- a/webapi/src/test/scala/org/knora/webapi/responders/admin/GroupsResponderADMSpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/responders/admin/GroupsResponderADMSpec.scala @@ -247,8 +247,8 @@ class GroupsResponderADMSpec extends CoreSpec(GroupsResponderADMSpec.config) wit val received: GroupMembersGetResponseADM = expectMsgType[GroupMembersGetResponseADM](timeout) received.members.map(_.id) should contain allElementsOf Seq( - SharedTestDataADM.multiuserUser.ofType(UserInformationTypeADM.RESTRICTED), - SharedTestDataADM.imagesReviewerUser.ofType(UserInformationTypeADM.RESTRICTED) + SharedTestDataADM.multiuserUser.ofType(UserInformationTypeADM.Restricted), + SharedTestDataADM.imagesReviewerUser.ofType(UserInformationTypeADM.Restricted) ).map(_.id) } diff --git a/webapi/src/test/scala/org/knora/webapi/responders/admin/ProjectsResponderADMSpec.scala b/webapi/src/test/scala/org/knora/webapi/responders/admin/ProjectsResponderADMSpec.scala index daf800da34..8f4d615b3b 100644 --- a/webapi/src/test/scala/org/knora/webapi/responders/admin/ProjectsResponderADMSpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/responders/admin/ProjectsResponderADMSpec.scala @@ -553,10 +553,10 @@ class ProjectsResponderADMSpec extends CoreSpec(ProjectsResponderADMSpec.config) members.size should be(4) members.map(_.id) should contain allElementsOf Seq( - SharedTestDataADM.imagesUser01.ofType(UserInformationTypeADM.RESTRICTED), - SharedTestDataADM.imagesUser02.ofType(UserInformationTypeADM.RESTRICTED), - SharedTestDataADM.multiuserUser.ofType(UserInformationTypeADM.RESTRICTED), - SharedTestDataADM.imagesReviewerUser.ofType(UserInformationTypeADM.RESTRICTED) + SharedTestDataADM.imagesUser01.ofType(UserInformationTypeADM.Restricted), + SharedTestDataADM.imagesUser02.ofType(UserInformationTypeADM.Restricted), + SharedTestDataADM.multiuserUser.ofType(UserInformationTypeADM.Restricted), + SharedTestDataADM.imagesReviewerUser.ofType(UserInformationTypeADM.Restricted) ).map(_.id) } @@ -572,10 +572,10 @@ class ProjectsResponderADMSpec extends CoreSpec(ProjectsResponderADMSpec.config) members.size should be(4) members.map(_.id) should contain allElementsOf Seq( - SharedTestDataADM.imagesUser01.ofType(UserInformationTypeADM.SHORT), - SharedTestDataADM.imagesUser02.ofType(UserInformationTypeADM.SHORT), - SharedTestDataADM.multiuserUser.ofType(UserInformationTypeADM.SHORT), - SharedTestDataADM.imagesReviewerUser.ofType(UserInformationTypeADM.SHORT) + SharedTestDataADM.imagesUser01.ofType(UserInformationTypeADM.Short), + SharedTestDataADM.imagesUser02.ofType(UserInformationTypeADM.Short), + SharedTestDataADM.multiuserUser.ofType(UserInformationTypeADM.Short), + SharedTestDataADM.imagesReviewerUser.ofType(UserInformationTypeADM.Short) ).map(_.id) } @@ -591,10 +591,10 @@ class ProjectsResponderADMSpec extends CoreSpec(ProjectsResponderADMSpec.config) members.size should be(4) members.map(_.id) should contain allElementsOf Seq( - SharedTestDataADM.imagesUser01.ofType(UserInformationTypeADM.SHORT), - SharedTestDataADM.imagesUser02.ofType(UserInformationTypeADM.SHORT), - SharedTestDataADM.multiuserUser.ofType(UserInformationTypeADM.SHORT), - SharedTestDataADM.imagesReviewerUser.ofType(UserInformationTypeADM.SHORT) + SharedTestDataADM.imagesUser01.ofType(UserInformationTypeADM.Short), + SharedTestDataADM.imagesUser02.ofType(UserInformationTypeADM.Short), + SharedTestDataADM.multiuserUser.ofType(UserInformationTypeADM.Short), + SharedTestDataADM.imagesReviewerUser.ofType(UserInformationTypeADM.Short) ).map(_.id) } @@ -637,8 +637,8 @@ class ProjectsResponderADMSpec extends CoreSpec(ProjectsResponderADMSpec.config) members.size should be(2) members.map(_.id) should contain allElementsOf Seq( - SharedTestDataADM.imagesUser01.ofType(UserInformationTypeADM.SHORT), - SharedTestDataADM.multiuserUser.ofType(UserInformationTypeADM.SHORT) + SharedTestDataADM.imagesUser01.ofType(UserInformationTypeADM.Short), + SharedTestDataADM.multiuserUser.ofType(UserInformationTypeADM.Short) ).map(_.id) } @@ -654,8 +654,8 @@ class ProjectsResponderADMSpec extends CoreSpec(ProjectsResponderADMSpec.config) members.size should be(2) members.map(_.id) should contain allElementsOf Seq( - SharedTestDataADM.imagesUser01.ofType(UserInformationTypeADM.SHORT), - SharedTestDataADM.multiuserUser.ofType(UserInformationTypeADM.SHORT) + SharedTestDataADM.imagesUser01.ofType(UserInformationTypeADM.Short), + SharedTestDataADM.multiuserUser.ofType(UserInformationTypeADM.Short) ).map(_.id) } @@ -671,8 +671,8 @@ class ProjectsResponderADMSpec extends CoreSpec(ProjectsResponderADMSpec.config) members.size should be(2) members.map(_.id) should contain allElementsOf Seq( - SharedTestDataADM.imagesUser01.ofType(UserInformationTypeADM.SHORT), - SharedTestDataADM.multiuserUser.ofType(UserInformationTypeADM.SHORT) + SharedTestDataADM.imagesUser01.ofType(UserInformationTypeADM.Short), + SharedTestDataADM.multiuserUser.ofType(UserInformationTypeADM.Short) ).map(_.id) } diff --git a/webapi/src/test/scala/org/knora/webapi/responders/admin/UsersResponderADMSpec.scala b/webapi/src/test/scala/org/knora/webapi/responders/admin/UsersResponderADMSpec.scala index c9fdd230cc..bc02448b98 100644 --- a/webapi/src/test/scala/org/knora/webapi/responders/admin/UsersResponderADMSpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/responders/admin/UsersResponderADMSpec.scala @@ -30,7 +30,7 @@ import org.knora.webapi.messages.admin.responder.groupsmessages.{GroupMembersGet import org.knora.webapi.messages.admin.responder.projectsmessages._ import org.knora.webapi.messages.admin.responder.usersmessages.{UserChangeRequestADM, _} import org.knora.webapi.messages.util.KnoraSystemInstances -import org.knora.webapi.messages.v2.routing.authenticationmessages.KnoraPasswordCredentialsV2 +import org.knora.webapi.messages.v2.routing.authenticationmessages.KnoraCredentialsV2.KnoraPasswordCredentialsV2 import org.knora.webapi.routing.Authenticator import org.knora.webapi.sharedtestdata.SharedTestDataADM @@ -112,27 +112,27 @@ class UsersResponderADMSpec extends CoreSpec(UsersResponderADMSpec.config) with "return a profile if the user (root user) is known" in { responderManager ! UserGetADM( identifier = UserIdentifierADM(maybeIri = Some(rootUser.id)), - userInformationTypeADM = UserInformationTypeADM.FULL, + userInformationTypeADM = UserInformationTypeADM.Full, featureFactoryConfig = defaultFeatureFactoryConfig, requestingUser = KnoraSystemInstances.Users.SystemUser ) - expectMsg(Some(rootUser.ofType(UserInformationTypeADM.FULL))) + expectMsg(Some(rootUser.ofType(UserInformationTypeADM.Full))) } "return a profile if the user (incunabula user) is known" in { responderManager ! UserGetADM( identifier = UserIdentifierADM(maybeIri = Some(incunabulaUser.id)), - userInformationTypeADM = UserInformationTypeADM.FULL, + userInformationTypeADM = UserInformationTypeADM.Full, featureFactoryConfig = defaultFeatureFactoryConfig, requestingUser = KnoraSystemInstances.Users.SystemUser ) - expectMsg(Some(incunabulaUser.ofType(UserInformationTypeADM.FULL))) + expectMsg(Some(incunabulaUser.ofType(UserInformationTypeADM.Full))) } "return 'NotFoundException' when the user is unknown" in { responderManager ! UserGetRequestADM( identifier = UserIdentifierADM(maybeIri = Some("http://rdfh.ch/users/notexisting")), - userInformationTypeADM = UserInformationTypeADM.FULL, + userInformationTypeADM = UserInformationTypeADM.Full, featureFactoryConfig = defaultFeatureFactoryConfig, requestingUser = KnoraSystemInstances.Users.SystemUser ) @@ -142,7 +142,7 @@ class UsersResponderADMSpec extends CoreSpec(UsersResponderADMSpec.config) with "return 'None' when the user is unknown" in { responderManager ! UserGetADM( identifier = UserIdentifierADM(maybeIri = Some("http://rdfh.ch/users/notexisting")), - userInformationTypeADM = UserInformationTypeADM.FULL, + userInformationTypeADM = UserInformationTypeADM.Full, featureFactoryConfig = defaultFeatureFactoryConfig, requestingUser = KnoraSystemInstances.Users.SystemUser ) @@ -155,27 +155,27 @@ class UsersResponderADMSpec extends CoreSpec(UsersResponderADMSpec.config) with "return a profile if the user (root user) is known" in { responderManager ! UserGetADM( identifier = UserIdentifierADM(maybeEmail = Some(rootUser.email)), - userInformationTypeADM = UserInformationTypeADM.FULL, + userInformationTypeADM = UserInformationTypeADM.Full, featureFactoryConfig = defaultFeatureFactoryConfig, requestingUser = KnoraSystemInstances.Users.SystemUser ) - expectMsg(Some(rootUser.ofType(UserInformationTypeADM.FULL))) + expectMsg(Some(rootUser.ofType(UserInformationTypeADM.Full))) } "return a profile if the user (incunabula user) is known" in { responderManager ! UserGetADM( identifier = UserIdentifierADM(maybeEmail = Some(incunabulaUser.email)), - userInformationTypeADM = UserInformationTypeADM.FULL, + userInformationTypeADM = UserInformationTypeADM.Full, featureFactoryConfig = defaultFeatureFactoryConfig, requestingUser = KnoraSystemInstances.Users.SystemUser ) - expectMsg(Some(incunabulaUser.ofType(UserInformationTypeADM.FULL))) + expectMsg(Some(incunabulaUser.ofType(UserInformationTypeADM.Full))) } "return 'NotFoundException' when the user is unknown" in { responderManager ! UserGetRequestADM( identifier = UserIdentifierADM(maybeEmail = Some("userwrong@example.com")), - userInformationTypeADM = UserInformationTypeADM.FULL, + userInformationTypeADM = UserInformationTypeADM.Full, featureFactoryConfig = defaultFeatureFactoryConfig, requestingUser = KnoraSystemInstances.Users.SystemUser ) @@ -185,7 +185,7 @@ class UsersResponderADMSpec extends CoreSpec(UsersResponderADMSpec.config) with "return 'None' when the user is unknown" in { responderManager ! UserGetADM( identifier = UserIdentifierADM(maybeEmail = Some("userwrong@example.com")), - userInformationTypeADM = UserInformationTypeADM.FULL, + userInformationTypeADM = UserInformationTypeADM.Full, featureFactoryConfig = defaultFeatureFactoryConfig, requestingUser = KnoraSystemInstances.Users.SystemUser ) @@ -198,27 +198,27 @@ class UsersResponderADMSpec extends CoreSpec(UsersResponderADMSpec.config) with "return a profile if the user (root user) is known" in { responderManager ! UserGetADM( identifier = UserIdentifierADM(maybeUsername = Some(rootUser.username)), - userInformationTypeADM = UserInformationTypeADM.FULL, + userInformationTypeADM = UserInformationTypeADM.Full, featureFactoryConfig = defaultFeatureFactoryConfig, requestingUser = KnoraSystemInstances.Users.SystemUser ) - expectMsg(Some(rootUser.ofType(UserInformationTypeADM.FULL))) + expectMsg(Some(rootUser.ofType(UserInformationTypeADM.Full))) } "return a profile if the user (incunabula user) is known" in { responderManager ! UserGetADM( identifier = UserIdentifierADM(maybeUsername = Some(incunabulaUser.username)), - userInformationTypeADM = UserInformationTypeADM.FULL, + userInformationTypeADM = UserInformationTypeADM.Full, featureFactoryConfig = defaultFeatureFactoryConfig, requestingUser = KnoraSystemInstances.Users.SystemUser ) - expectMsg(Some(incunabulaUser.ofType(UserInformationTypeADM.FULL))) + expectMsg(Some(incunabulaUser.ofType(UserInformationTypeADM.Full))) } "return 'NotFoundException' when the user is unknown" in { responderManager ! UserGetRequestADM( identifier = UserIdentifierADM(maybeUsername = Some("userwrong")), - userInformationTypeADM = UserInformationTypeADM.FULL, + userInformationTypeADM = UserInformationTypeADM.Full, featureFactoryConfig = defaultFeatureFactoryConfig, requestingUser = KnoraSystemInstances.Users.SystemUser ) @@ -228,7 +228,7 @@ class UsersResponderADMSpec extends CoreSpec(UsersResponderADMSpec.config) with "return 'None' when the user is unknown" in { responderManager ! UserGetADM( identifier = UserIdentifierADM(maybeUsername = Some("userwrong")), - userInformationTypeADM = UserInformationTypeADM.FULL, + userInformationTypeADM = UserInformationTypeADM.Full, featureFactoryConfig = defaultFeatureFactoryConfig, requestingUser = KnoraSystemInstances.Users.SystemUser ) @@ -656,7 +656,7 @@ class UsersResponderADMSpec extends CoreSpec(UsersResponderADMSpec.config) with ) val received: ProjectMembersGetResponseADM = expectMsgType[ProjectMembersGetResponseADM](timeout) - received.members should not contain normalUser.ofType(UserInformationTypeADM.RESTRICTED) + received.members should not contain normalUser.ofType(UserInformationTypeADM.Restricted) } "return a 'ForbiddenException' if the user requesting update is not the project or system admin" in { @@ -732,7 +732,7 @@ class UsersResponderADMSpec extends CoreSpec(UsersResponderADMSpec.config) with ) val received: ProjectAdminMembersGetResponseADM = expectMsgType[ProjectAdminMembersGetResponseADM](timeout) - received.members should contain(normalUser.ofType(UserInformationTypeADM.RESTRICTED)) + received.members should contain(normalUser.ofType(UserInformationTypeADM.Restricted)) } "DELETE user from project admin group" in { @@ -770,7 +770,7 @@ class UsersResponderADMSpec extends CoreSpec(UsersResponderADMSpec.config) with ) val received: ProjectAdminMembersGetResponseADM = expectMsgType[ProjectAdminMembersGetResponseADM](timeout) - received.members should not contain normalUser.ofType(UserInformationTypeADM.RESTRICTED) + received.members should not contain normalUser.ofType(UserInformationTypeADM.Restricted) } "return a 'ForbiddenException' if the user requesting update is not the project or system admin" in { diff --git a/webapi/src/test/scala/org/knora/webapi/routing/AuthenticatorSpec.scala b/webapi/src/test/scala/org/knora/webapi/routing/AuthenticatorSpec.scala index 0353bb2258..a925fd6a5c 100644 --- a/webapi/src/test/scala/org/knora/webapi/routing/AuthenticatorSpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/routing/AuthenticatorSpec.scala @@ -25,7 +25,10 @@ import org.knora.webapi._ import org.knora.webapi.exceptions.{BadCredentialsException, BadRequestException} import org.knora.webapi.messages.StringFormatter import org.knora.webapi.messages.admin.responder.usersmessages.{UserADM, UserIdentifierADM} -import org.knora.webapi.messages.v2.routing.authenticationmessages.{KnoraPasswordCredentialsV2, KnoraTokenCredentialsV2} +import org.knora.webapi.messages.v2.routing.authenticationmessages.KnoraCredentialsV2.{ + KnoraJWTTokenCredentialsV2, + KnoraPasswordCredentialsV2 +} import org.knora.webapi.routing.Authenticator.AUTHENTICATION_INVALIDATION_CACHE_NAME import org.knora.webapi.sharedtestdata.SharedTestDataADM import org.knora.webapi.util.cache.CacheUtil @@ -143,7 +146,7 @@ class AuthenticatorSpec extends CoreSpec("AuthenticationTestSystem") with Implic } "succeed with correct token" in { val token = JWTHelper.createToken("myuseriri", settings.jwtSecretKey, settings.jwtLongevity) - val tokenCreds = KnoraTokenCredentialsV2(token) + val tokenCreds = KnoraJWTTokenCredentialsV2(token) val resF = Authenticator invokePrivate authenticateCredentialsV2( Some(tokenCreds), defaultFeatureFactoryConfig, @@ -157,8 +160,8 @@ class AuthenticatorSpec extends CoreSpec("AuthenticationTestSystem") with Implic } "fail with invalidated token" in { val token = JWTHelper.createToken("myuseriri", settings.jwtSecretKey, settings.jwtLongevity) - val tokenCreds = KnoraTokenCredentialsV2(token) - CacheUtil.put(AUTHENTICATION_INVALIDATION_CACHE_NAME, tokenCreds.token, tokenCreds.token) + val tokenCreds = KnoraJWTTokenCredentialsV2(token) + CacheUtil.put(AUTHENTICATION_INVALIDATION_CACHE_NAME, tokenCreds.jwtToken, tokenCreds.jwtToken) val resF = Authenticator invokePrivate authenticateCredentialsV2( Some(tokenCreds), defaultFeatureFactoryConfig, @@ -171,7 +174,7 @@ class AuthenticatorSpec extends CoreSpec("AuthenticationTestSystem") with Implic } } "fail with wrong token" in { - val tokenCreds = KnoraTokenCredentialsV2("123456") + val tokenCreds = KnoraJWTTokenCredentialsV2("123456") val resF = Authenticator invokePrivate authenticateCredentialsV2( Some(tokenCreds), defaultFeatureFactoryConfig,