moved some code out of common library

This commit is contained in:
Mariotaku Lee 2017-05-25 10:33:19 +08:00
parent 53d9ce3f77
commit 647767e436
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
11 changed files with 118 additions and 182 deletions

View File

@ -1,98 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mariotaku.twidere.util;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import org.mariotaku.microblog.library.twitter.model.User;
import org.mariotaku.twidere.common.R;
import org.mariotaku.twidere.model.ConsumerKeyType;
import java.nio.charset.Charset;
import java.util.zip.CRC32;
/**
* Created by mariotaku on 15/1/11.
*/
public class TwitterContentUtils {
private TwitterContentUtils() {
}
public static boolean isOfficialKey(final Context context, final String consumerKey,
final String consumerSecret) {
if (context == null || consumerKey == null || consumerSecret == null) return false;
final String[] keySecrets = context.getResources().getStringArray(R.array.values_official_consumer_secret_crc32);
final CRC32 crc32 = new CRC32();
final byte[] consumerSecretBytes = consumerSecret.getBytes(Charset.forName("UTF-8"));
crc32.update(consumerSecretBytes, 0, consumerSecretBytes.length);
final long value = crc32.getValue();
crc32.reset();
for (final String keySecret : keySecrets) {
if (Long.parseLong(keySecret, 16) == value) return true;
}
return false;
}
public static String getOfficialKeyName(final Context context, final String consumerKey,
final String consumerSecret) {
if (context == null || consumerKey == null || consumerSecret == null) return null;
final String[] keySecrets = context.getResources().getStringArray(R.array.values_official_consumer_secret_crc32);
final String[] keyNames = context.getResources().getStringArray(R.array.names_official_consumer_secret);
final CRC32 crc32 = new CRC32();
final byte[] consumerSecretBytes = consumerSecret.getBytes(Charset.forName("UTF-8"));
crc32.update(consumerSecretBytes, 0, consumerSecretBytes.length);
final long value = crc32.getValue();
crc32.reset();
for (int i = 0, j = keySecrets.length; i < j; i++) {
if (Long.parseLong(keySecrets[i], 16) == value) return keyNames[i];
}
return null;
}
@NonNull
public static ConsumerKeyType getOfficialKeyType(final Context context, final String consumerKey,
final String consumerSecret) {
if (context == null || consumerKey == null || consumerSecret == null) {
return ConsumerKeyType.UNKNOWN;
}
final String[] keySecrets = context.getResources().getStringArray(R.array.values_official_consumer_secret_crc32);
final String[] keyNames = context.getResources().getStringArray(R.array.types_official_consumer_secret);
final CRC32 crc32 = new CRC32();
final byte[] consumerSecretBytes = consumerSecret.getBytes(Charset.forName("UTF-8"));
crc32.update(consumerSecretBytes, 0, consumerSecretBytes.length);
final long value = crc32.getValue();
crc32.reset();
for (int i = 0, j = keySecrets.length; i < j; i++) {
if (Long.parseLong(keySecrets[i], 16) == value) {
return ConsumerKeyType.parse(keyNames[i]);
}
}
return ConsumerKeyType.UNKNOWN;
}
public static String getProfileImageUrl(@Nullable User user) {
if (user == null) return null;
return TextUtils.isEmpty(user.getProfileImageUrlHttps()) ? user.getProfileImageUrl() : user.getProfileImageUrlHttps();
}
}

View File

