Skip to content

Commit

Permalink
Improved error and debugging messages
Browse files Browse the repository at this point in the history
  • Loading branch information
1earch committed Sep 5, 2019
1 parent 90ec8ff commit 5616e38
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 36 deletions.
9 changes: 5 additions & 4 deletions thehive-backend/app/services/OAuth2Srv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class OAuth2Srv(
}

private def getAuthTokenAndAuthenticate(clientId: String, code: String)(implicit request: RequestHeader): Future[AuthContext] = {
logger.debug("Getting user token with the code from the response!")
logger.debug("Getting user token with the code from the response")
withOAuth2Config { cfg
ws.url(cfg.tokenUrl)
.post(
Expand All @@ -99,22 +99,23 @@ class OAuth2Srv(
.flatMap { r
r.status match {
case Status.OK
logger.debug("Getting user info using access token")
val accessToken = (r.json \ "access_token").asOpt[String].getOrElse("")
val authHeader = "Authorization" s"bearer $accessToken"
ws.url(cfg.userUrl)
.addHttpHeaders(authHeader)
.get()
.flatMap { userResponse
if (userResponse.status != Status.OK) {
Future.failed(AuthenticationError(s"unexpected response from server: ${userResponse.status} ${userResponse.body}"))
Future.failed(AuthenticationError(s"Unexpected response from server: ${userResponse.status} ${userResponse.body}"))
} else {
val response = userResponse.json.asInstanceOf[JsObject]
getOrCreateUser(response, authHeader)
}
}
case _
logger.error(s"unexpected response from server: ${r.status} ${r.body}")
Future.failed(AuthenticationError("unexpected response from server"))
logger.error(s"Unexpected response from server: ${r.status} ${r.body}")
Future.failed(AuthenticationError("Unexpected response from server"))
}
}
}
Expand Down
60 changes: 29 additions & 31 deletions thehive-backend/app/services/mappers/GroupUserMapper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -55,45 +55,43 @@ class GroupUserMapper(
case None Seq.empty[String]
}
}

def apply(input: String): Seq[String] = parseAll(expr, input) match {
case Success(result, _) result
case failure : NoSuccess {
logger.error(s"Can't parse groups list: ${failure.msg}")
Seq.empty[String]
}
}
}

override def getUserFields(jsValue: JsValue, authHeader: Option[(String, String)]): Future[Fields] = {
groupsUrl match {
case Some(groupsEndpointUrl) {
logger.debug(s"Retreiving groups from ${groupsEndpointUrl}")
val apiCall = authHeader.fold(ws.url(groupsEndpointUrl))(headers ws.url(groupsEndpointUrl).addHttpHeaders(headers))
apiCall.get.flatMap { r
val jsonGroups = (r.json \ groupsAttrName).as[Seq[String]]
mapGroupsAndBuildUserFields(jsValue, jsonGroups)
}
apiCall.get.flatMap { r extractGroupsThenBuildUserFields(jsValue, r.json) }
}
case None {
val jsonGroups: Seq[String] = (jsValue \ groupsAttrName) match {
// Groups received as valid JSON array
case JsDefined(JsArray(groupsList)) groupsList.map(_.as[String]).toList
// Groups list received as string (invalid JSON, for example: "ROLE" or "['Role 1', ROLE2, 'Role_3']")
case JsDefined(JsString(groupsStr)) (new RoleListParser).apply(groupsStr)
// Invalid group list
case JsDefined(error) {
logger.error(s"Invalid groups list received in user info: '${error}' of type ${error.getClass}")
Seq.empty[String]
}
// Groups field is undefined
case _: JsUndefined {
logger.error(s"OAuth2 not configured properly: groups attribute ${groupsAttrName} doesn't exist in user info")
Seq.empty[String]
}
logger.debug(s"Extracting groups from user info")
extractGroupsThenBuildUserFields(jsValue, jsValue)
}
}
}

private def extractGroupsThenBuildUserFields(jsValue: JsValue, groupsContainer: JsValue): Future[Fields] = {
(groupsContainer \ groupsAttrName) match {
// Groups received as valid JSON array
case JsDefined(JsArray(groupsList)) mapGroupsAndBuildUserFields(jsValue, groupsList.map(_.as[String]).toList)

// Groups list received as string (invalid JSON, for example: "ROLE" or "['Role 1', ROLE2, 'Role_3']")
case JsDefined(JsString(groupsStr)) {
val parser = new RoleListParser
parser.parseAll(parser.expr, groupsStr) match {
case parser.Success(result, _) mapGroupsAndBuildUserFields(jsValue, result)
case err: parser.NoSuccess Future.failed(AuthenticationError(s"User info fails: can't parse groups list (${err.msg})"))
}
mapGroupsAndBuildUserFields(jsValue, jsonGroups)
}

// Invalid group list
case JsDefined(error)
Future.failed(AuthenticationError(s"User info fails: invalid groups list received in user info ('${error}' of type ${error.getClass})"))

// Groups field is undefined
case _: JsUndefined
Future.failed(AuthenticationError(s"User info fails: groups attribute ${groupsAttrName} doesn't exist in user info"))
}
}

Expand All @@ -102,18 +100,18 @@ class GroupUserMapper(
val roles = if (mappedRoles.nonEmpty) mappedRoles else defaultRoles

if (roles.isEmpty) {
Future.failed(AuthorizationError(s"No matched roles for user."))
Future.failed(AuthorizationError(s"No matched roles for user"))

} else {
logger.debug(s"Computed roles: ${roles}")
logger.debug(s"Computed roles: ${roles.mkString(", ")}")

val fields = for {
login (jsValue \ loginAttrName).validate[String]
name (jsValue \ nameAttrName).validate[String]
} yield Fields(Json.obj("login" login, "name" name, "roles" roles))
fields match {
case JsSuccess(f, _) Future.successful(f)
case JsError(errors) Future.failed(AuthenticationError(s"User info fails: ${errors.map(_._1).mkString}"))
case JsError(errors) Future.failed(AuthenticationError(s"User info fails: ${errors.map(_._2).map(_.map(_.messages.mkString(", ")).mkString("; ")).mkString}"))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class SimpleUserMapper(
} yield Fields(Json.obj("login" login, "name" name, "roles" roles))
fields match {
case JsSuccess(f, _) Future.successful(f)
case JsError(errors) Future.failed(AuthenticationError(s"User info fails: ${errors.map(_._1).mkString}"))
case JsError(errors) Future.failed(AuthenticationError(s"User info fails: ${errors.map(_._2).map(_.map(_.messages.mkString(", ")).mkString("; ")).mkString}"))
}
}
}

0 comments on commit 5616e38

Please sign in to comment.