Skip to content

Commit

Permalink
add well known endpoints.
Browse files Browse the repository at this point in the history
  • Loading branch information
uakihir0 committed Oct 3, 2024
1 parent 4ce8b8d commit 44e798e
Show file tree
Hide file tree
Showing 9 changed files with 232 additions and 0 deletions.
3 changes: 3 additions & 0 deletions core/src/commonMain/kotlin/work/socialhub/kbsky/ATProtocol.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ package work.socialhub.kbsky
import work.socialhub.kbsky.api.com.atproto.IdentityResource
import work.socialhub.kbsky.api.com.atproto.RepoResource
import work.socialhub.kbsky.api.com.atproto.ServerResource
import work.socialhub.kbsky.api.meta.MetaResource

interface ATProtocol {
fun identity(): IdentityResource
fun server(): ServerResource
fun repo(): RepoResource

fun meta(): MetaResource
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,19 @@ open class ATProtocolConfig {
*/
var pdsUri: String = Service.BSKY_SOCIAL.uri

/**
* URI of authorization server.
*/
var authUri: String = Service.BSKY_SOCIAL.uri

/**
* Change the URI to the PDS to which you belong when requesting a session-based API?
* (If you use the Chat feature, you will need to change the URI to the PDS you belong to if you turn it off)
*/
var updatePdsUri: Boolean = true

/**
* Update AuthURI when retrieving Meta resources?
*/
var updateAuthUri: Boolean = true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package work.socialhub.kbsky.api.entity.meta

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
class WellKnownOAuthAuthorizationServer {

@SerialName("issuer")
lateinit var issuer: String

@SerialName("scopes_supported")
lateinit var scopesSupported: List<String>

@SerialName("subject_types_supported")
lateinit var subjectTypesSupported: List<String>

@SerialName("response_types_supported")
lateinit var responseTypesSupported: List<String>

@SerialName("response_modes_supported")
lateinit var responseModesSupported: List<String>

@SerialName("grant_types_supported")
lateinit var grantTypesSupported: List<String>

@SerialName("code_challenge_methods_supported")
lateinit var codeChallengeMethodsSupported: List<String>

@SerialName("ui_locales_supported")
lateinit var uiLocalesSupported: List<String>

@SerialName("display_values_supported")
lateinit var displayValuesSupported: List<String>

@SerialName("authorization_response_iss_parameter_supported")
var authorizationResponseIssParameterSupported: Boolean = false

@SerialName("request_object_signing_alg_values_supported")
lateinit var requestObjectSigningAlgValuesSupported: List<String>

@SerialName("request_object_encryption_alg_values_supported")
lateinit var requestObjectEncryptionAlgValuesSupported: List<String>

@SerialName("request_object_encryption_enc_values_supported")
lateinit var requestObjectEncryptionEncValuesSupported: List<String>

@SerialName("request_parameter_supported")
var requestParameterSupported: Boolean = false

@SerialName("request_uri_parameter_supported")
var requestUriParameterSupported: Boolean = false

@SerialName("require_request_uri_registration")
var requireRequestUriRegistration: Boolean = false

@SerialName("jwks_uri")
lateinit var jwksUri: String

@SerialName("authorization_endpoint")
lateinit var authorizationEndpoint: String

@SerialName("token_endpoint")
lateinit var tokenEndpoint: String

@SerialName("token_endpoint_auth_methods_supported")
lateinit var tokenEndpointAuthMethodsSupported: List<String>

@SerialName("token_endpoint_auth_signing_alg_values_supported")
lateinit var tokenEndpointAuthSigningAlgValuesSupported: List<String>

@SerialName("revocation_endpoint")
lateinit var revocationEndpoint: String

@SerialName("introspection_endpoint")
lateinit var introspectionEndpoint: String

@SerialName("pushed_authorization_request_endpoint")
lateinit var pushedAuthorizationRequestEndpoint: String

@SerialName("require_pushed_authorization_requests")
var requirePushedAuthorizationRequests: Boolean = false

@SerialName("dpop_signing_alg_values_supported")
lateinit var dpopSigningAlgValuesSupported: List<String>

@SerialName("client_id_metadata_document_supported")
var clientIdMetadataDocumentSupported: Boolean = false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package work.socialhub.kbsky.api.entity.meta

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
class WellKnownOAuthProtectedResourceResponse {

@SerialName("resource")
lateinit var resource: String

@SerialName("authorization_servers")
lateinit var authorizationServers: List<String>

@SerialName("scopes_supported")
lateinit var scopesSupported: List<String>

@SerialName("bearer_methods_supported")
lateinit var bearerMethodsSupported: List<String>

@SerialName("resource_documentation")
lateinit var resourceDocumentation: String
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package work.socialhub.kbsky.api.meta

import work.socialhub.kbsky.api.entity.meta.WellKnownOAuthAuthorizationServer
import work.socialhub.kbsky.api.entity.meta.WellKnownOAuthProtectedResourceResponse
import work.socialhub.kbsky.api.entity.share.Response

interface MetaResource {

/**
* Get OAuth Protected Resource
* https://oyster.us-east.host.bsky.network/.well-known/oauth-protected-resource
*/
fun wellKnownOAuthProtectedResource()
: Response<WellKnownOAuthProtectedResourceResponse>


/**
* Get OAuth authorization server
* https://bsky.social/.well-known/oauth-authorization-server
*/
fun wellKnownOAuthAuthorizationServer()
: Response<WellKnownOAuthAuthorizationServer>
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import work.socialhub.kbsky.ATProtocolConfig
import work.socialhub.kbsky.api.com.atproto.IdentityResource
import work.socialhub.kbsky.api.com.atproto.RepoResource
import work.socialhub.kbsky.api.com.atproto.ServerResource
import work.socialhub.kbsky.api.meta.MetaResource
import work.socialhub.kbsky.internal.com.atproto._IdentityResource
import work.socialhub.kbsky.internal.com.atproto._RepoResource
import work.socialhub.kbsky.internal.com.atproto._ServerResource
import work.socialhub.kbsky.internal.meta._MetaResource

open class _ATProtocol(
config: ATProtocolConfig
Expand All @@ -16,6 +18,7 @@ open class _ATProtocol(
protected val identity: IdentityResource = _IdentityResource(config)
protected val server: ServerResource = _ServerResource(config)
protected val repo: RepoResource = _RepoResource(config)
protected val meta: MetaResource = _MetaResource(config)

/**
* {@inheritDoc}
Expand All @@ -31,4 +34,9 @@ open class _ATProtocol(
* {@inheritDoc}
*/
override fun repo() = repo

/**
* {@inheritDoc}
*/
override fun meta() = meta
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package work.socialhub.kbsky.internal.meta

import kotlinx.coroutines.runBlocking
import work.socialhub.kbsky.ATProtocolConfig
import work.socialhub.kbsky.api.entity.meta.WellKnownOAuthAuthorizationServer
import work.socialhub.kbsky.api.entity.meta.WellKnownOAuthProtectedResourceResponse
import work.socialhub.kbsky.api.entity.share.Response
import work.socialhub.kbsky.api.meta.MetaResource
import work.socialhub.kbsky.internal.share._InternalUtility.proceed
import work.socialhub.kbsky.util.MediaType
import work.socialhub.khttpclient.HttpRequest

class _MetaResource(
private val config: ATProtocolConfig
) : MetaResource {

override fun wellKnownOAuthProtectedResource()
: Response<WellKnownOAuthProtectedResourceResponse> {
return proceed<WellKnownOAuthProtectedResourceResponse> {
runBlocking {
HttpRequest()
.url("${config.pdsUri}.well-known/oauth-protected-resource")
.accept(MediaType.JSON)
.get()
}
}.also {
if (config.updateAuthUri) {
var authUri = it.data.authorizationServers[0]
if (!authUri.endsWith("/")) authUri += "/"
config.authUri = authUri
}
}
}

override fun wellKnownOAuthAuthorizationServer()
: Response<WellKnownOAuthAuthorizationServer> {
return proceed {
runBlocking {
HttpRequest()
.url("${config.pdsUri}.well-known/oauth-authorization-server")
.accept(MediaType.JSON)
.get()
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class CreateSessionTest : AbstractTest() {
println(response.data.email)
println(response.data.emailConfirmed)
println(response.data.didDoc?.asDIDDetails?.id)
println(response.data.didDoc?.asDIDDetails?.service?.get(0)?.serviceEndpoint)


// Save the accessJwt for testing other APIs
accessJwt = checkNotNull(response.data.accessJwt)
Expand Down
28 changes: 28 additions & 0 deletions core/src/jvmTest/kotlin/work/socialhub/kbsky/meta/MetaTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package work.socialhub.kbsky.meta

import work.socialhub.kbsky.AbstractTest
import work.socialhub.kbsky.BlueskyFactory
import work.socialhub.kbsky.domain.Service.BSKY_SOCIAL
import work.socialhub.kbsky.domain.Service.OYSTER_US_EAST
import kotlin.test.Test

class MetaTest : AbstractTest() {

@Test
fun testWellKnownOAuthProtectedResource() {
val response = BlueskyFactory
.instance(OYSTER_US_EAST.uri)
.meta()
.wellKnownOAuthProtectedResource()
println(response.data.authorizationServers[0])
}

@Test
fun testWell() {
val response = BlueskyFactory
.instance(BSKY_SOCIAL.uri)
.meta()
.wellKnownOAuthAuthorizationServer()
println(response.data.issuer)
}
}

0 comments on commit 44e798e

Please sign in to comment.