Skip to content

Commit dc6cfb6

Browse files
committed
allow pkce for token auth
1 parent 40ca24a commit dc6cfb6

File tree

8 files changed

+45
-43
lines changed

8 files changed

+45
-43
lines changed

build.gradle.kts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ buildscript {
3131
}
3232

3333
group = "com.adamratzman"
34-
version = "3.2.05"
34+
version = "3.2.06"
3535

3636
/*java {
3737
withSourcesJar()
@@ -48,15 +48,15 @@ tasks.withType<Test> {
4848
android {
4949
compileSdkVersion(30)
5050
compileOptions {
51-
setSourceCompatibility(JavaVersion.VERSION_1_8)
52-
setTargetCompatibility(JavaVersion.VERSION_1_8)
51+
sourceCompatibility = JavaVersion.VERSION_1_8
52+
targetCompatibility = JavaVersion.VERSION_1_8
5353
}
5454
packagingOptions {
5555
// exclude("META-INF/*.kotlin_module")
5656
exclude("META-INF/*.md")
5757
}
5858
defaultConfig {
59-
minSdkVersion(20)
59+
minSdkVersion(15)
6060
targetSdkVersion(30)
6161
versionCode = 1
6262
versionName = "1.0"
@@ -145,8 +145,8 @@ kotlin {
145145
val commonMain by getting {
146146
dependencies {
147147
api("org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutineVersion")
148-
api("org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serializationVersion")
149-
api("io.ktor:ktor-client-core:$ktorVersion")
148+
implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serializationVersion")
149+
implementation("io.ktor:ktor-client-core:$ktorVersion")
150150

151151
implementation(kotlin("stdlib-common"))
152152
}
@@ -167,8 +167,8 @@ kotlin {
167167

168168
dependencies {
169169
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutineVersion")
170-
api("org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion")
171-
api("io.ktor:ktor-client-okhttp:$ktorVersion")
170+
implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion")
171+
implementation("io.ktor:ktor-client-cio:$ktorVersion")
172172
implementation(kotlin("stdlib-jdk8"))
173173
}
174174
}
@@ -187,10 +187,10 @@ kotlin {
187187

188188
val jsMain by getting {
189189
dependencies {
190-
api(npm("text-encoding", "0.7.0"))
190+
implementation(npm("text-encoding", "0.7.0"))
191191
api("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutineVersion")
192-
api("org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:$serializationVersion")
193-
api("io.ktor:ktor-client-js:$ktorVersion")
192+
implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:$serializationVersion")
193+
implementation("io.ktor:ktor-client-js:$ktorVersion")
194194
api(npm("abort-controller", "3.0.0"))
195195
api(npm("node-fetch", "2.6.0"))
196196

@@ -212,10 +212,10 @@ kotlin {
212212
}
213213

214214
dependencies {
215-
api("net.sourceforge.streamsupport:android-retrofuture:1.7.2")
215+
implementation("net.sourceforge.streamsupport:android-retrofuture:1.7.2")
216216
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutineVersion")
217-
api("org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion")
218-
api("io.ktor:ktor-client-okhttp:$ktorVersion")
217+
implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion")
218+
implementation("io.ktor:ktor-client-cio:$ktorVersion")
219219
implementation(kotlin("stdlib-jdk8"))
220220
}
221221
}

src/commonMain/kotlin/com.adamratzman.spotify/Builder.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ fun spotifyAppApi(
172172
fun spotifyAppApi(
173173
clientId: String,
174174
clientSecret: String,
175-
block: SpotifyAppApiBuilder.() -> Unit
175+
block: SpotifyAppApiBuilder.() -> Unit = {}
176176
) = SpotifyAppApiBuilder().apply(block).apply {
177177
credentials {
178178
this.clientId = clientId
@@ -249,7 +249,7 @@ fun spotifyClientApi(
249249
clientId: String,
250250
clientSecret: String,
251251
redirectUri: String,
252-
block: SpotifyClientApiBuilder.() -> Unit
252+
block: SpotifyClientApiBuilder.() -> Unit = {}
253253
) = SpotifyClientApiBuilder().apply(block).apply {
254254
credentials {
255255
this.clientId = clientId
@@ -826,7 +826,7 @@ class SpotifyClientApiBuilder(
826826
options.requestTimeoutMillis,
827827
options.json,
828828
options.refreshTokenProducer,
829-
false,
829+
authorization.pkceCodeVerifier != null,
830830
options.onTokenRefresh
831831
)
832832
authorization.tokenString != null -> SpotifyClientApi(

src/commonMain/kotlin/com.adamratzman.spotify/SpotifyRestAction.kt

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import kotlinx.coroutines.CoroutineScope
1717
import kotlinx.coroutines.Dispatchers
1818
import kotlinx.coroutines.ExperimentalCoroutinesApi
1919
import kotlinx.coroutines.FlowPreview
20-
import kotlinx.coroutines.GlobalScope
20+
import kotlinx.coroutines.coroutineScope
2121
import kotlinx.coroutines.flow.asFlow
2222
import kotlinx.coroutines.flow.emitAll
2323
import kotlinx.coroutines.flow.flatMapConcat
@@ -33,6 +33,8 @@ open class SpotifyRestAction<T> internal constructor(protected val api: GenericS
3333
private var hasRunBacking: Boolean = false
3434
private var hasCompletedBacking: Boolean = false
3535

36+
lateinit var scope: CoroutineContext
37+
3638
/**
3739
* Whether this REST action has been *commenced*.
3840
*
@@ -88,20 +90,22 @@ open class SpotifyRestAction<T> internal constructor(protected val api: GenericS
8890
* @param consumer to be invoked with [T] after successful completion of [supplier]
8991
*/
9092
@JvmOverloads
91-
fun queue(failure: ((Throwable) -> Unit) = { throw it }, consumer: ((T) -> Unit) = {}): SpotifyRestAction<T> {
93+
fun queue(failure: (suspend (Throwable) -> Unit) = { throw it }, consumer: (suspend (T) -> Unit) = {}) {
9294
hasRunBacking = true
93-
GlobalScope.launch {
94-
try {
95-
val result = suspendComplete()
96-
consumer(result)
97-
} catch (e: CancellationException) {
98-
throw e
99-
} catch (t: Throwable) {
100-
failure(t)
95+
runBlocking {
96+
coroutineScope {
97+
launch {
98+
try {
99+
val result = suspendComplete()
100+
consumer(result)
101+
} catch (e: CancellationException) {
102+
throw e
103+
} catch (t: Throwable) {
104+
failure(t)
105+
}
106+
}
101107
}
102108
}
103-
104-
return this
105109
}
106110

107111
/**
@@ -115,17 +119,16 @@ open class SpotifyRestAction<T> internal constructor(protected val api: GenericS
115119
fun queueAfter(
116120
quantity: Int,
117121
timeUnit: TimeUnit = TimeUnit.SECONDS,
118-
scope: CoroutineScope = GlobalScope,
122+
scope: CoroutineScope? = null,
119123
failure: (Throwable) -> Unit = { throw it },
120124
consumer: (T) -> Unit
121-
): SpotifyRestAction<T> {
125+
) {
122126
val runAt = getCurrentTimeMs() + timeUnit.toMillis(quantity.toLong())
123127
queue({ exception ->
124-
scope.schedule((runAt - getCurrentTimeMs()).toInt(), TimeUnit.MILLISECONDS) { failure(exception) }
128+
(scope ?: coroutineScope { this }).schedule((runAt - getCurrentTimeMs()).toInt(), TimeUnit.MILLISECONDS) { failure(exception) }
125129
}) { result ->
126-
scope.schedule((runAt - getCurrentTimeMs()).toInt(), TimeUnit.MILLISECONDS) { consumer(result) }
130+
(scope ?: coroutineScope { this }).schedule((runAt - getCurrentTimeMs()).toInt(), TimeUnit.MILLISECONDS) { consumer(result) }
127131
}
128-
return this
129132
}
130133

131134
override fun toString() = complete().toString()

src/commonMain/kotlin/com.adamratzman.spotify/http/HttpConnection.kt

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,6 @@ class HttpConnection constructor(
4949
) {
5050
val contentType: ContentType = contentType?.let { ContentType.parse(it) } ?: ContentType.Application.Json
5151

52-
companion object {
53-
private val client = HttpClient()
54-
}
55-
5652
fun String?.toByteArrayContent(): ByteArrayContent? {
5753
return if (this == null) null else ByteArrayContent(this.toByteArray(), contentType)
5854
}
@@ -94,7 +90,7 @@ class HttpConnection constructor(
9490
val httpRequest = buildRequest(additionalHeaders)
9591

9692
try {
97-
return client.request<io.ktor.client.statement.HttpResponse>(httpRequest).let { response ->
93+
return HttpClient().request<io.ktor.client.statement.HttpResponse>(httpRequest).let { response ->
9894
val respCode = response.status.value
9995

10096
if (respCode == 502 && retryIf502) {
@@ -149,7 +145,7 @@ class HttpConnection constructor(
149145
} catch (e: ResponseException) {
150146
val errorBody = e.response.readText()
151147
val error = errorBody.toObject(ErrorResponse.serializer(), api, api?.json ?: nonstrictJson).error
152-
throw SpotifyException.BadRequestException(error)
148+
throw SpotifyException.BadRequestException(error.copy(reason = (error.reason ?: "") + " URL: $url"))
153149
}
154150
}
155151

src/commonMain/kotlin/com.adamratzman.spotify/utils/Concurrency.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ expect enum class TimeUnit {
1010
}
1111

1212
internal expect fun CoroutineScope.schedule(quantity: Int, timeUnit: TimeUnit, consumer: () -> Unit)
13+
14+
expect fun <T> runBlocking(coroutineCode: suspend () -> T): T

src/commonMain/kotlin/com.adamratzman.spotify/utils/Utils.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,3 @@ internal fun <T : ResultEnum> Array<T>.match(identifier: String) =
2323
firstOrNull { it.retrieveIdentifier().toString().equals(identifier, true) }
2424

2525
internal expect fun formatDate(format: String, date: Long): String
26-
27-
expect fun <T> runBlocking(coroutineCode: suspend () -> T): T

src/commonTest/kotlin/com.adamratzman/spotify/utilities/RestActionTests.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ import com.adamratzman.spotify.annotations.SpotifyExperimentalHttpApi
66
import com.adamratzman.spotify.api
77
import com.adamratzman.spotify.utils.runBlocking
88
import kotlin.test.assertFailsWith
9+
import kotlin.time.ExperimentalTime
910
import org.spekframework.spek2.Spek
1011
import org.spekframework.spek2.style.specification.describe
1112

13+
@ExperimentalTime
1214
@SpotifyExperimentalHttpApi
1315
class RestActionTests : Spek({
1416
describe("Paging Object") {

src/jvmTest/kotlin/com/adamratzman/spotify/PkceTest.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,10 @@ class PkceTest : Spek({
5353
} else "err."
5454
}
5555

56+
println("Waiting...")
57+
5658
while (!stop) {
5759
Thread.sleep(2000)
58-
println("Waiting...")
5960
}
6061
}
6162
}

0 commit comments

Comments
 (0)