move custm api permission methods into helper class (composition over inheritance)
This commit is contained in:
@@ -17,9 +17,14 @@
|
||||
|
||||
package org.sufficientlysecure.keychain.remote;
|
||||
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
@@ -38,15 +43,21 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||
import org.sufficientlysecure.keychain.remote.ui.RemoteServiceActivity;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Abstract service class for remote APIs that handle app registration and user input.
|
||||
*/
|
||||
public abstract class RemoteService extends Service {
|
||||
public class ApiPermissionHelper {
|
||||
|
||||
private final Context mContext;
|
||||
private final ProviderHelper mProviderHelper;
|
||||
private PackageManager mPackageManager;
|
||||
|
||||
public ApiPermissionHelper(Context context) {
|
||||
mContext = context;
|
||||
mPackageManager = context.getPackageManager();
|
||||
mProviderHelper = new ProviderHelper(context);
|
||||
}
|
||||
|
||||
public static class WrongPackageCertificateException extends Exception {
|
||||
private static final long serialVersionUID = -8294642703122196028L;
|
||||
@@ -56,13 +67,6 @@ public abstract class RemoteService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
Context mContext;
|
||||
ProviderHelper mProviderHelper;
|
||||
|
||||
public Context getContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if caller is allowed to access the API
|
||||
*
|
||||
@@ -90,13 +94,13 @@ public abstract class RemoteService extends Service {
|
||||
}
|
||||
Log.e(Constants.TAG, "Not allowed to use service! return PendingIntent for registration!");
|
||||
|
||||
Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
|
||||
Intent intent = new Intent(mContext, RemoteServiceActivity.class);
|
||||
intent.setAction(RemoteServiceActivity.ACTION_REGISTER);
|
||||
intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName);
|
||||
intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_SIGNATURE, packageCertificate);
|
||||
intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
|
||||
|
||||
PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0,
|
||||
PendingIntent pi = PendingIntent.getActivity(mContext, 0,
|
||||
intent,
|
||||
PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
|
||||
|
||||
@@ -110,13 +114,13 @@ public abstract class RemoteService extends Service {
|
||||
} catch (WrongPackageCertificateException e) {
|
||||
Log.e(Constants.TAG, "wrong signature!", e);
|
||||
|
||||
Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
|
||||
Intent intent = new Intent(mContext, RemoteServiceActivity.class);
|
||||
intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE);
|
||||
intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE,
|
||||
getString(R.string.api_error_wrong_signature));
|
||||
mContext.getString(R.string.api_error_wrong_signature));
|
||||
intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
|
||||
|
||||
PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0,
|
||||
PendingIntent pi = PendingIntent.getActivity(mContext, 0,
|
||||
intent,
|
||||
PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
|
||||
@@ -131,7 +135,7 @@ public abstract class RemoteService extends Service {
|
||||
|
||||
private byte[] getPackageCertificate(String packageName) throws NameNotFoundException {
|
||||
@SuppressLint("PackageManagerGetSignatures") // we do check the byte array of *all* signatures
|
||||
PackageInfo pkgInfo = getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
|
||||
PackageInfo pkgInfo = mContext.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
|
||||
// NOTE: Silly Android API naming: Signatures are actually certificates
|
||||
Signature[] certificates = pkgInfo.signatures;
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
@@ -156,7 +160,7 @@ public abstract class RemoteService extends Service {
|
||||
* @return package name
|
||||
*/
|
||||
protected String getCurrentCallingPackage() {
|
||||
String[] callingPackages = getPackageManager().getPackagesForUid(Binder.getCallingUid());
|
||||
String[] callingPackages = mPackageManager.getPackagesForUid(Binder.getCallingUid());
|
||||
|
||||
// NOTE: No support for sharedUserIds
|
||||
// callingPackages contains more than one entry when sharedUserId has been used
|
||||
@@ -189,13 +193,13 @@ public abstract class RemoteService extends Service {
|
||||
String packageName = getCurrentCallingPackage();
|
||||
Log.d(Constants.TAG, "getCreateAccountIntent accountName: " + accountName);
|
||||
|
||||
Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
|
||||
Intent intent = new Intent(mContext, RemoteServiceActivity.class);
|
||||
intent.setAction(RemoteServiceActivity.ACTION_CREATE_ACCOUNT);
|
||||
intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName);
|
||||
intent.putExtra(RemoteServiceActivity.EXTRA_ACC_NAME, accountName);
|
||||
intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
|
||||
|
||||
PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0,
|
||||
PendingIntent pi = PendingIntent.getActivity(mContext, 0,
|
||||
intent,
|
||||
PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
|
||||
@@ -221,7 +225,7 @@ public abstract class RemoteService extends Service {
|
||||
private boolean isUidAllowed(int uid)
|
||||
throws WrongPackageCertificateException {
|
||||
|
||||
String[] callingPackages = getPackageManager().getPackagesForUid(uid);
|
||||
String[] callingPackages = mPackageManager.getPackagesForUid(uid);
|
||||
|
||||
// is calling package allowed to use this service?
|
||||
for (String currentPkg : callingPackages) {
|
||||
@@ -273,11 +277,4 @@ public abstract class RemoteService extends Service {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
mContext = this;
|
||||
mProviderHelper = new ProviderHelper(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,6 +18,7 @@
|
||||
package org.sufficientlysecure.keychain.remote;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
@@ -74,7 +75,7 @@ import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class OpenPgpService extends RemoteService {
|
||||
public class OpenPgpService extends Service {
|
||||
|
||||
static final String[] EMAIL_SEARCH_PROJECTION = new String[]{
|
||||
KeyRings._ID,
|
||||
@@ -87,6 +88,16 @@ public class OpenPgpService extends RemoteService {
|
||||
static final String EMAIL_SEARCH_WHERE = Tables.KEYS + "." + KeychainContract.KeyRings.IS_REVOKED
|
||||
+ " = 0 AND " + KeychainContract.KeyRings.IS_EXPIRED + " = 0";
|
||||
|
||||
private ApiPermissionHelper mApiPermissionHelper;
|
||||
private ProviderHelper mProviderHelper;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
mApiPermissionHelper = new ApiPermissionHelper(this);
|
||||
mProviderHelper = new ProviderHelper(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search database for key ids based on emails.
|
||||
*/
|
||||
@@ -225,7 +236,7 @@ public class OpenPgpService extends RemoteService {
|
||||
// to retrieve the missing key
|
||||
Intent intent = new Intent(getBaseContext(), SelectAllowedKeysActivity.class);
|
||||
intent.putExtra(SelectAllowedKeysActivity.EXTRA_SERVICE_INTENT, data);
|
||||
intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(getCurrentCallingPackage()));
|
||||
intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(mApiPermissionHelper.getCurrentCallingPackage()));
|
||||
|
||||
return PendingIntent.getActivity(getBaseContext(), 0,
|
||||
intent,
|
||||
@@ -297,7 +308,7 @@ public class OpenPgpService extends RemoteService {
|
||||
}
|
||||
|
||||
// execute PGP operation!
|
||||
PgpSignEncryptOperation pse = new PgpSignEncryptOperation(this, new ProviderHelper(getContext()), null);
|
||||
PgpSignEncryptOperation pse = new PgpSignEncryptOperation(this, new ProviderHelper(this), null);
|
||||
PgpSignEncryptResult pgpResult = pse.execute(pseInput, inputParcel, inputData, outputStream);
|
||||
|
||||
if (pgpResult.isPending()) {
|
||||
@@ -414,9 +425,9 @@ public class OpenPgpService extends RemoteService {
|
||||
if (TextUtils.isEmpty(accName)) {
|
||||
accName = "default";
|
||||
}
|
||||
final AccountSettings accSettings = getAccSettings(accName);
|
||||
final AccountSettings accSettings = mApiPermissionHelper.getAccSettings(accName);
|
||||
if (accSettings == null || (accSettings.getKeyId() == Constants.key.none)) {
|
||||
return getCreateAccountIntent(data, accName);
|
||||
return mApiPermissionHelper.getCreateAccountIntent(data, accName);
|
||||
}
|
||||
pseInput.setAdditionalEncryptId(accSettings.getKeyId());
|
||||
}
|
||||
@@ -431,7 +442,7 @@ public class OpenPgpService extends RemoteService {
|
||||
new Passphrase(data.getCharArrayExtra(OpenPgpApi.EXTRA_PASSPHRASE));
|
||||
}
|
||||
|
||||
PgpSignEncryptOperation op = new PgpSignEncryptOperation(this, new ProviderHelper(getContext()), null);
|
||||
PgpSignEncryptOperation op = new PgpSignEncryptOperation(this, mProviderHelper, null);
|
||||
|
||||
// execute PGP operation!
|
||||
PgpSignEncryptResult pgpResult = op.execute(pseInput, inputParcel, inputData, outputStream);
|
||||
@@ -472,7 +483,7 @@ public class OpenPgpService extends RemoteService {
|
||||
outputStream = null;
|
||||
}
|
||||
|
||||
String currentPkg = getCurrentCallingPackage();
|
||||
String currentPkg = mApiPermissionHelper.getCurrentCallingPackage();
|
||||
HashSet<Long> allowedKeyIds = mProviderHelper.getAllowedKeyIdsForApp(
|
||||
KeychainContract.ApiAllowedKeys.buildBaseUri(currentPkg));
|
||||
|
||||
@@ -695,7 +706,7 @@ public class OpenPgpService extends RemoteService {
|
||||
String preferredUserId = data.getStringExtra(OpenPgpApi.EXTRA_USER_ID);
|
||||
|
||||
Intent intent = new Intent(getBaseContext(), SelectSignKeyIdActivity.class);
|
||||
String currentPkg = getCurrentCallingPackage();
|
||||
String currentPkg = mApiPermissionHelper.getCurrentCallingPackage();
|
||||
intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(currentPkg));
|
||||
intent.putExtra(SelectSignKeyIdActivity.EXTRA_USER_ID, preferredUserId);
|
||||
intent.putExtra(SelectSignKeyIdActivity.EXTRA_DATA, data);
|
||||
@@ -740,9 +751,9 @@ public class OpenPgpService extends RemoteService {
|
||||
}
|
||||
Log.d(Constants.TAG, "accName: " + accName);
|
||||
// fallback to old API
|
||||
final AccountSettings accSettings = getAccSettings(accName);
|
||||
final AccountSettings accSettings = mApiPermissionHelper.getAccSettings(accName);
|
||||
if (accSettings == null || (accSettings.getKeyId() == Constants.key.none)) {
|
||||
return getCreateAccountIntent(data, accName);
|
||||
return mApiPermissionHelper.getCreateAccountIntent(data, accName);
|
||||
}
|
||||
|
||||
// NOTE: just wrapping the key id
|
||||
@@ -792,7 +803,7 @@ public class OpenPgpService extends RemoteService {
|
||||
}
|
||||
|
||||
// check if caller is allowed to access OpenKeychain
|
||||
Intent result = isAllowed(data);
|
||||
Intent result = mApiPermissionHelper.isAllowed(data);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user