Reveal services secrets #313 #317

This commit is contained in:
Koitharu
2023-03-05 07:30:47 +02:00
parent 866f9272ef
commit 5cfad9ab8a
7 changed files with 46 additions and 37 deletions

View File

@@ -25,15 +25,6 @@ android {
arg 'room.schemaLocation', "$projectDir/schemas".toString() arg 'room.schemaLocation', "$projectDir/schemas".toString()
} }
} }
// define this values in your local.properties file
buildConfigField 'String', 'SHIKIMORI_CLIENT_ID', "\"${localProperty('shikimori.clientId')}\""
buildConfigField 'String', 'SHIKIMORI_CLIENT_SECRET', "\"${localProperty('shikimori.clientSecret')}\""
buildConfigField 'String', 'ANILIST_CLIENT_ID', "\"${localProperty('anilist.clientId')}\""
buildConfigField 'String', 'ANILIST_CLIENT_SECRET', "\"${localProperty('anilist.clientSecret')}\""
buildConfigField 'String', 'MAL_CLIENT_ID', "\"${localProperty('mal.clientId')}\""
resValue "string", "acra_login", "${localProperty('acra.login')}"
resValue "string", "acra_password", "${localProperty('acra.password')}"
} }
buildTypes { buildTypes {
debug { debug {

View File

@@ -36,6 +36,7 @@ object ScrobblingModule {
@Provides @Provides
@Singleton @Singleton
fun provideShikimoriRepository( fun provideShikimoriRepository(
@ApplicationContext context: Context,
@ScrobblerType(ScrobblerService.SHIKIMORI) storage: ScrobblerStorage, @ScrobblerType(ScrobblerService.SHIKIMORI) storage: ScrobblerStorage,
database: MangaDatabase, database: MangaDatabase,
authenticator: ShikimoriAuthenticator, authenticator: ShikimoriAuthenticator,
@@ -47,12 +48,13 @@ object ScrobblingModule {
addInterceptor(CurlLoggingInterceptor()) addInterceptor(CurlLoggingInterceptor())
} }
}.build() }.build()
return ShikimoriRepository(okHttp, storage, database) return ShikimoriRepository(context, okHttp, storage, database)
} }
@Provides @Provides
@Singleton @Singleton
fun provideMALRepository( fun provideMALRepository(
@ApplicationContext context: Context,
@ScrobblerType(ScrobblerService.MAL) storage: ScrobblerStorage, @ScrobblerType(ScrobblerService.MAL) storage: ScrobblerStorage,
database: MangaDatabase, database: MangaDatabase,
authenticator: MALAuthenticator, authenticator: MALAuthenticator,
@@ -64,12 +66,13 @@ object ScrobblingModule {
addInterceptor(CurlLoggingInterceptor()) addInterceptor(CurlLoggingInterceptor())
} }
}.build() }.build()
return MALRepository(okHttp, storage, database) return MALRepository(context, okHttp, storage, database)
} }
@Provides @Provides
@Singleton @Singleton
fun provideAniListRepository( fun provideAniListRepository(
@ApplicationContext context: Context,
@ScrobblerType(ScrobblerService.ANILIST) storage: ScrobblerStorage, @ScrobblerType(ScrobblerService.ANILIST) storage: ScrobblerStorage,
database: MangaDatabase, database: MangaDatabase,
authenticator: AniListAuthenticator, authenticator: AniListAuthenticator,
@@ -81,7 +84,7 @@ object ScrobblingModule {
addInterceptor(CurlLoggingInterceptor()) addInterceptor(CurlLoggingInterceptor())
} }
}.build() }.build()
return AniListRepository(okHttp, storage, database) return AniListRepository(context, okHttp, storage, database)
} }
@Provides @Provides

View File

