@@ -13,16 +13,16 @@ import com.adamratzman.spotify.endpoints.client.ClientPlaylistApi
13
13
import com.adamratzman.spotify.endpoints.client.ClientProfileApi
14
14
import com.adamratzman.spotify.endpoints.client.ClientSearchApi
15
15
import com.adamratzman.spotify.endpoints.client.ClientShowApi
16
- import com.adamratzman.spotify.endpoints.public .AlbumApi
17
- import com.adamratzman.spotify.endpoints.public .ArtistApi
18
- import com.adamratzman.spotify.endpoints.public .BrowseApi
19
- import com.adamratzman.spotify.endpoints.public .EpisodeApi
20
- import com.adamratzman.spotify.endpoints.public .FollowingApi
21
- import com.adamratzman.spotify.endpoints.public .PlaylistApi
22
- import com.adamratzman.spotify.endpoints.public .SearchApi
23
- import com.adamratzman.spotify.endpoints.public .ShowApi
24
- import com.adamratzman.spotify.endpoints.public .TrackApi
25
- import com.adamratzman.spotify.endpoints.public .UserApi
16
+ import com.adamratzman.spotify.endpoints.pub .AlbumApi
17
+ import com.adamratzman.spotify.endpoints.pub .ArtistApi
18
+ import com.adamratzman.spotify.endpoints.pub .BrowseApi
19
+ import com.adamratzman.spotify.endpoints.pub .EpisodeApi
20
+ import com.adamratzman.spotify.endpoints.pub .FollowingApi
21
+ import com.adamratzman.spotify.endpoints.pub .PlaylistApi
22
+ import com.adamratzman.spotify.endpoints.pub .SearchApi
23
+ import com.adamratzman.spotify.endpoints.pub .ShowApi
24
+ import com.adamratzman.spotify.endpoints.pub .TrackApi
25
+ import com.adamratzman.spotify.endpoints.pub .UserApi
26
26
import com.adamratzman.spotify.http.CacheState
27
27
import com.adamratzman.spotify.http.HttpConnection
28
28
import com.adamratzman.spotify.http.HttpHeader
@@ -37,8 +37,8 @@ import com.adamratzman.spotify.models.serialization.nonstrictJson
37
37
import com.adamratzman.spotify.models.serialization.toObject
38
38
import com.adamratzman.spotify.utils.asList
39
39
import com.adamratzman.spotify.utils.base64ByteEncode
40
- import kotlin.jvm.JvmOverloads
41
40
import kotlinx.serialization.json.Json
41
+ import kotlin.jvm.JvmOverloads
42
42
43
43
/* *
44
44
* Represents an instance of the Spotify API client, with common
@@ -212,6 +212,20 @@ public sealed class SpotifyApi<T : SpotifyApi<T, B>, B : ISpotifyApiBuilder<T, B
212
212
}
213
213
}
214
214
215
+ /* *
216
+ * Tests whether the current [token] is actually valid. By default, an endpoint is called *once* to verify
217
+ * validity.
218
+ *
219
+ * @param makeTestRequest Whether to also make an endpoint request to verify authentication.
220
+ *
221
+ * @return [TokenValidityResponse] containing whether this token is valid, and if not, an Exception explaining why
222
+ */
223
+ @JvmOverloads
224
+ public fun isTokenValidRestAction (makeTestRequest : Boolean = true): SpotifyRestAction <TokenValidityResponse > =
225
+ SpotifyRestAction {
226
+ isTokenValid(makeTestRequest)
227
+ }
228
+
215
229
/* *
216
230
* If the method used to create the [token] supports token refresh and
217
231
* the information in [token] is accurate, attempt to refresh the token
@@ -224,7 +238,18 @@ public sealed class SpotifyApi<T : SpotifyApi<T, B>, B : ISpotifyApiBuilder<T, B
224
238
this @SpotifyApi.token = this
225
239
spotifyApiOptions.onTokenRefresh?.invoke(this @SpotifyApi)
226
240
spotifyApiOptions.afterTokenRefresh?.invoke(this @SpotifyApi)
227
- } ? : throw SpotifyException .ReAuthenticationNeededException (IllegalStateException (" The refreshTokenProducer is null." ))
241
+ }
242
+ ? : throw SpotifyException .ReAuthenticationNeededException (IllegalStateException (" The refreshTokenProducer is null." ))
243
+
244
+ /* *
245
+ * If the method used to create the [token] supports token refresh and
246
+ * the information in [token] is accurate, attempt to refresh the token
247
+ *
248
+ * @return The old access token if refresh was successful
249
+ * @throws BadRequestException if refresh fails
250
+ * @throws IllegalStateException if [SpotifyApiOptions.refreshTokenProducer] is null
251
+ */
252
+ public fun refreshTokenRestAction (): SpotifyRestAction <Token > = SpotifyRestAction { refreshToken() }
228
253
229
254
public companion object {
230
255
internal suspend fun testTokenValidity (api : GenericSpotifyApi ) {
@@ -327,6 +352,22 @@ public sealed class SpotifyApi<T : SpotifyApi<T, B>, B : ISpotifyApiBuilder<T, B
327
352
328
353
throw BadRequestException (response.body.toObject(AuthenticationError .serializer(), null , json))
329
354
}
355
+
356
+ /* *
357
+ *
358
+ * Get an application token (can only access public methods) that can be used to instantiate a new [SpotifyAppApi]
359
+ *
360
+ * @param clientId Spotify [client id](https://developer.spotify.com/documentation/general/guides/app-settings/)
361
+ * @param clientSecret Spotify [client secret](https://developer.spotify.com/documentation/general/guides/app-settings/)
362
+ * @param api The Spotify Api instance, or null if one doesn't exist yet
363
+ * @param json The json instance that will deserialize the response.
364
+ */
365
+ public fun getCredentialedTokenRestAction (
366
+ clientId : String ,
367
+ clientSecret : String ,
368
+ api : GenericSpotifyApi ? ,
369
+ json : Json = api?.spotifyApiOptions?.json ? : Json .Default
370
+ ): SpotifyRestAction <Token > = SpotifyRestAction { getCredentialedToken(clientId, clientSecret, api, json) }
330
371
}
331
372
}
332
373
@@ -501,18 +542,23 @@ public open class SpotifyClientApi(
501
542
*/
502
543
public val player: ClientPlayerApi = ClientPlayerApi (this )
503
544
504
- private lateinit var userIdBacking: String
545
+ private var userIdBacking: String? = null
505
546
506
547
private suspend fun initiatizeUserIdBacking (): String {
507
548
userIdBacking = users.getClientProfile().id
508
- return userIdBacking
549
+ return userIdBacking!!
509
550
}
510
551
511
552
/* *
512
553
* The Spotify user id to which the api instance is connected
513
554
*/
514
555
public suspend fun getUserId (): String =
515
- if (::userIdBacking.isInitialized) userIdBacking else initiatizeUserIdBacking()
556
+ if (userIdBacking != null ) userIdBacking!! else initiatizeUserIdBacking()
557
+
558
+ /* *
559
+ * The Spotify user id to which the api instance is connected
560
+ */
561
+ public fun getUserIdRestAction (): SpotifyRestAction <String > = SpotifyRestAction { getUserId() }
516
562
517
563
/* *
518
564
* Stop all automatic functions like refreshToken or clearCache and shut down the scheduled
@@ -574,6 +620,12 @@ public open class SpotifyClientApi(
574
620
*/
575
621
public suspend fun hasScope (scope : SpotifyScope ): Boolean? = hasScopes(scope)
576
622
623
+ /* *
624
+ * Whether the current access token allows access to scope [scope]
625
+ */
626
+ public fun hasScopeRestAction (scope : SpotifyScope ): SpotifyRestAction <Boolean ?> =
627
+ SpotifyRestAction { hasScope(scope) }
628
+
577
629
/* *
578
630
* Whether the current access token allows access to all of the provided scopes
579
631
*/
@@ -583,13 +635,21 @@ public open class SpotifyClientApi(
583
635
token.scopes?.contains(scope) == true &&
584
636
scopes.all { token.scopes?.contains(it) == true }
585
637
638
+ /* *
639
+ * Whether the current access token allows access to all of the provided scopes
640
+ */
641
+ public fun hasScopesRestAction (scope : SpotifyScope , vararg scopes : SpotifyScope ): SpotifyRestAction <Boolean ?> =
642
+ SpotifyRestAction {
643
+ hasScopes(scope, * scopes)
644
+ }
645
+
586
646
public companion object {
587
647
private val defaultClientApiTokenRefreshProducer: suspend (GenericSpotifyApi ) -> Token = { api ->
588
648
api as SpotifyClientApi
589
649
590
650
require(api.clientId != null ) { " The client id is not set" }
591
651
592
- refreshSpotifyClientToken(api.clientId, api.clientSecret, api.token.refreshToken, api.usesPkceAuth)
652
+ refreshSpotifyClientToken(api.clientId, api.clientSecret, api.token.refreshToken, api.usesPkceAuth)
593
653
}
594
654
}
595
655
}
@@ -707,3 +767,21 @@ public suspend fun refreshSpotifyClientToken(
707
767
)
708
768
)
709
769
}
770
+
771
+ /* *
772
+ * Refresh a Spotify client token
773
+ *
774
+ * @param clientId The Spotify application client id.
775
+ * @param clientSecret The Spotify application client secret (not needed for PKCE).
776
+ * @param refreshToken The refresh token.
777
+ * @param usesPkceAuth Whether this token was created using PKCE auth or not.
778
+ */
779
+ public fun refreshSpotifyClientTokenRestAction (
780
+ clientId : String ,
781
+ clientSecret : String? ,
782
+ refreshToken : String? ,
783
+ usesPkceAuth : Boolean
784
+ ): SpotifyRestAction <Token > =
785
+ SpotifyRestAction { refreshSpotifyClientToken(clientId, clientSecret, refreshToken, usesPkceAuth) }
786
+
787
+
0 commit comments