-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Zoe Maas
committed
Oct 9, 2024
1 parent
6bfd979
commit bb5f34d
Showing
7 changed files
with
295 additions
and
15 deletions.
There are no files selected for viewing
40 changes: 40 additions & 0 deletions
40
...deration-common/src/commonMain/kotlin/com/sphereon/oid/fed/common/jwt/ICallbackService.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package com.sphereon.oid.fed.common.jwt | ||
|
||
/** | ||
* The main object used by code to be calling into the platform specific callbacks for signature creation/verification | ||
* | ||
* Non Kotlin code could still extend their implementations. This object is available directly as well except for JS, which has to use its actual implementations this service depends on | ||
*/ | ||
|
||
object JwtService { | ||
val JWT = jwtService() | ||
} | ||
|
||
/** | ||
* 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(): PlatformCallbackType | ||
|
||
/** | ||
* Enable the callback verification (default) | ||
*/ | ||
fun enable(): PlatformCallbackType | ||
|
||
|
||
/** | ||
* Is the service enabled or not | ||
*/ | ||
fun isEnabled(): Boolean | ||
|
||
/** | ||
* Register the platform specific callback that implements the verification | ||
* | ||
* External developers use this as an entry point for their platform code | ||
*/ | ||
fun register(platformCallback: PlatformCallbackType): ICallbackService<PlatformCallbackType> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletions
9
...penid-federation-common/src/commonMain/kotlin/com/sphereon/oid/fed/common/jwt/JwtConst.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package com.sphereon.oid.fed.common.jwt | ||
|
||
import com.sphereon.oid.fed.common.logging.Logger | ||
|
||
object JwtConst { | ||
val LOG_NAMESPACE = "sphereon:kmp:openid-federation-common" | ||
val LOG = Logger.Static.tag(LOG_NAMESPACE) | ||
val JWT_LITERAL = "JWT" | ||
} |
25 changes: 17 additions & 8 deletions
25
...nid-federation-common/src/commonMain/kotlin/com/sphereon/oid/fed/common/logging/Logger.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,35 @@ | ||
package com.sphereon.oid.fed.common.logging | ||
|
||
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("") |
45 changes: 45 additions & 0 deletions
45
...federation-common/src/jsMain/kotlin/com/sphereon/oid/fed/common/jwt/ICallbackServiceJS.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package com.sphereon.oid.fed.common.jwt | ||
|
||
/** | ||
* The main object used by code to be calling into the platform specific callbacks for signature creation/verification | ||
* | ||
* Non Kotlin code could still extend their implementations. This object is available directly as well except for JS, which has to use its actual implementations this service depends on | ||
*/ | ||
|
||
@ExperimentalJsExport | ||
@JsExport | ||
object JwtServiceJS { | ||
val JWT = jwtService() | ||
} | ||
|
||
/** | ||
* The main entry point for platform validation, delegating to a platform specific callback implemented by external developers | ||
*/ | ||
|
||
@ExperimentalJsExport | ||
@JsExport | ||
interface ICallbackServiceJS<PlatformCallbackType> { | ||
/** | ||
* Disable callback verification (be careful!) | ||
*/ | ||
fun disable(): PlatformCallbackType | ||
|
||
/** | ||
* Enable the callback verification (default) | ||
*/ | ||
fun enable(): PlatformCallbackType | ||
|
||
|
||
/** | ||
* Is the service enabled or not | ||
*/ | ||
fun isEnabled(): Boolean | ||
|
||
/** | ||
* Register the platform specific callback that implements the verification | ||
* | ||
* External developers use this as an entry point for their platform code | ||
*/ | ||
@JsName("register") | ||
fun register(platformCallback: PlatformCallbackType): ICallbackServiceJS<PlatformCallbackType> | ||
} |
120 changes: 120 additions & 0 deletions
120
...enid-federation-common/src/jsMain/kotlin/com/sphereon/oid/fed/common/jwt/JwtService.js.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
package com.sphereon.oid.fed.common.jwt | ||
|
||
import kotlinx.coroutines.await | ||
import kotlin.js.Promise | ||
|
||
@ExperimentalJsExport | ||
@JsExport | ||
interface IJwtServiceJS { | ||
fun sign(input: JwtSignInput): Promise<String> | ||
fun verify(input: JwtVerifyInput): Promise<Boolean> | ||
} | ||
|
||
@ExperimentalJsExport | ||
@JsExport | ||
interface JwtCallbackServiceJS: ICallbackService<IJwtServiceJS>, IJwtServiceJS | ||
|
||
@ExperimentalJsExport | ||
@JsExport | ||
object JwtServiceObjectJS: JwtCallbackServiceJS { | ||
|
||
private lateinit var platformCallback: IJwtServiceJS | ||
|
||
private var disabled = false; | ||
|
||
override fun disable(): IJwtServiceJS { | ||
this.disabled = true | ||
return this | ||
} | ||
|
||
override fun enable(): IJwtServiceJS { | ||
this.disabled = false | ||
return this | ||
} | ||
|
||
override fun isEnabled(): Boolean { | ||
return !this.disabled | ||
} | ||
|
||
override fun register(platformCallback: IJwtServiceJS): JwtCallbackServiceJS { | ||
this.platformCallback = platformCallback | ||
return this | ||
} | ||
|
||
|
||
override fun sign(input: JwtSignInput): Promise<String> { | ||
if (!isEnabled()) { | ||
JwtConst.LOG.info("JWT sign has been disabled") | ||
throw IllegalStateException("JWT sign is disabled cannot sign") | ||
} else if (!this::platformCallback.isInitialized) { | ||
JwtConst.LOG.info("JWT callback (JS) is not registered") | ||
throw IllegalStateException("JWT have not been initialized. Please register your JWTCallbackJS, or a default implementation") | ||
} | ||
return platformCallback.sign(input) | ||
} | ||
|
||
override fun verify(input: JwtVerifyInput): Promise<Boolean> { | ||
if (!isEnabled()) { | ||
JwtConst.LOG.info("JWT verify has been disabled") | ||
throw IllegalStateException("JWT verify is disabled cannot sign") | ||
} else if (!this::platformCallback.isInitialized) { | ||
JwtConst.LOG.info("JWT callback (JS) is not registered") | ||
throw IllegalStateException("JWT have not been initialized. Please register your JWTCallbackJS, or a default implementation") | ||
} | ||
return platformCallback.verify(input) | ||
} | ||
} | ||
|
||
open class JwtServiceJSAdapter @OptIn(ExperimentalJsExport::class) constructor(val jwtcallbackJS: JwtServiceObjectJS = JwtServiceObjectJS): | ||
JwtCallbackService { | ||
@OptIn(ExperimentalJsExport::class) | ||
override fun disable(): IJwtService { | ||
this.jwtcallbackJS.disable() | ||
return this | ||
} | ||
|
||
@OptIn(ExperimentalJsExport::class) | ||
override fun enable(): IJwtService { | ||
this.jwtcallbackJS.enable() | ||
return this | ||
} | ||
|
||
@OptIn(ExperimentalJsExport::class) | ||
override fun isEnabled(): Boolean { | ||
return this.jwtcallbackJS.isEnabled() | ||
} | ||
|
||
override fun register(platformCallback: IJwtService): ICallbackService<IJwtService> { | ||
throw Error("Register function should not be used on the adapter. It depends on the Javascript jwtService object") | ||
} | ||
|
||
@OptIn(ExperimentalJsExport::class) | ||
override suspend fun sign(input: JwtSignInput): String { | ||
JwtConst.LOG.error("Creating JWT sign signature...") | ||
return try { | ||
this.jwtcallbackJS.sign(input).await() | ||
} catch (e: Exception) { | ||
throw e | ||
}.also { | ||
JwtConst.LOG.error("Created JWT sign signature: $it") | ||
} | ||
} | ||
|
||
@OptIn(ExperimentalJsExport::class) | ||
override suspend fun verify(input: JwtVerifyInput): Boolean { | ||
JwtConst.LOG.error("Verifying JWT signature...") | ||
return try { | ||
this.jwtcallbackJS.verify(input).await() | ||
} catch (e: Exception) { | ||
throw e | ||
}.also { | ||
JwtConst.LOG.error("Verified JWT signature: $it") | ||
} | ||
} | ||
|
||
} | ||
|
||
@OptIn(ExperimentalJsExport::class) | ||
object JWTServiceJSAdapterObject: JwtServiceJSAdapter(JwtServiceObjectJS) | ||
|
||
actual fun jwtService(): JwtCallbackService = JWTServiceJSAdapterObject |
3 changes: 3 additions & 0 deletions
3
...id-federation-common/src/jvmMain/kotlin/com/sphereon/oid/fed/common/jwt/JwtService.jvm.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package com.sphereon.oid.fed.common.jwt | ||
|
||
actual fun jwtService(): JwtCallbackService = JwtServiceObject |