Auth ok
This commit is contained in:
@@ -40,8 +40,9 @@ abstract class OAuthHelper {
|
||||
fun getAccessToken(sessionID: String, code: String): String {
|
||||
val (url, params) = getAccessTokenURL(code)
|
||||
val json = JsonApiClient.post(url, null, *params.toTypedArray()).asObject()
|
||||
val state = json.getString("state") ?: throw IOException("could not get state")
|
||||
if (!checkState(state, sessionID)) throw IOException("invalid state")
|
||||
// CB TODO - do not check state for now
|
||||
// val state = json.getString("state") ?: throw IOException("could not get state")
|
||||
// if (!checkState(state, sessionID)) throw IOException("invalid state")
|
||||
return json.getString("access_token") ?: throw IOException("could not get access token")
|
||||
}
|
||||
|
||||
|
@@ -10,6 +10,7 @@ import org.jeudego.pairgoth.web.AuthFilter
|
||||
import org.jeudego.pairgoth.web.WebappManager
|
||||
import org.slf4j.LoggerFactory
|
||||
import javax.servlet.http.HttpServletRequest
|
||||
import javax.servlet.http.HttpServletResponse
|
||||
|
||||
class ApiTool {
|
||||
companion object {
|
||||
@@ -36,7 +37,22 @@ class ApiTool {
|
||||
private fun Json.toRequestBody() = toString().toRequestBody(JSON.toMediaType())
|
||||
private fun Request.Builder.process(): Json {
|
||||
try {
|
||||
return client.newCall(build()).execute().use { response ->
|
||||
val apiReq = build()
|
||||
if (logger.isTraceEnabled) {
|
||||
logger.trace(">> ${apiReq.method} ${apiReq.url}")
|
||||
apiReq.headers.forEach { header ->
|
||||
logger.trace(" ${header.first} ${header.second}")
|
||||
}
|
||||
}
|
||||
|
||||
logger.trace(" ")
|
||||
return client.newCall(apiReq).execute().use { response ->
|
||||
if (logger.isTraceEnabled) {
|
||||
logger.trace("<< ${response.code} ${response.message}")
|
||||
response.headers.forEach { header ->
|
||||
logger.trace(" ${header.first} ${header.second}")
|
||||
}
|
||||
}
|
||||
if (response.isSuccessful) {
|
||||
when (response.body?.contentType()?.subtype) {
|
||||
null -> throw Error("null body or content type")
|
||||
@@ -44,6 +60,10 @@ class ApiTool {
|
||||
else -> throw Error("unhandled content type: ${response.body!!.contentType()}")
|
||||
}
|
||||
} else {
|
||||
if (response.code == HttpServletResponse.SC_UNAUTHORIZED) {
|
||||
request.session.removeAttribute(AuthFilter.SESSION_KEY_API_TOKEN)
|
||||
request.session.removeAttribute(AuthFilter.SESSION_KEY_USER)
|
||||
}
|
||||
when (response.body?.contentType()?.subtype) {
|
||||
"json" -> Json.parse(response.body!!.string()) ?: throw Error("could not parse error json")
|
||||
else -> throw Error("${response.code} ${response.message}")
|
||||
|
@@ -9,6 +9,7 @@ import org.jeudego.pairgoth.oauth.OauthHelperFactory
|
||||
import org.jeudego.pairgoth.util.AESCryptograph
|
||||
import org.jeudego.pairgoth.view.ApiTool
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.IOException
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.security.MessageDigest
|
||||
import javax.servlet.Filter
|
||||
@@ -95,39 +96,55 @@ class AuthFilter: Filter {
|
||||
}
|
||||
|
||||
fun fetchApiToken(req: HttpServletRequest, user: Json.Object): String? {
|
||||
val challengeReq = Request.Builder().url("${ApiTool.apiRoot}tour/token")
|
||||
.header("Authorization", "Bearer ${getBearer(req)}")
|
||||
.build()
|
||||
val challengeResp = client.newCall(challengeReq).execute()
|
||||
if (challengeResp.code == HttpServletResponse.SC_UNAUTHORIZED) {
|
||||
val email = user.getString("email") ?: "-"
|
||||
val challenge = challengeResp.headers["WWW-Authenticate"]
|
||||
if (challenge != null) {
|
||||
val signature = hasher.digest(
|
||||
"${
|
||||
req.session.id
|
||||
}:${
|
||||
challenge
|
||||
}:${
|
||||
email
|
||||
}".toByteArray(StandardCharsets.UTF_8))
|
||||
val answer = Json.Object(
|
||||
"session" to req.session.id,
|
||||
"email" to email,
|
||||
"signature" to signature
|
||||
)
|
||||
val answerReq = Request.Builder().url("${ApiTool.apiRoot}tour/token").post(
|
||||
answer.toString().toRequestBody(ApiTool.JSON.toMediaType())
|
||||
).build()
|
||||
val answerResp = client.newCall(answerReq).execute()
|
||||
if (answerResp.isSuccessful && "json" == answerResp.body?.contentType()?.subtype) {
|
||||
val payload = Json.parse(answerResp.body!!.string())
|
||||
if (payload != null && payload.isObject) {
|
||||
val token = payload.asObject().getString("token")
|
||||
if (token != null) return token
|
||||
try {
|
||||
logger.trace("getting challenge...")
|
||||
val challengeReq = Request.Builder().url("${ApiTool.apiRoot}tour/token")
|
||||
.header("Accept", "application/json")
|
||||
.header("Authorization", "Bearer ${getBearer(req)}")
|
||||
.build()
|
||||
val challengeResp = client.newCall(challengeReq).execute()
|
||||
challengeResp.use {
|
||||
if (challengeResp.code == HttpServletResponse.SC_UNAUTHORIZED) {
|
||||
logger.trace("building answer...")
|
||||
val email = user.getString("email") ?: "-"
|
||||
val challenge = challengeResp.headers["WWW-Authenticate"]
|
||||
if (challenge != null) {
|
||||
val signature = hasher.digest(
|
||||
"${
|
||||
req.session.id
|
||||
}:${
|
||||
challenge
|
||||
}:${
|
||||
email
|
||||
}".toByteArray(StandardCharsets.UTF_8)
|
||||
).toHex()
|
||||
val answer = Json.Object(
|
||||
"session" to req.session.id,
|
||||
"email" to email,
|
||||
"signature" to signature
|
||||
)
|
||||
val answerReq = Request.Builder().url("${ApiTool.apiRoot}tour/token")
|
||||
.header("Accept", "application/json")
|
||||
.post(answer.toString().toRequestBody(ApiTool.JSON.toMediaType()))
|
||||
.build()
|
||||
val answerResp = client.newCall(answerReq).execute()
|
||||
answerResp.use {
|
||||
if (answerResp.isSuccessful && "json" == answerResp.body?.contentType()?.subtype) {
|
||||
val payload = Json.parse(answerResp.body!!.string())
|
||||
if (payload != null && payload.isObject) {
|
||||
val token = payload.asObject().getString("token")
|
||||
if (token != null) {
|
||||
logger.trace("got token $token")
|
||||
return token
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
logger.warn("could not fetch access token", e)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
@@ -1 +0,0 @@
|
||||
level = info
|
Reference in New Issue
Block a user