@ -1,70 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Twidere - Twitter client for Android
~
~ Copyright 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<resources>
<!-- CRC32 checksum of consumer secret of official clients to check whether user is using official keys -->
<string-array name="values_official_consumer_secret_crc32">
<!--Twitter for Android-->
<item>6ce85096</item>
<!--Twitter for iPhone-->
<item>deffe9c7</item>
<!--Twitter for iPad-->
<item>9f00e0cb</item>
<!--Twitter for Mac-->
<item>df27640e</item>
<!--Twitter for Windows Phone-->
<item>62bd0d33</item>
<!--Twitter for Google TV-->
<item>56d8f9ff</item>
<!--TweetDeck-->
<item>ac602936</item>
</string-array>
<string-array name="names_official_consumer_secret">
<!--Twitter for Android-->
<item>Twitter for Android</item>
<!--Twitter for iPhone-->
<item>Twitter for iPhone</item>
<!--Twitter for iPad-->
<item>Twitter for iPad</item>
<!--Twitter for Mac-->
<item>Twitter for Mac</item>
<!--Twitter for Windows Phone-->
<item>Twitter for Windows Phone</item>
<!--Twitter for Google TV-->
<item>Twitter for Google TV</item>
<!--TweetDeck-->
<item>TweetDeck</item>
</string-array>
<string-array name="types_official_consumer_secret">
<!--Twitter for Android-->
<item>TWITTER_FOR_ANDROID</item>
<!--Twitter for iPhone-->
<item>TWITTER_FOR_IPHONE</item>
<!--Twitter for iPad-->
<item>TWITTER_FOR_IPAD</item>
<!--Twitter for Mac-->
<item>TWITTER_FOR_MAC</item>
<!--Twitter for Windows Phone-->
<item>TWITTER_FOR_WINDOWS_PHONE</item>
<!--Twitter for Google TV-->
<item>TWITTER_FOR_GOOGLE_TV</item>
<!--TweetDeck-->
<item>TWEETDECK</item>
</string-array>
</resources>

View File

