move custm api permission methods into helper class (composition over inheritance)

This commit is contained in:
Vincent Breitmoser
2015-11-27 23:40:04 +01:00
parent 984c91d62c
commit df219b61c6
2 changed files with 49 additions and 41 deletions

View File

@@ -17,9 +17,14 @@
package org.sufficientlysecure.keychain.remote; 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.annotation.SuppressLint;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.app.Service;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageInfo; 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.remote.ui.RemoteServiceActivity;
import org.sufficientlysecure.keychain.util.Log; 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. * 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 { public static class WrongPackageCertificateException extends Exception {
private static final long serialVersionUID = -8294642703122196028L; 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 * 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!"); 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.setAction(RemoteServiceActivity.ACTION_REGISTER);
intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName); intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName);
intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_SIGNATURE, packageCertificate); intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_SIGNATURE, packageCertificate);
intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, PendingIntent pi = PendingIntent.getActivity(mContext, 0,
intent, intent,
PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT); PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
@@ -110,13 +114,13 @@ public abstract class RemoteService extends Service {
} catch (WrongPackageCertificateException e) { } catch (WrongPackageCertificateException e) {
Log.e(Constants.TAG, "wrong signature!", 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.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE);
intent.putExtra(RemoteServiceActivity.EXTRA_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); intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, PendingIntent pi = PendingIntent.getActivity(mContext, 0,
intent, intent,
PendingIntent.FLAG_CANCEL_CURRENT); PendingIntent.FLAG_CANCEL_CURRENT);
@@ -131,7 +135,7 @@ public abstract class RemoteService extends Service {
private byte[] getPackageCertificate(String packageName) throws NameNotFoundException { private byte[] getPackageCertificate(String packageName) throws NameNotFoundException {
@SuppressLint("PackageManagerGetSignatures") // we do check the byte array of *all* signatures @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 // NOTE: Silly Android API naming: Signatures are actually certificates
Signature[] certificates = pkgInfo.signatures; Signature[] certificates = pkgInfo.signatures;
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
@@ -156,7 +160,7 @@ public abstract class RemoteService extends Service {
* @return package name * @return package name
*/ */
protected String getCurrentCallingPackage() { protected String getCurrentCallingPackage() {
String[] callingPackages = getPackageManager().getPackagesForUid(Binder.getCallingUid()); String[] callingPackages = mPackageManager.getPackagesForUid(Binder.getCallingUid());
// NOTE: No support for sharedUserIds // NOTE: No support for sharedUserIds
// callingPackages contains more than one entry when sharedUserId has been used // callingPackages contains more than one entry when sharedUserId has been used
@@ -189,13 +193,13 @@ public abstract class RemoteService extends Service {
String packageName = getCurrentCallingPackage(); String packageName = getCurrentCallingPackage();
Log.d(Constants.TAG, "getCreateAccountIntent accountName: " + accountName); 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.setAction(RemoteServiceActivity.ACTION_CREATE_ACCOUNT);
intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName); intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName);
intent.putExtra(RemoteServiceActivity.EXTRA_ACC_NAME, accountName); intent.putExtra(RemoteServiceActivity.EXTRA_ACC_NAME, accountName);
intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data); intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, PendingIntent pi = PendingIntent.getActivity(mContext, 0,
intent, intent,
PendingIntent.FLAG_CANCEL_CURRENT); PendingIntent.FLAG_CANCEL_CURRENT);
@@ -221,7 +225,7 @@ public abstract class RemoteService extends Service {
private boolean isUidAllowed(int uid) private boolean isUidAllowed(int uid)
throws WrongPackageCertificateException { throws WrongPackageCertificateException {
String[] callingPackages = getPackageManager().getPackagesForUid(uid); String[] callingPackages = mPackageManager.getPackagesForUid(uid);
// is calling package allowed to use this service? // is calling package allowed to use this service?
for (String currentPkg : callingPackages) { for (String currentPkg : callingPackages) {
@@ -273,11 +277,4 @@ public abstract class RemoteService extends Service {
return false; return false;
} }
@Override
public void onCreate() {
super.onCreate();
mContext = this;
mProviderHelper = new ProviderHelper(this);
}
} }

View File

@@ -18,6 +18,7 @@
package org.sufficientlysecure.keychain.remote; package org.sufficientlysecure.keychain.remote;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.app.Service;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.database.Cursor; import android.database.Cursor;
@@ -74,7 +75,7 @@ import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
public class OpenPgpService extends RemoteService { public class OpenPgpService extends Service {
static final String[] EMAIL_SEARCH_PROJECTION = new String[]{ static final String[] EMAIL_SEARCH_PROJECTION = new String[]{
KeyRings._ID, KeyRings._ID,
@@ -87,6 +88,16 @@ public class OpenPgpService extends RemoteService {
static final String EMAIL_SEARCH_WHERE = Tables.KEYS + "." + KeychainContract.KeyRings.IS_REVOKED static final String EMAIL_SEARCH_WHERE = Tables.KEYS + "." + KeychainContract.KeyRings.IS_REVOKED
+ " = 0 AND " + KeychainContract.KeyRings.IS_EXPIRED + " = 0"; + " = 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. * Search database for key ids based on emails.
*/ */
@@ -225,7 +236,7 @@ public class OpenPgpService extends RemoteService {
// to retrieve the missing key // to retrieve the missing key
Intent intent = new Intent(getBaseContext(), SelectAllowedKeysActivity.class); Intent intent = new Intent(getBaseContext(), SelectAllowedKeysActivity.class);
intent.putExtra(SelectAllowedKeysActivity.EXTRA_SERVICE_INTENT, data); 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, return PendingIntent.getActivity(getBaseContext(), 0,
intent, intent,
@@ -297,7 +308,7 @@ public class OpenPgpService extends RemoteService {
} }
// execute PGP operation! // 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); PgpSignEncryptResult pgpResult = pse.execute(pseInput, inputParcel, inputData, outputStream);
if (pgpResult.isPending()) { if (pgpResult.isPending()) {
@@ -414,9 +425,9 @@ public class OpenPgpService extends RemoteService {
if (TextUtils.isEmpty(accName)) { if (TextUtils.isEmpty(accName)) {
accName = "default"; accName = "default";
} }
final AccountSettings accSettings = getAccSettings(accName); final AccountSettings accSettings = mApiPermissionHelper.getAccSettings(accName);
if (accSettings == null || (accSettings.getKeyId() == Constants.key.none)) { if (accSettings == null || (accSettings.getKeyId() == Constants.key.none)) {
return getCreateAccountIntent(data, accName); return mApiPermissionHelper.getCreateAccountIntent(data, accName);
} }
pseInput.setAdditionalEncryptId(accSettings.getKeyId()); pseInput.setAdditionalEncryptId(accSettings.getKeyId());
} }
@@ -431,7 +442,7 @@ public class OpenPgpService extends RemoteService {
new Passphrase(data.getCharArrayExtra(OpenPgpApi.EXTRA_PASSPHRASE)); 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! // execute PGP operation!
PgpSignEncryptResult pgpResult = op.execute(pseInput, inputParcel, inputData, outputStream); PgpSignEncryptResult pgpResult = op.execute(pseInput, inputParcel, inputData, outputStream);
@@ -472,7 +483,7 @@ public class OpenPgpService extends RemoteService {
outputStream = null; outputStream = null;
} }
String currentPkg = getCurrentCallingPackage(); String currentPkg = mApiPermissionHelper.getCurrentCallingPackage();
HashSet<Long> allowedKeyIds = mProviderHelper.getAllowedKeyIdsForApp( HashSet<Long> allowedKeyIds = mProviderHelper.getAllowedKeyIdsForApp(
KeychainContract.ApiAllowedKeys.buildBaseUri(currentPkg)); KeychainContract.ApiAllowedKeys.buildBaseUri(currentPkg));
@@ -695,7 +706,7 @@ public class OpenPgpService extends RemoteService {
String preferredUserId = data.getStringExtra(OpenPgpApi.EXTRA_USER_ID); String preferredUserId = data.getStringExtra(OpenPgpApi.EXTRA_USER_ID);
Intent intent = new Intent(getBaseContext(), SelectSignKeyIdActivity.class); Intent intent = new Intent(getBaseContext(), SelectSignKeyIdActivity.class);
String currentPkg = getCurrentCallingPackage(); String currentPkg = mApiPermissionHelper.getCurrentCallingPackage();
intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(currentPkg)); intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(currentPkg));
intent.putExtra(SelectSignKeyIdActivity.EXTRA_USER_ID, preferredUserId); intent.putExtra(SelectSignKeyIdActivity.EXTRA_USER_ID, preferredUserId);
intent.putExtra(SelectSignKeyIdActivity.EXTRA_DATA, data); intent.putExtra(SelectSignKeyIdActivity.EXTRA_DATA, data);
@@ -740,9 +751,9 @@ public class OpenPgpService extends RemoteService {
} }
Log.d(Constants.TAG, "accName: " + accName); Log.d(Constants.TAG, "accName: " + accName);
// fallback to old API // fallback to old API
final AccountSettings accSettings = getAccSettings(accName); final AccountSettings accSettings = mApiPermissionHelper.getAccSettings(accName);
if (accSettings == null || (accSettings.getKeyId() == Constants.key.none)) { if (accSettings == null || (accSettings.getKeyId() == Constants.key.none)) {
return getCreateAccountIntent(data, accName); return mApiPermissionHelper.getCreateAccountIntent(data, accName);
} }
// NOTE: just wrapping the key id // NOTE: just wrapping the key id
@@ -792,7 +803,7 @@ public class OpenPgpService extends RemoteService {
} }
// check if caller is allowed to access OpenKeychain // check if caller is allowed to access OpenKeychain
Intent result = isAllowed(data); Intent result = mApiPermissionHelper.isAllowed(data);
if (result != null) { if (result != null) {
return result; return result;
} }