106 lines
4.6 KiB
Kotlin
106 lines
4.6 KiB
Kotlin
package jp.juggler.subwaytooter.api.auth
|
|
|
|
import android.net.Uri
|
|
import jp.juggler.subwaytooter.api.TootApiClient
|
|
import jp.juggler.subwaytooter.api.TootApiResult
|
|
import jp.juggler.subwaytooter.api.entity.InstanceType
|
|
import jp.juggler.subwaytooter.api.entity.TootInstance
|
|
import jp.juggler.subwaytooter.pref.PrefS
|
|
import jp.juggler.util.data.JsonObject
|
|
import jp.juggler.util.data.notBlank
|
|
|
|
abstract class AuthBase {
|
|
companion object {
|
|
private const val DEFAULT_CLIENT_NAME = "SubwayTooter"
|
|
const val appNameId = "SubwayTooter"
|
|
const val appDescription = "Android app for federated SNS"
|
|
|
|
// 20181225 3=>4 client credentialの取得時にもscopeの取得が必要になった
|
|
// 20190147 4=>5 client id とユーザIDが同じだと同じアクセストークンが返ってくるので複数端末の利用で困る。
|
|
// AUTH_VERSIONが古いclient情報は使わない。また、インポートの対象にしない。
|
|
const val AUTH_VERSION = 5
|
|
|
|
const val KEY_CLIENT_CREDENTIAL = "SubwayTooterClientCredential"
|
|
const val KEY_CLIENT_SCOPE = "SubwayTooterClientScope"
|
|
const val KEY_AUTH_VERSION = "SubwayTooterAuthVersion"
|
|
const val KEY_IS_MISSKEY = "isMisskey" // for ClientInfo
|
|
const val KEY_MISSKEY_VERSION = "isMisskey" // for tokenInfo,TootInstance
|
|
const val KEY_MISSKEY_APP_SECRET = "secret"
|
|
const val KEY_API_KEY_MISSKEY = "apiKeyMisskey"
|
|
const val KEY_USER_ID = "userId"
|
|
|
|
var testClientName: String? = null
|
|
|
|
val clientName
|
|
get() = arrayOf(
|
|
testClientName,
|
|
PrefS.spClientName.value,
|
|
).firstNotNullOfOrNull { it.notBlank() }
|
|
?: DEFAULT_CLIENT_NAME
|
|
|
|
fun findAuthForVerifyAccount(client: TootApiClient, misskeyVersionMajor: Int) =
|
|
when {
|
|
// https://mastodon.juggler.jp/@tateisu/109819635248751031
|
|
// https://github.com/misskey-dev/misskey/issues/9825
|
|
// https://github.com/misskey-dev/misskey/commit/788ae2f6ca37d297e912bfba02821543e8566522
|
|
// misskeyVersionMajor >= 13 -> MisskeyAuth13(client)
|
|
misskeyVersionMajor > 0 -> AuthMisskey10(client)
|
|
else -> AuthMastodon(client)
|
|
}
|
|
|
|
fun findAuthForAuthStep1(client: TootApiClient, ti: TootInstance?, ri: TootApiResult?) =
|
|
ti?.let { findAuthForVerifyAccount(client, ti.misskeyVersionMajor) }
|
|
?: when (ri?.response?.code) {
|
|
// インスタンス情報を取得できないが、マストドンだと分かる場合がある
|
|
// https://github.com/tateisu/SubwayTooter/issues/155
|
|
// Mastodon's WHITELIST_MODE
|
|
401 -> AuthMastodon(client)
|
|
else -> null
|
|
}
|
|
|
|
fun findAuthForAuthCallback(client: TootApiClient, callbackUrl: String) =
|
|
when {
|
|
AuthMisskey10.isCallbackUrl(callbackUrl) -> AuthMisskey10(client)
|
|
AuthMisskey13.isCallbackUrl(callbackUrl) -> AuthMisskey13(client)
|
|
else -> AuthMastodon(client)
|
|
}
|
|
|
|
fun findAuthForCreateUser(client: TootApiClient, ti: TootInstance?) =
|
|
when (ti?.instanceType) {
|
|
InstanceType.Mastodon -> AuthMastodon(client)
|
|
else -> null
|
|
}
|
|
}
|
|
|
|
protected abstract val client: TootApiClient
|
|
|
|
protected val apiHost get() = client.apiHost
|
|
protected val account get() = client.account
|
|
protected val context get() = client.context
|
|
|
|
/**
|
|
* クライアントを登録してブラウザで開くURLを生成する
|
|
* 成功したら TootApiResult.data にURL文字列を格納すること
|
|
*/
|
|
abstract suspend fun authStep1(
|
|
// サーバ情報。Mastodonのホワイトリストモードではnullかもしれない
|
|
ti: TootInstance?,
|
|
// (Mastodon)クライアントを強制的に登録しなおす
|
|
forceUpdateClient: Boolean,
|
|
): Uri
|
|
|
|
/**
|
|
* ブラウザから戻ってきたコールバックURLを使い認証の続きを行う
|
|
*/
|
|
abstract suspend fun authStep2(uri: Uri): Auth2Result
|
|
|
|
/**
|
|
* アクセストークンを手動入力した場合、それを使って本人のユーザ情報を取得する
|
|
*/
|
|
abstract suspend fun verifyAccount(
|
|
accessToken: String,
|
|
outTokenJson: JsonObject?,
|
|
misskeyVersion: Int,
|
|
): JsonObject
|
|
}
|