@@ -1,12 +1,14 @@
package org.koitharu.kotatsu.scrobbling.anilist.data package org.koitharu.kotatsu.scrobbling.anilist.data
import android.content.Context
import dagger.hilt.android.qualifiers.ApplicationContext
import okhttp3.FormBody import okhttp3.FormBody
import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject import org.json.JSONObject
import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.db.MangaDatabase import org.koitharu.kotatsu.core.db.MangaDatabase
import org.koitharu.kotatsu.parsers.exception.GraphQLException import org.koitharu.kotatsu.parsers.exception.GraphQLException
import org.koitharu.kotatsu.parsers.model.MangaChapter import org.koitharu.kotatsu.parsers.model.MangaChapter
@@ -15,6 +17,7 @@ import org.koitharu.kotatsu.parsers.util.json.getStringOrNull
import org.koitharu.kotatsu.parsers.util.json.mapJSON import org.koitharu.kotatsu.parsers.util.json.mapJSON
import org.koitharu.kotatsu.parsers.util.parseJson import org.koitharu.kotatsu.parsers.util.parseJson
import org.koitharu.kotatsu.parsers.util.toIntUp import org.koitharu.kotatsu.parsers.util.toIntUp
import org.koitharu.kotatsu.scrobbling.common.data.ScrobblerRepository
import org.koitharu.kotatsu.scrobbling.common.data.ScrobblerStorage import org.koitharu.kotatsu.scrobbling.common.data.ScrobblerStorage
import org.koitharu.kotatsu.scrobbling.common.data.ScrobblingEntity import org.koitharu.kotatsu.scrobbling.common.data.ScrobblingEntity
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerManga import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerManga
@@ -32,13 +35,17 @@ private const val REQUEST_MUTATION = "mutation"
private const val KEY_SCORE_FORMAT = "score_format" private const val KEY_SCORE_FORMAT = "score_format"
class AniListRepository( class AniListRepository(
@ApplicationContext context: Context,
private val okHttp: OkHttpClient, private val okHttp: OkHttpClient,
private val storage: ScrobblerStorage, private val storage: ScrobblerStorage,
private val db: MangaDatabase, private val db: MangaDatabase,
) : org.koitharu.kotatsu.scrobbling.common.data.ScrobblerRepository { ) : ScrobblerRepository {
private val clientId = context.getString(R.string.anilist_clientId)
private val clientSecret = context.getString(R.string.anilist_clientSecret)
override val oauthUrl: String override val oauthUrl: String
get() = "${BASE_URL}oauth/authorize?client_id=${BuildConfig.ANILIST_CLIENT_ID}&" + get() = "${BASE_URL}oauth/authorize?client_id=$clientId&" +
"redirect_uri=${REDIRECT_URI}&response_type=code" "redirect_uri=${REDIRECT_URI}&response_type=code"
override val isAuthorized: Boolean override val isAuthorized: Boolean
@@ -48,8 +55,8 @@ class AniListRepository(
override suspend fun authorize(code: String?) { override suspend fun authorize(code: String?) {
val body = FormBody.Builder() val body = FormBody.Builder()
body.add("client_id", BuildConfig.ANILIST_CLIENT_ID) body.add("client_id", clientId)
body.add("client_secret", BuildConfig.ANILIST_CLIENT_SECRET) body.add("client_secret", clientSecret)
if (code != null) { if (code != null) {
body.add("grant_type", "authorization_code") body.add("grant_type", "authorization_code")
body.add("redirect_uri", REDIRECT_URI) body.add("redirect_uri", REDIRECT_URI)

View File

@@ -1,16 +1,19 @@
package org.koitharu.kotatsu.scrobbling.mal.data package org.koitharu.kotatsu.scrobbling.mal.data
import android.content.Context
import dagger.hilt.android.qualifiers.ApplicationContext
import okhttp3.FormBody import okhttp3.FormBody
import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import org.json.JSONObject import org.json.JSONObject
import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.db.MangaDatabase import org.koitharu.kotatsu.core.db.MangaDatabase
import org.koitharu.kotatsu.parsers.model.MangaChapter import org.koitharu.kotatsu.parsers.model.MangaChapter
import org.koitharu.kotatsu.parsers.util.await import org.koitharu.kotatsu.parsers.util.await
import org.koitharu.kotatsu.parsers.util.json.mapJSONNotNull import org.koitharu.kotatsu.parsers.util.json.mapJSONNotNull
import org.koitharu.kotatsu.parsers.util.parseJson import org.koitharu.kotatsu.parsers.util.parseJson
import org.koitharu.kotatsu.scrobbling.common.data.ScrobblerRepository
import org.koitharu.kotatsu.scrobbling.common.data.ScrobblerStorage import org.koitharu.kotatsu.scrobbling.common.data.ScrobblerStorage
import org.koitharu.kotatsu.scrobbling.common.data.ScrobblingEntity import org.koitharu.kotatsu.scrobbling.common.data.ScrobblingEntity
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerManga import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerManga
@@ -25,17 +28,19 @@ private const val BASE_API_URL = "https://api.myanimelist.net/v2"
private const val AVATAR_STUB = "https://cdn.myanimelist.net/images/questionmark_50.gif" private const val AVATAR_STUB = "https://cdn.myanimelist.net/images/questionmark_50.gif"
class MALRepository( class MALRepository(
@ApplicationContext context: Context,
private val okHttp: OkHttpClient, private val okHttp: OkHttpClient,
private val storage: ScrobblerStorage, private val storage: ScrobblerStorage,
private val db: MangaDatabase, private val db: MangaDatabase,
) : org.koitharu.kotatsu.scrobbling.common.data.ScrobblerRepository { ) : ScrobblerRepository {
private val clientId = context.getString(R.string.mal_clientId)
private var codeVerifier: String = getPKCEChallengeCode() private var codeVerifier: String = getPKCEChallengeCode()
override val oauthUrl: String override val oauthUrl: String
get() = "$BASE_WEB_URL/v1/oauth2/authorize?" + get() = "$BASE_WEB_URL/v1/oauth2/authorize?" +
"response_type=code" + "response_type=code" +
"&client_id=${BuildConfig.MAL_CLIENT_ID}" + "&client_id=$clientId" +
"&redirect_uri=$REDIRECT_URI" + "&redirect_uri=$REDIRECT_URI" +
"&code_challenge=$codeVerifier" + "&code_challenge=$codeVerifier" +
"&code_challenge_method=plain" "&code_challenge_method=plain"
@@ -51,7 +56,7 @@ class MALRepository(
override suspend fun authorize(code: String?) { override suspend fun authorize(code: String?) {
val body = FormBody.Builder() val body = FormBody.Builder()
if (code != null) { if (code != null) {
body.add("client_id", BuildConfig.MAL_CLIENT_ID) body.add("client_id", clientId)
body.add("grant_type", "authorization_code") body.add("grant_type", "authorization_code")
body.add("code", code) body.add("code", code)
body.add("redirect_uri", REDIRECT_URI) body.add("redirect_uri", REDIRECT_URI)
@@ -205,5 +210,4 @@ class MALRepository(
avatar = json.getString("picture") ?: AVATAR_STUB, avatar = json.getString("picture") ?: AVATAR_STUB,
service = ScrobblerService.MAL, service = ScrobblerService.MAL,
) )
} }

View File

@@ -1,11 +1,13 @@
package org.koitharu.kotatsu.scrobbling.shikimori.data package org.koitharu.kotatsu.scrobbling.shikimori.data
import android.content.Context
import dagger.hilt.android.qualifiers.ApplicationContext
import okhttp3.FormBody import okhttp3.FormBody
import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import org.json.JSONObject import org.json.JSONObject
import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.db.MangaDatabase import org.koitharu.kotatsu.core.db.MangaDatabase
import org.koitharu.kotatsu.parsers.model.MangaChapter import org.koitharu.kotatsu.parsers.model.MangaChapter
import org.koitharu.kotatsu.parsers.util.await import org.koitharu.kotatsu.parsers.util.await
@@ -28,13 +30,17 @@ private const val BASE_URL = "https://shikimori.one/"
private const val MANGA_PAGE_SIZE = 10 private const val MANGA_PAGE_SIZE = 10
class ShikimoriRepository( class ShikimoriRepository(
@ApplicationContext context: Context,
private val okHttp: OkHttpClient, private val okHttp: OkHttpClient,
private val storage: ScrobblerStorage, private val storage: ScrobblerStorage,
private val db: MangaDatabase, private val db: MangaDatabase,
) : ScrobblerRepository { ) : ScrobblerRepository {
private val clientId = context.getString(R.string.shikimori_clientId)
private val clientSecret = context.getString(R.string.shikimori_clientSecret)
override val oauthUrl: String override val oauthUrl: String
get() = "${BASE_URL}oauth/authorize?client_id=${BuildConfig.SHIKIMORI_CLIENT_ID}&" + get() = "${BASE_URL}oauth/authorize?client_id=$clientId&" +
"redirect_uri=$REDIRECT_URI&response_type=code&scope=" "redirect_uri=$REDIRECT_URI&response_type=code&scope="
override val isAuthorized: Boolean override val isAuthorized: Boolean
@@ -42,8 +48,8 @@ class ShikimoriRepository(
override suspend fun authorize(code: String?) { override suspend fun authorize(code: String?) {
val body = FormBody.Builder() val body = FormBody.Builder()
body.add("client_id", BuildConfig.SHIKIMORI_CLIENT_ID) body.add("client_id", clientId)
body.add("client_secret", BuildConfig.SHIKIMORI_CLIENT_SECRET) body.add("client_secret", clientSecret)
if (code != null) { if (code != null) {
body.add("grant_type", "authorization_code") body.add("grant_type", "authorization_code")
body.add("redirect_uri", REDIRECT_URI) body.add("redirect_uri", REDIRECT_URI)
@@ -98,13 +104,13 @@ class ShikimoriRepository(
return if (pageOffset != 0) list.drop(pageOffset) else list return if (pageOffset != 0) list.drop(pageOffset) else list
} }
override suspend fun createRate(mangaId: Long, shikiMangaId: Long) { override suspend fun createRate(mangaId: Long, scrobblerMangaId: Long) {
val user = cachedUser ?: loadUser() val user = cachedUser ?: loadUser()
val payload = JSONObject() val payload = JSONObject()
payload.put( payload.put(
"user_rate", "user_rate",
JSONObject().apply { JSONObject().apply {
put("target_id", shikiMangaId) put("target_id", scrobblerMangaId)
put("target_type", "Manga") put("target_type", "Manga")
put("user_id", user.id) put("user_id", user.id)
}, },

View File

@@ -9,6 +9,13 @@
<string name="url_error_report" translatable="false">https://acra.rumblur.space/report</string> <string name="url_error_report" translatable="false">https://acra.rumblur.space/report</string>
<string name="account_type_sync" translatable="false">org.kotatsu.sync</string> <string name="account_type_sync" translatable="false">org.kotatsu.sync</string>
<string name="url_sync_server" translatable="false">http://86.57.183.214:8081</string> <string name="url_sync_server" translatable="false">http://86.57.183.214:8081</string>
<string name="shikimori_clientId" translatable="false">Mw6F0tPEOgyV7F9U9Twg50Q8SndMY7hzIOfXg0AX_XU</string>
<string name="shikimori_clientSecret" translatable="false">euBMt1GGRSDpVIFQVPxZrO7Kh6X4gWyv0dABuj4B-M8</string>
<string name="anilist_clientId" translatable="false">9887</string>
<string name="anilist_clientSecret" translatable="false">wrMqFosItQWsmB8dtAHfIFPDt15FfQi2ZGiKkJoW</string>
<string name="mal_clientId" translatable="false">6cd8e6349e9a36bc1fc1ab97703c9fd1</string>
<string name="acra_login" translatable="false">SxhkCVnqVLbGogvi</string>
<string name="acra_password" translatable="false">xPDACTLHnHU9Nfjv</string>
<string-array name="values_theme" translatable="false"> <string-array name="values_theme" translatable="false">
<item>-1</item> <item>-1</item>
<item>1</item> <item>1</item>

View File

@@ -20,15 +20,6 @@ allprojects {
} }
} }
String localProperty(String name, String defaultValue = 'null') {
Properties localProperties = new Properties()
project.rootProject.file('local.properties').withInputStream { localProperties.load(it) }
def value = localProperties[name]
return value != null ? value : defaultValue
}
String currentBranch() { String currentBranch() {
def branchName = "" def branchName = ""
try { try {