@ -1,5 +1,6 @@
package org.mariotaku.twidere.util;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.annotation.NonNull;
@ -14,12 +15,17 @@ import org.mariotaku.microblog.library.twitter.model.DirectMessage;
import org.mariotaku.microblog.library.twitter.model.MediaEntity;
import org.mariotaku.microblog.library.twitter.model.UrlEntity;
import org.mariotaku.microblog.library.twitter.model.User;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.extension.model.api.StatusExtensionsKt;
import org.mariotaku.twidere.model.ConsumerKeyType;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.model.SpanItem;
import org.mariotaku.twidere.model.UserKey;
import org.mariotaku.twidere.util.database.FilterQueryBuilder;
import java.nio.charset.Charset;
import java.util.zip.CRC32;
import kotlin.Pair;
/**
@ -146,4 +152,55 @@ public class InternalTwitterContentUtils {
}
public static boolean isOfficialKey(final Context context, final String consumerKey,
final String consumerSecret) {
if (context == null || consumerKey == null || consumerSecret == null) return false;
final String[] keySecrets = context.getResources().getStringArray(R.array.values_official_consumer_secret_crc32);
final CRC32 crc32 = new CRC32();
final byte[] consumerSecretBytes = consumerSecret.getBytes(Charset.forName("UTF-8"));
crc32.update(consumerSecretBytes, 0, consumerSecretBytes.length);
final long value = crc32.getValue();
crc32.reset();
for (final String keySecret : keySecrets) {
if (Long.parseLong(keySecret, 16) == value) return true;
}
return false;
}
public static String getOfficialKeyName(final Context context, final String consumerKey,
final String consumerSecret) {
if (context == null || consumerKey == null || consumerSecret == null) return null;
final String[] keySecrets = context.getResources().getStringArray(R.array.values_official_consumer_secret_crc32);
final String[] keyNames = context.getResources().getStringArray(R.array.names_official_consumer_secret);
final CRC32 crc32 = new CRC32();
final byte[] consumerSecretBytes = consumerSecret.getBytes(Charset.forName("UTF-8"));
crc32.update(consumerSecretBytes, 0, consumerSecretBytes.length);
final long value = crc32.getValue();
crc32.reset();
for (int i = 0, j = keySecrets.length; i < j; i++) {
if (Long.parseLong(keySecrets[i], 16) == value) return keyNames[i];
}
return null;
}
@NonNull
public static ConsumerKeyType getOfficialKeyType(final Context context, final String consumerKey,
final String consumerSecret) {
if (context == null || consumerKey == null || consumerSecret == null) {
return ConsumerKeyType.UNKNOWN;
}
final String[] keySecrets = context.getResources().getStringArray(R.array.values_official_consumer_secret_crc32);
final String[] keyNames = context.getResources().getStringArray(R.array.types_official_consumer_secret);
final CRC32 crc32 = new CRC32();
final byte[] consumerSecretBytes = consumerSecret.getBytes(Charset.forName("UTF-8"));
crc32.update(consumerSecretBytes, 0, consumerSecretBytes.length);
final long value = crc32.getValue();
crc32.reset();
for (int i = 0, j = keySecrets.length; i < j; i++) {
if (Long.parseLong(keySecrets[i], 16) == value) {
return ConsumerKeyType.parse(keyNames[i]);
}
}
return ConsumerKeyType.UNKNOWN;
}
}

View File

@ -20,11 +20,9 @@ package org.mariotaku.twidere.util;
import android.graphics.Color;
import org.mariotaku.twidere.TwidereConstants;
import static android.text.TextUtils.isEmpty;
public final class ParseUtils implements TwidereConstants {
public final class ParseUtils {
private ParseUtils() {
}

View File

@ -41,10 +41,10 @@ public class PermissionsManager implements Constants {
private final SharedPreferences preferences;
private final PackageManager packageManager;
private final Context mContext;
private final Context context;
public PermissionsManager(final Context context) {
mContext = context;
this.context = context;
preferences = context.getSharedPreferences(PERMISSION_PREFERENCES_NAME, Context.MODE_PRIVATE);
packageManager = context.getPackageManager();
}
@ -71,7 +71,7 @@ public class PermissionsManager implements Constants {
public boolean checkPermission(final String packageName, final String... requiredPermissions) {
if (requiredPermissions == null || requiredPermissions.length == 0) return true;
if (mContext.getPackageName().equals(packageName)) return true;
if (context.getPackageName().equals(packageName)) return true;
if (checkSignature(packageName)) return true;
final String[] permissions = getPermissions(packageName);
return TwidereArrayUtils.contains(permissions, requiredPermissions);
@ -82,9 +82,9 @@ public class PermissionsManager implements Constants {
}
public boolean checkSignature(final String pname) {
if (mContext.getPackageName().equals(pname)) return true;
if (context.getPackageName().equals(pname)) return true;
if (BuildConfig.DEBUG) return false;
return packageManager.checkSignatures(pname, mContext.getPackageName()) == PackageManager.SIGNATURE_MATCH;
return packageManager.checkSignatures(pname, context.getPackageName()) == PackageManager.SIGNATURE_MATCH;
}
public boolean deny(final String packageName) {

View File

@ -11,7 +11,7 @@ import org.mariotaku.twidere.model.account.TwitterAccountExtras
import org.mariotaku.twidere.model.account.cred.Credentials
import org.mariotaku.twidere.model.account.cred.OAuthCredentials
import org.mariotaku.twidere.task.twitter.UpdateStatusTask
import org.mariotaku.twidere.util.TwitterContentUtils
import org.mariotaku.twidere.util.InternalTwitterContentUtils
fun AccountDetails.isOfficial(context: Context): Boolean {
val extra = this.extras
@ -20,7 +20,7 @@ fun AccountDetails.isOfficial(context: Context): Boolean {
}
val credentials = this.credentials
if (credentials is OAuthCredentials) {
return TwitterContentUtils.isOfficialKey(context,
return InternalTwitterContentUtils.isOfficialKey(context,
credentials.consumer_key, credentials.consumer_secret)
}
return false

View File

@ -19,9 +19,9 @@ import org.mariotaku.twidere.model.account.TwitterAccountExtras
import org.mariotaku.twidere.model.account.cred.*
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.model.util.AccountUtils.ACCOUNT_USER_DATA_KEYS
import org.mariotaku.twidere.util.InternalTwitterContentUtils
import org.mariotaku.twidere.util.JsonSerializer
import org.mariotaku.twidere.util.ParseUtils
import org.mariotaku.twidere.util.TwitterContentUtils
import org.mariotaku.twidere.util.model.AccountDetailsUtils
import java.io.IOException
import java.util.concurrent.Callable
@ -107,7 +107,7 @@ fun Account.isOfficial(am: AccountManager, context: Context): Boolean {
}
val credentials = getCredentials(am)
if (credentials is OAuthCredentials) {
return TwitterContentUtils.isOfficialKey(context, credentials.consumer_key,
return InternalTwitterContentUtils.isOfficialKey(context, credentials.consumer_key,
credentials.consumer_secret)
}
return false

View File

@ -25,10 +25,10 @@ import org.mariotaku.twidere.TwidereConstants.DEFAULT_TWITTER_API_URL_FORMAT
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.model.account.cred.*
import org.mariotaku.twidere.util.HttpClientFactory
import org.mariotaku.twidere.util.InternalTwitterContentUtils
import org.mariotaku.twidere.util.MicroBlogAPIFactory
import org.mariotaku.twidere.util.MicroBlogAPIFactory.sFanfouConstantPool
import org.mariotaku.twidere.util.MicroBlogAPIFactory.sTwitterConstantPool
import org.mariotaku.twidere.util.TwitterContentUtils
import org.mariotaku.twidere.util.api.*
import org.mariotaku.twidere.util.dagger.DependencyHolder
import org.mariotaku.twidere.util.media.TwidereMediaDownloader
@ -148,7 +148,7 @@ fun <T> newMicroBlogInstance(context: Context, endpoint: Endpoint, auth: Authori
val factory = RestAPIFactory<MicroBlogException>()
val extraHeaders = run {
if (auth !is OAuthAuthorization) return@run null
val officialKeyType = TwitterContentUtils.getOfficialKeyType(context,
val officialKeyType = InternalTwitterContentUtils.getOfficialKeyType(context,
auth.consumerKey, auth.consumerSecret)
return@run MicroBlogAPIFactory.getExtraHeaders(context, officialKeyType)
} ?: UserAgentExtraHeaders(MicroBlogAPIFactory.getTwidereUserAgent(context))

View File

@ -109,4 +109,53 @@
<item>replies</item>
<item>retweets</item>
</string-array>
<!-- CRC32 checksum of consumer secret of official clients to check whether user is using official keys -->
<string-array name="values_official_consumer_secret_crc32">
<!--Twitter for Android-->
<item>6ce85096</item>
<!--Twitter for iPhone-->
<item>deffe9c7</item>
<!--Twitter for iPad-->
<item>9f00e0cb</item>
<!--Twitter for Mac-->
<item>df27640e</item>
<!--Twitter for Windows Phone-->
<item>62bd0d33</item>
<!--Twitter for Google TV-->
<item>56d8f9ff</item>
<!--TweetDeck-->
<item>ac602936</item>
</string-array>
<string-array name="names_official_consumer_secret">
<!--Twitter for Android-->
<item>Twitter for Android</item>
<!--Twitter for iPhone-->
<item>Twitter for iPhone</item>
<!--Twitter for iPad-->
<item>Twitter for iPad</item>
<!--Twitter for Mac-->
<item>Twitter for Mac</item>
<!--Twitter for Windows Phone-->
<item>Twitter for Windows Phone</item>
<!--Twitter for Google TV-->
<item>Twitter for Google TV</item>
<!--TweetDeck-->
<item>TweetDeck</item>
</string-array>
<string-array name="types_official_consumer_secret">
<!--Twitter for Android-->
<item>TWITTER_FOR_ANDROID</item>
<!--Twitter for iPhone-->
<item>TWITTER_FOR_IPHONE</item>
<!--Twitter for iPad-->
<item>TWITTER_FOR_IPAD</item>
<!--Twitter for Mac-->
<item>TWITTER_FOR_MAC</item>
<!--Twitter for Windows Phone-->
<item>TWITTER_FOR_WINDOWS_PHONE</item>
<!--Twitter for Google TV-->
<item>TWITTER_FOR_GOOGLE_TV</item>
<!--TweetDeck-->
<item>TWEETDECK</item>
</string-array>
</resources>