Skip to content

Commit

Permalink
refactor: Refactored OIDF-Client according to mdoc-cbor-crypto-multip…
Browse files Browse the repository at this point in the history
…latform
  • Loading branch information
Zoe Maas committed Oct 24, 2024
1 parent f4d4a9f commit bebef87
Show file tree
Hide file tree
Showing 16 changed files with 423 additions and 162 deletions.
Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
package com.sphereon.oid.fed.common.logging
package com.sphereon.oid.fed.logger

import co.touchlab.kermit.Logger
import co.touchlab.kermit.Severity

object Logger {

fun verbose(tag: String, message: String) {
class Logger(val tag: String = "") {
fun verbose(message: String, tag: String = this.tag) {
Logger.v(tag = tag, messageString = message)
}

fun debug(tag: String, message: String) {
fun debug(message: String, tag: String = this.tag) {
Logger.d(tag = tag, messageString = message)
}

fun info(tag: String, message: String) {
fun info(message: String, tag: String = this.tag) {
Logger.i(tag = tag, messageString = message)
}

fun warn(tag: String, message: String) {
fun warn(message: String, tag: String = this.tag) {
Logger.w(tag = tag, messageString = message)
}

fun error(tag: String, message: String, throwable: Throwable? = null) {
fun error(message: String, throwable: Throwable? = null, tag: String = this.tag) {
Logger.e(tag = tag, messageString = message, throwable = throwable)
}

fun setMinSeverity(severity: Severity) = Logger.setMinSeverity(severity)

object Static {
fun tag(tag: String = "", severity: Severity = Severity.Info) = Logger(tag).also { it.setMinSeverity(severity) }
}

}

val DefaultLogger = Logger("")
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
package com.sphereon.oid.fed.client

import com.sphereon.oid.fed.client.crypto.CryptoServiceObject
import com.sphereon.oid.fed.client.crypto.ICryptoService
import com.sphereon.oid.fed.client.fetch.FetchServiceObject
import com.sphereon.oid.fed.client.fetch.IFetchService
import com.sphereon.oid.fed.client.crypto.ICryptoCallbackMarkerType
import com.sphereon.oid.fed.client.fetch.IFetchCallbackMarkerType
import com.sphereon.oid.fed.client.trustchain.TrustChain

class FederationClient(fetchServiceCallback: IFetchService?, cryptoServiceCallback: ICryptoService) {
private val fetchService = FetchServiceObject.register(fetchServiceCallback)
private val cryptoService = CryptoServiceObject.register(cryptoServiceCallback)
private val trustChainService = TrustChain(fetchService, cryptoService)
class FederationClient(fetchServiceCallback: IFetchCallbackMarkerType?, cryptoServiceCallback: ICryptoCallbackMarkerType) {
private val trustChainService = TrustChain(fetchServiceCallback, cryptoServiceCallback)

suspend fun resolveTrustChain(entityIdentifier: String, trustAnchors: Array<String>): MutableList<String>? {
return trustChainService.resolve(entityIdentifier, trustAnchors)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,48 +1,102 @@
package com.sphereon.oid.fed.client.crypto

import com.sphereon.oid.fed.client.mapper.decodeJWTComponents
import com.sphereon.oid.fed.client.types.ICallbackService
import com.sphereon.oid.fed.client.service.DefaultCallbacks
import com.sphereon.oid.fed.client.service.ICallbackService
import com.sphereon.oid.fed.openapi.models.Jwk
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import kotlin.js.JsExport

interface ICryptoService {
expect interface ICryptoCallbackMarkerType
interface ICryptoMarkerType

@JsExport.Ignore
interface ICryptoCallbackService: ICryptoCallbackMarkerType {
suspend fun verify(
jwt: String,
key: Jwk,
): Boolean
}

interface ICryptoCallbackService : ICallbackService<ICryptoService>, ICryptoService
@JsExport.Ignore
interface ICryptoService: ICryptoMarkerType {
suspend fun verify(
jwt: String,
key: Jwk,
): Boolean
}

class DefaultPlatformCallback : ICryptoService {
override suspend fun verify(jwt: String, key: Jwk): Boolean {
return verifyImpl(jwt, key)
expect fun cryptoService(platformCallback: ICryptoCallbackMarkerType = DefaultCallbacks.jwtService()): ICryptoService

abstract class AbstractCryptoService<CallbackServiceType>(open val platformCallback: CallbackServiceType?): ICallbackService<CallbackServiceType> {
private var disabled = false

override fun isEnabled(): Boolean {
return !this.disabled
}
}

object CryptoServiceObject : ICryptoCallbackService {
private lateinit var platformCallback: ICryptoService
override fun disable() = apply {
this.disabled = true
}

override suspend fun verify(jwt: String, key: Jwk): Boolean {
if (!::platformCallback.isInitialized) {
throw IllegalStateException("CryptoServiceObject not initialized")
override fun enable() = apply {
this.disabled = false
}

protected fun assertEnabled() {
if (!isEnabled()) {
//CryptoConst.LOG.info("CRYPTO verify has been disabled")
throw IllegalStateException("CRYPTO service is disable; cannot verify")
} else if (this.platformCallback == null) {
//CryptoConst.LOG.error("CRYPTO callback is not registered")
throw IllegalStateException("CRYPTO has not been initialized. Please register your CryptoCallback implementation, or register a default implementation")
}
return platformCallback.verify(jwt, key)
}
}

class CryptoService(override val platformCallback: ICryptoCallbackService = DefaultCallbacks.jwtService()): AbstractCryptoService<ICryptoCallbackService>(platformCallback), ICryptoService {
override fun platform(): ICryptoCallbackService {
return this.platformCallback
}

override fun register(platformCallback: ICryptoService?): ICryptoCallbackService {
this.platformCallback = platformCallback ?: DefaultPlatformCallback()
return this
override suspend fun verify(jwt: String, key: Jwk): Boolean {
return this.platformCallback.verify(jwt, key)
}

}

expect fun cryptoService(): ICryptoCallbackService
// ###########################################################################


//class DefaultPlatformCallback : ICryptoCallbackService {
// override suspend fun verify(jwt: String, key: Jwk): Boolean {
// return verifyImpl(jwt, key)
// }
//}
//
//object CryptoServiceObject : ICryptoCallbackService {
// private lateinit var platformCallback: ICryptoCallbackService
//
// override suspend fun verify(jwt: String, key: Jwk): Boolean {
// if (!::platformCallback.isInitialized) {
// throw IllegalStateException("CryptoServiceObject not initialized")
// }
// return platformCallback.verify(jwt, key)
// }
//
// override fun register(platformCallback: ICryptoCallbackService?): ICryptoCallbackService {
// this.platformCallback = platformCallback ?: DefaultPlatformCallback()
// return this
// }
//}

expect suspend fun verifyImpl(jwt: String, key: Jwk): Boolean
//expect fun cryptoService(): ICryptoCallbackService
//
//expect suspend fun verifyImpl(jwt: String, key: Jwk): Boolean

fun findKeyInJwks(keys: JsonArray, kid: String): Jwk? {
val key = keys.firstOrNull { it.jsonObject["kid"]?.jsonPrimitive?.content?.trim() == kid.trim() }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.sphereon.oid.fed.client.crypto

//import com.sphereon.oid.fed.logger

object CryptoConst {
// val LOG_NAMESPACE = "sphereon:oidf:client:crypto"
// val LOG = Logger.Static.tag(LOG_NAMESPACE)
// val CRYPTO_LITERAL = "CRYPTO"
}
Original file line number Diff line number Diff line change
@@ -1,50 +1,68 @@
package com.sphereon.oid.fed.client.fetch

import com.sphereon.oid.fed.client.types.ICallbackService
import com.sphereon.oid.fed.client.service.DefaultCallbacks
import com.sphereon.oid.fed.client.service.ICallbackService
import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.request.*
import io.ktor.http.*
import kotlin.js.JsExport

expect interface IFetchCallbackMarkerType
interface IFetchMarkerType

interface IFetchService {
fun getHttpClient(): HttpClient
@JsExport.Ignore
interface IFetchCallbackService: IFetchCallbackMarkerType {
suspend fun fetchStatement(
endpoint: String
): String
suspend fun getHttpClient(): HttpClient
}

interface IFetchServiceInternal {
@JsExport.Ignore
interface IFetchService: IFetchMarkerType {
suspend fun fetchStatement(
endpoint: String
): String
suspend fun getHttpClient(): HttpClient
}

interface IFetchCallbackService : ICallbackService<IFetchService>, IFetchService, IFetchServiceInternal
expect fun fetchService(platformCallback: IFetchCallbackMarkerType = DefaultCallbacks.fetchService()): IFetchService

object FetchServiceObject : IFetchCallbackService {
private lateinit var platformCallback: IFetchService
private lateinit var httpClient: HttpClient
abstract class AbstractFetchService<CallbackServiceType>(open val platformCallback: CallbackServiceType): ICallbackService<CallbackServiceType> {
private var disabled = false

override suspend fun fetchStatement(endpoint: String): String {
return httpClient
.get(endpoint) {
headers {
append(HttpHeaders.Accept, "application/entity-statement+jwt")
}
}.body()
override fun isEnabled(): Boolean {
return !this.disabled
}

override fun getHttpClient(): HttpClient {
return this.platformCallback.getHttpClient()
override fun disable() = apply {
this.disabled = true
}

override fun enable() = apply {
this.disabled = false
}

class DefaultPlatformCallback : IFetchService {
override fun getHttpClient(): HttpClient {
return HttpClient()
protected fun assertEnabled() {
if (!isEnabled()) {
//FetchConst.LOG.info("CRYPTO verify has been disabled")
throw IllegalStateException("CRYPTO service is disable; cannot verify")
} else if (this.platformCallback == null) {
//FetchConst.LOG.error("CRYPTO callback is not registered")
throw IllegalStateException("CRYPTO has not been initialized. Please register your CryptoCallback implementation, or register a default implementation")
}
}
}

override fun register(platformCallback: IFetchService?): IFetchCallbackService {
this.platformCallback = platformCallback ?: DefaultPlatformCallback()
this.httpClient = this.platformCallback.getHttpClient()
return this
class FetchService(override val platformCallback: IFetchCallbackService = DefaultCallbacks.jwtService()): AbstractFetchService<IFetchCallbackService>(platformCallback), IFetchService {

override fun platform(): IFetchCallbackService {
return this.platformCallback
}

override suspend fun fetchStatement(endpoint: String): String {
return this.platformCallback.fetchStatement(endpoint)
}

override suspend fun getHttpClient(): HttpClient {
return this.platformCallback.getHttpClient()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.sphereon.oid.fed.client.fetch

//import com.sphereon.oid.fed.logger

object FetchConst {
// val LOG_NAMESPACE = "sphereon:oidf:client:crypto"
// val LOG = Logger.Static.tag(LOG_NAMESPACE)
// val FETCH_LITERAL = "FETCH"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.sphereon.oid.fed.client.service

import com.sphereon.oid.fed.client.crypto.ICryptoCallbackMarkerType
import com.sphereon.oid.fed.client.fetch.IFetchCallbackMarkerType
import kotlin.js.JsExport

@JsExport
object DefaultCallbacks {
private var cryptoCallbackService: ICryptoCallbackMarkerType? = null
private var fetchCallbackService: IFetchCallbackMarkerType? = null

fun <CallbackType: ICryptoCallbackMarkerType> jwtService(): CallbackType {
if (cryptoCallbackService == null) {
throw IllegalStateException("No default Crypto Platform Callback implementation was registered")
}
return cryptoCallbackService as CallbackType
}

fun setCryptoServiceDefault(cryptoCallbackService: ICryptoCallbackMarkerType?) {
this.cryptoCallbackService = cryptoCallbackService
}

fun <CallbackType: IFetchCallbackMarkerType> fetchService(): CallbackType {
if (fetchCallbackService == null) {
throw IllegalStateException("No default Crypto Platform Callback implementation was registered")
}
return fetchCallbackService as CallbackType
}

fun setFetchServiceDefault(fetchCallbackService: IFetchCallbackMarkerType?) {
this.fetchCallbackService = fetchCallbackService
}
}

/**
* The main entry point for platform validation, delegating to a platform specific callback implemented by external developers
*/

interface ICallbackService<PlatformCallbackType> {

/**
* Disable callback verification (be careful!)
*/
fun disable(): ICallbackService<PlatformCallbackType>

/**
* Enable the callback verification (default)
*/
fun enable(): ICallbackService<PlatformCallbackType>

/**
* Is the service enabled or not
*/
fun isEnabled(): Boolean

fun platform(): PlatformCallbackType
}
Loading

0 comments on commit bebef87

Please sign in to comment.