Mastodonのクライアント情報再利用チェックでAPIがエラーを返した際のフォールバックが不足していた

This commit is contained in:
tateisu 2023-03-03 09:42:16 +09:00
parent 953cdea115
commit c4150b1ff1
2 changed files with 44 additions and 40 deletions

View File

@ -104,51 +104,53 @@ class AuthMastodon(override val client: TootApiClient) : AuthBase() {
// スコープ一覧を取得する
val scopeString = mastodonScope(tootInstance)
when {
// 古いクライアント情報は使わない。削除もしない。
AUTH_VERSION != clientInfo?.int(KEY_AUTH_VERSION) -> Unit
try {
when {
// 古いクライアント情報は使わない。削除もしない。
AUTH_VERSION != clientInfo?.int(KEY_AUTH_VERSION) -> Unit
// Misskeyにはclient情報をまだ利用できるかどうか調べる手段がないので、再利用しない
clientInfo.boolean(KEY_IS_MISSKEY) == true -> Unit
// Misskeyにはclient情報をまだ利用できるかどうか調べる手段がないので、再利用しない
clientInfo.boolean(KEY_IS_MISSKEY) == true -> Unit
else -> {
val clientCredential = prepareClientCredential(apiHost, clientInfo, clientName)
// client_credential があるならcredentialがまだ使えるか確認する
if (!clientCredential.isNullOrEmpty()) {
else -> {
val clientCredential = prepareClientCredential(apiHost, clientInfo, clientName)
// client_credential があるならcredentialがまだ使えるか確認する
if (!clientCredential.isNullOrEmpty()) {
// 存在確認するだけで、結果は使ってない
api.verifyClientCredential(apiHost, clientCredential)
// 存在確認するだけで、結果は使ってない
api.verifyClientCredential(apiHost, clientCredential)
// 過去にはスコープを+で連結したものを保存していた
val oldScope = clientInfo.string(KEY_CLIENT_SCOPE)
?.replace("+", " ")
// 過去にはスコープを+で連結したものを保存していた
val oldScope = clientInfo.string(KEY_CLIENT_SCOPE)
?.replace("+", " ")
when {
// クライアント情報を再利用する
!forceUpdateClient && oldScope == scopeString -> return clientInfo
when {
// クライアント情報を再利用する
!forceUpdateClient && oldScope == scopeString -> return clientInfo
else -> try {
// マストドン2.4でスコープが追加された
// 取得時のスコープ指定がマッチしない(もしくは記録されていない)ならクライアント情報を再利用してはいけない
daoClientInfo.delete(apiHost, clientName)
else -> {
// マストドン2.4でスコープが追加された
// 取得時のスコープ指定がマッチしない(もしくは記録されていない)ならクライアント情報を再利用してはいけない
daoClientInfo.delete(apiHost, clientName)
// クライアントアプリ情報そのものはまだサーバに残っているが、明示的に消す方法は現状存在しない
// client credential だけは消せる
api.revokeClientCredential(
apiHost = apiHost,
clientId = clientInfo.string("client_id")
?: error("revokeClientCredential: missing client_id"),
clientSecret = clientInfo.string("client_secret")
?: error("revokeClientCredential: missing client_secret"),
clientCredential = clientCredential,
)
} catch (ex: Throwable) {
// クライアント情報の削除処理はエラーが起きても無視する
log.w(ex, "can't delete client information.")
// クライアントアプリ情報そのものはまだサーバに残っているが、明示的に消す方法は現状存在しない
// client credential だけは消せる
api.revokeClientCredential(
apiHost = apiHost,
clientId = clientInfo.string("client_id")
?: error("revokeClientCredential: missing client_id"),
clientSecret = clientInfo.string("client_secret")
?: error("revokeClientCredential: missing client_secret"),
clientCredential = clientCredential,
)
}
}
}
}
}
} catch (ex: Throwable) {
// クライアント再利用チェックやクライアント情報の削除処理はエラーが起きても無視する
log.w(ex, "can't verify/delete client information.")
}
clientInfo = api.registerClient(apiHost, scopeString, clientName, callbackUrl).apply {
@ -156,7 +158,7 @@ class AuthMastodon(override val client: TootApiClient) : AuthBase() {
put(KEY_AUTH_VERSION, AUTH_VERSION)
put(KEY_CLIENT_SCOPE, scopeString)
}
if(DEBUG_AUTH) log.i("DEBUG_AUTH client_id=${clientInfo.string("client_id")}")
if (DEBUG_AUTH) log.i("DEBUG_AUTH client_id=${clientInfo.string("client_id")}")
// client credentialを取得して保存する
// この時点ではまだ client credential がないので、必ず更新と保存が行われる
prepareClientCredential(apiHost, clientInfo, clientName)
@ -295,7 +297,7 @@ class AuthMastodon(override val client: TootApiClient) : AuthBase() {
val accessToken = tokenInfo.string("access_token")
?.notEmpty() ?: error("can't parse access token.")
if(DEBUG_AUTH) log.i("DEBUG_AUTH accessToken=${accessToken}")
if (DEBUG_AUTH) log.i("DEBUG_AUTH accessToken=${accessToken}")
val accountJson = verifyAccount(
accessToken = accessToken,

View File

@ -204,7 +204,6 @@ private class EmojiPicker(
}
private inner class VhCategory(
parent: ViewGroup,
view: FrameLayout = FrameLayout(activity),
) : ViewHolderBase(view) {
var lastItem: PickerItemCategory? = null
@ -212,12 +211,15 @@ private class EmojiPicker(
val tv = AppCompatTextView(activity).apply {
layoutParams = FrameLayout.LayoutParams(matchParent, wrapContent)
minHeightCompat = (density * 48f + 0.5f).toInt()
gravity = Gravity.START or Gravity.CENTER_VERTICAL
includeFontPadding = false
background = ContextCompat.getDrawable(
this@EmojiPicker.activity,
R.drawable.btn_bg_transparent_round6dp
)
gravity = Gravity.START or Gravity.CENTER_VERTICAL
includeFontPadding = false
val paddingH = (density * 4f + 0.5f).toInt()
val paddingV = (density * 2f + 0.5f).toInt()
setPadding(paddingH,paddingV,paddingH,paddingV)
compoundDrawablePadding = (density * 4f + 0.5f).toInt()
setOnClickListener {
@ -401,7 +403,7 @@ private class EmojiPicker(
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int) =
when (viewType) {
VT_CATEGORY -> VhCategory(viewGroup)
VT_CATEGORY -> VhCategory()
VT_CUSTOM_EMOJI -> VhCustomEmoji()
VT_TWEMOJI -> VhTwemoji()
VT_COMPAT_EMOJI -> VhAppCompatEmoji()