Skip to content

Commit

Permalink
Apple Sign In signature for kid
Browse files Browse the repository at this point in the history
  • Loading branch information
Dario Pellegrini committed Nov 22, 2021
1 parent 1ac10a3 commit bef3d2e
Show file tree
Hide file tree
Showing 11 changed files with 36 additions and 28 deletions.
Binary file modified .gradle/buildOutputCleanup/buildOutputCleanup.lock
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ fun Application.installKDone(mongoDatabase: MongoDatabase,
header(HttpHeaders.AcceptLanguage)
header("facebookToken")
header("facebookId")
header("appleToken")
header("appleId")
header("googleToken")
header("googleId")
exposeHeader(HttpHeaders.Authorization)
allowNonSimpleContentTypes = true
anyHost()
Expand All @@ -59,7 +63,7 @@ fun Application.installKDone(mongoDatabase: MongoDatabase,
verifier {
jwtConfig.verifier
}
realm = "kdone.dariopellegrini.com"
realm = jwtConfig.issuer
validate { credentials ->
JWTValidator().validate(credentials)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import com.auth0.jwt.algorithms.Algorithm
import java.util.*

class JWTConfig(private val secret: String,
private val issuer: String = "kdone.com",
val issuer: String = "kdone.com",
private val validityInMs: Long? = null, // 100 hours
private val algorithm: Algorithm = Algorithm.HMAC512(secret)) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,22 @@ import kotlin.reflect.full.isSubclassOf
import kotlin.reflect.jvm.javaField
import kotlin.reflect.jvm.jvmErasure

suspend inline fun <reified T: Any>ApplicationCall.receiveMap(): Map<String, Any> {
val inputMap = this.receive<Map<String, Any>>()
suspend inline fun <reified T: Any>ApplicationCall.receiveMap(): Map<String, Any?> {
val inputMap = this.receive<Map<String, Any?>>()
val kClass = T::class
val propertiesMap = kClass.declaredMemberProperties.map {
it.name to it
}.toMap()

val resultMap = mutableMapOf<String, Any>()
val resultMap = mutableMapOf<String, Any?>()

inputMap.forEach { entry ->
val key = entry.key
val value = entry.value
val property = propertiesMap[key] ?: throw IOException("$key not found for class $kClass")

when {
value == null -> resultMap[key] = null
entry.value is Map<*, *> -> {
val element = ObjectMapper().configureForKDone().convertValue(entry.value, property.returnType.jvmErasure.java)
resultMap[key] = element
Expand Down Expand Up @@ -73,7 +74,7 @@ suspend inline fun <reified T: Any>ApplicationCall.receiveMap(): Map<String, Any
suspend inline fun <reified T: Any>ApplicationCall.receiveMultipartMap(
uploader: Uploader,
addUnknown: List<String> = listOf(),
beforeUpload: (Map<String, Any>) -> Unit = {}): Map<String, Any> {
beforeUpload: (Map<String, Any>) -> Unit = {}): Map<String, Any?> {

val parts = this@receiveMultipartMap.receiveMultipart().readAllParts()

Expand Down Expand Up @@ -152,13 +153,13 @@ suspend inline fun <reified T: Any>ApplicationCall.receiveMultipartMap(
return resultMap
}

suspend fun <T: Any>ApplicationCall.receiveMap(kClass: KClass<T>): Map<String, Any> {
suspend fun <T: Any>ApplicationCall.receiveMap(kClass: KClass<T>): Map<String, Any?> {
val inputMap = this.receive<Map<String, Any>>()
val propertiesMap = kClass.declaredMemberProperties.map {
it.name to it
}.toMap()

val resultMap = mutableMapOf<String, Any>()
val resultMap = mutableMapOf<String, Any?>()

inputMap.forEach { entry ->
val key = entry.key
Expand All @@ -167,6 +168,7 @@ suspend fun <T: Any>ApplicationCall.receiveMap(kClass: KClass<T>): Map<String, A


when {
value == null -> resultMap[key] = null
entry.value is Map<*, *> -> {
val element = ObjectMapper().configureForKDone().convertValue(entry.value, property.returnType.jvmErasure.java)
resultMap[key] = element
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import com.dariopellegrini.kdone.exceptions.MapCheckException
import kotlin.reflect.full.memberProperties
import kotlin.reflect.jvm.jvmErasure

inline fun <reified T: Any> Map<String, Any>.checkWithType() {
inline fun <reified T: Any> Map<String, Any?>.checkWithType() {
val kClass = T::class
val parametersMap = kClass.memberProperties.associateBy { it.name }
this.forEach {
Expand All @@ -13,6 +13,6 @@ inline fun <reified T: Any> Map<String, Any>.checkWithType() {
val value = entry.value
val property = parametersMap[key] ?: throw MapCheckException("Parameter $key is not present $kClass")

if (property.returnType.jvmErasure != value::class) throw MapCheckException("Parameter $key is not compatible with $kClass")
if (value != null && property.returnType.jvmErasure != value::class) throw MapCheckException("Parameter $key is not compatible with $kClass")
}
}
}
2 changes: 1 addition & 1 deletion src/main/kotlin/com/dariopellegrini/kdone/routes/Module.kt
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ inline fun <reified T : Any>Route.module(endpoint: String,
}
webSocketController?.update(updatedElement, call.userAuthOrNull)
} catch (e: Exception) {
call.respondWithException(e)
// call.respondWithException(e)
configuration.exceptionHandler?.invoke(call, e)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ class RouteConfiguration<T: Any> {
var beforeGet: (suspend (ApplicationCall, Map<String, Any>) -> Unit)? = null
var afterGet: (suspend (ApplicationCall, Map<String, Any>, List<T>) -> Unit)? = null

var beforeUpdate: (suspend (ApplicationCall, Id<T>, Map<String, Any>) -> Unit)? = null
var afterUpdate: (suspend (ApplicationCall, Map<String, Any>, T) -> Unit)? = null
var beforeUpdate: (suspend (ApplicationCall, Id<T>, Map<String, Any?>) -> Unit)? = null
var afterUpdate: (suspend (ApplicationCall, Map<String, Any?>, T) -> Unit)? = null

var beforeDelete: (suspend (ApplicationCall, Id<T>) -> Unit)? = null
var afterDelete: (suspend (ApplicationCall, DeleteResult) -> Unit)? = null
Expand Down Expand Up @@ -76,11 +76,11 @@ class RouteConfiguration<T: Any> {
afterGet = closure
}

fun beforeUpdate(closure: suspend (ApplicationCall, Id<T>, Map<String, Any>) -> Unit) {
fun beforeUpdate(closure: suspend (ApplicationCall, Id<T>, Map<String, Any?>) -> Unit) {
beforeUpdate = closure
}

fun afterUpdate(closure: suspend (ApplicationCall, Map<String, Any>, T) -> Unit) {
fun afterUpdate(closure: suspend (ApplicationCall, Map<String, Any?>, T) -> Unit) {
afterUpdate = closure
}

Expand Down
13 changes: 7 additions & 6 deletions src/main/kotlin/com/dariopellegrini/kdone/startup/Startup.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.mongodb.ConnectionString
import com.mongodb.MongoClientSettings
import com.mongodb.client.MongoDatabase
import com.mongodb.connection.SslSettings
import io.ktor.features.*
import io.ktor.routing.Route
import io.ktor.server.engine.embeddedServer
import io.ktor.server.netty.Netty
Expand Down Expand Up @@ -37,12 +38,12 @@ fun startKDone(port: Int,
jwtConfig: JWTConfig,
closure: Route.() -> Unit) {
embeddedServer(Netty, port) {
val settings = MongoClientSettings.builder()
.applyConnectionString(ConnectionString(mongoURL))
.applyToSslSettings {
builder: SslSettings.Builder -> builder.enabled(true).invalidHostNameAllowed(true)
}
.build()
// val settings = MongoClientSettings.builder()
// .applyConnectionString(ConnectionString(mongoURL))
// .applyToSslSettings {
// builder: SslSettings.Builder -> builder.enabled(true).invalidHostNameAllowed(true)
// }
// .build()
val client = KMongo.createClient(mongoURL)
installKDone(client.getDatabase(databaseName),
jwtConfig,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ inline fun <reified T : KDoneUser>Route.userModule(endpoint: String = "users",
if (!configuration.authorization.checkOwner(update)) throw NotAuthorizedException()
call.checkToken(this@authenticate.database)

val patch: Map<String, Any> = if (call.request.isMultipart()) {
val patch: Map<String, Any?> = if (call.request.isMultipart()) {
val uploader = configuration.uploader ?: throw ServerException(500, "Uploader not configured")
call.receiveMultipartMap<T>(uploader) { map ->
ownerForbiddenAttributes.forEach {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ open class UserRouteConfiguration<T: KDoneUser> {
var beforeGet: (suspend (ApplicationCall, Map<String, Any>) -> Unit)? = null
var afterGet: (suspend (ApplicationCall, Map<String, Any>, List<T>) -> Unit)? = null

var beforeUpdate: (suspend (ApplicationCall, Id<T>, Map<String, Any>) -> Unit)? = null
var afterUpdate: (suspend (ApplicationCall, Map<String, Any>, T) -> Unit)? = null
var beforeUpdate: (suspend (ApplicationCall, Id<T>, Map<String, Any?>) -> Unit)? = null
var afterUpdate: (suspend (ApplicationCall, Map<String, Any?>, T) -> Unit)? = null

var beforeDelete: (suspend (ApplicationCall, Id<T>) -> Unit)? = null
var afterDelete: (suspend (ApplicationCall, DeleteResult) -> Unit)? = null
Expand Down Expand Up @@ -116,11 +116,11 @@ open class UserRouteConfiguration<T: KDoneUser> {
afterGet = closure
}

fun beforeUpdate(closure: suspend (ApplicationCall, Id<T>, Map<String, Any>) -> Unit) {
fun beforeUpdate(closure: suspend (ApplicationCall, Id<T>, Map<String, Any?>) -> Unit) {
beforeUpdate = closure
}

fun afterUpdate(closure: suspend (ApplicationCall, Map<String, Any>, T) -> Unit) {
fun afterUpdate(closure: suspend (ApplicationCall, Map<String, Any?>, T) -> Unit) {
afterUpdate = closure
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,8 @@ suspend fun checkAppleToken(appleToken: String, appleId: String, bundleId: Strin

override fun getPublicKeyById(kid: String): RSAPublicKey {
val provider = UrlJwkProvider("https://appleid.apple.com/auth/keys/")
val jwk = provider.all.first()
val list = provider.all
val jwk = list.first { it.id == kid }
return jwk.publicKey as RSAPublicKey
}
}
Expand Down

0 comments on commit bef3d2e

Please sign in to comment.