48 lines
1.5 KiB
Kotlin
48 lines
1.5 KiB
Kotlin
package org.moire.ultrasonic.api.subsonic.interceptors
|
|
|
|
import java.security.MessageDigest
|
|
import java.security.NoSuchAlgorithmException
|
|
import java.security.SecureRandom
|
|
import java.util.Locale
|
|
import okhttp3.Interceptor
|
|
import okhttp3.Interceptor.Chain
|
|
import okhttp3.Response
|
|
|
|
/**
|
|
* Adds password param as MD5 hash with random salt. Salt is also added as a param.
|
|
*
|
|
* Should be enabled for requests against [org.moire.ultrasonic.api.subsonic.SubsonicAPIVersions.V1_13_0]
|
|
* and above.
|
|
*/
|
|
class PasswordMD5Interceptor(private val password: String) : Interceptor {
|
|
private val secureRandom = SecureRandom()
|
|
private val saltBytes = ByteArray(16)
|
|
|
|
override fun intercept(chain: Chain): Response {
|
|
val originalRequest = chain.request()
|
|
val salt = getSalt()
|
|
val updatedUrl = originalRequest.url.newBuilder()
|
|
.addQueryParameter("t", getPasswordMD5Hash(salt))
|
|
.addQueryParameter("s", salt)
|
|
.build()
|
|
|
|
return chain.proceed(originalRequest.newBuilder().url(updatedUrl).build())
|
|
}
|
|
|
|
private fun getSalt(): String {
|
|
secureRandom.nextBytes(saltBytes)
|
|
return saltBytes.toHexBytes()
|
|
}
|
|
|
|
private fun getPasswordMD5Hash(salt: String): String {
|
|
try {
|
|
val md5Digest = MessageDigest.getInstance("MD5")
|
|
return md5Digest.digest(
|
|
"$password$salt".toByteArray()
|
|
).toHexBytes().lowercase(Locale.getDefault())
|
|
} catch (e: NoSuchAlgorithmException) {
|
|
throw IllegalStateException(e)
|
|
}
|
|
}
|
|
}
|