mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-10 23:21:59 +01:00
fall back to password auth when the server rejects the token scheme
Navidrome refuses the Subsonic token scheme for LDAP users with error code 41. Catch it once in SubsonicClient: flip that client to the password scheme, tell SourceRepository to persist the change for the source and show a toast, then retry the request. Only 41 is retried, the flip is idempotent, and a client never retries more than once.
This commit is contained in:
@@ -25,14 +25,22 @@ class SubsonicClientTest {
|
||||
server.shutdown()
|
||||
}
|
||||
|
||||
private fun client(tokenAuth: Boolean) =
|
||||
SubsonicClient(
|
||||
baseUrl = server.url("/"),
|
||||
username = "guest",
|
||||
password = "secret",
|
||||
useTokenAuth = tokenAuth,
|
||||
http = OkHttpClient(),
|
||||
)
|
||||
private fun client(
|
||||
tokenAuth: Boolean,
|
||||
onTokenAuthUnsupported: (() -> Unit)? = null,
|
||||
) = SubsonicClient(
|
||||
baseUrl = server.url("/"),
|
||||
username = "guest",
|
||||
password = "secret",
|
||||
useTokenAuth = tokenAuth,
|
||||
http = OkHttpClient(),
|
||||
onTokenAuthUnsupported = onTokenAuthUnsupported,
|
||||
)
|
||||
|
||||
private fun failed(
|
||||
code: Int,
|
||||
message: String,
|
||||
) = "<subsonic-response status=\"failed\"><error code=\"$code\" message=\"$message\"/></subsonic-response>"
|
||||
|
||||
@Test
|
||||
fun tokenAuthSendsSaltAndHash() {
|
||||
@@ -90,4 +98,51 @@ class SubsonicClientTest {
|
||||
|
||||
assertThrows(SubsonicException::class.java) { client(tokenAuth = true).check("ping") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun tokenAuthUnsupportedRetriesWithPassword() {
|
||||
server.enqueue(MockResponse().setBody(failed(41, "Token authentication not supported for LDAP users.")))
|
||||
server.enqueue(MockResponse().setBody("<subsonic-response status=\"ok\" version=\"1.16.1\"/>"))
|
||||
var notified = 0
|
||||
|
||||
client(tokenAuth = true, onTokenAuthUnsupported = { notified++ }).check("ping")
|
||||
|
||||
val first = server.takeRequest().requestUrl!!
|
||||
assertNotNull(first.queryParameter("t"))
|
||||
assertNull(first.queryParameter("p"))
|
||||
val second = server.takeRequest().requestUrl!!
|
||||
assertNull(second.queryParameter("t"))
|
||||
assertEquals("secret", second.queryParameter("p"))
|
||||
assertEquals(1, notified)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun tokenAuthUnsupportedIsNotifiedOnceAndNotRetriedAgain() {
|
||||
server.enqueue(MockResponse().setBody(failed(41, "Token authentication not supported for LDAP users.")))
|
||||
server.enqueue(MockResponse().setBody("<subsonic-response status=\"ok\" version=\"1.16.1\"/>"))
|
||||
server.enqueue(MockResponse().setBody(failed(41, "Token authentication not supported for LDAP users.")))
|
||||
var notified = 0
|
||||
val client = client(tokenAuth = true, onTokenAuthUnsupported = { notified++ })
|
||||
|
||||
client.check("ping")
|
||||
assertThrows(SubsonicException::class.java) { client.check("ping") }
|
||||
|
||||
assertEquals(1, notified)
|
||||
assertEquals(3, server.requestCount)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun otherErrorsAreNotRetried() {
|
||||
server.enqueue(MockResponse().setBody(failed(40, "Wrong username")))
|
||||
var notified = 0
|
||||
|
||||
val error =
|
||||
assertThrows(SubsonicException::class.java) {
|
||||
client(tokenAuth = true, onTokenAuthUnsupported = { notified++ }).check("ping")
|
||||
}
|
||||
|
||||
assertEquals(40, error.code)
|
||||
assertEquals(0, notified)
|
||||
assertEquals(1, server.requestCount)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user