summaryrefslogtreecommitdiffstats
path: root/core/java/android/accounts
diff options
context:
space:
mode:
authorAmith Yamasani <yamasani@google.com>2013-03-30 17:07:47 -0700
committerAmith Yamasani <yamasani@google.com>2013-03-30 18:25:49 -0700
commit27db46850b708070452c0ce49daf5f79503fbde6 (patch)
treeb8ee9ba7481bbd869601b8320f5070394bde13bd /core/java/android/accounts
parent9e8ba8f27316c793578e68fcc6632a6ea6240f4a (diff)
downloadframeworks_base-27db46850b708070452c0ce49daf5f79503fbde6.zip
frameworks_base-27db46850b708070452c0ce49daf5f79503fbde6.tar.gz
frameworks_base-27db46850b708070452c0ce49daf5f79503fbde6.tar.bz2
Block access to accounts for limited users.
Make sure that apps that have access to restricted accounts can see them. If they don't have access, they shouldn't be able to add a new account either. Show an error message in the account picker if the user/app is not authorized. Change-Id: I117c0b14d7d06c5ac4e66506df156b174567f5f3
Diffstat (limited to 'core/java/android/accounts')
-rw-r--r--core/java/android/accounts/AccountManager.java21
-rw-r--r--core/java/android/accounts/ChooseTypeAndAccountActivity.java49
-rw-r--r--core/java/android/accounts/IAccountManager.aidl5
3 files changed, 65 insertions, 10 deletions
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index bdc882a..241a64a 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -388,6 +388,23 @@ public class AccountManager {
}
/**
+ * @hide
+ * For use by internal activities. Returns the list of accounts that the calling package
+ * is authorized to use, particularly for shared accounts.
+ * @param packageName package name of the calling app.
+ * @param uid the uid of the calling app.
+ * @return the accounts that are available to this package and user.
+ */
+ public Account[] getAccountsForPackage(String packageName, int uid) {
+ try {
+ return mService.getAccountsForPackage(packageName, uid);
+ } catch (RemoteException re) {
+ // possible security exception
+ throw new RuntimeException(re);
+ }
+ }
+
+ /**
* Lists all accounts of a particular type. The account type is a
* string token corresponding to the authenticator and useful domain
* of the account. For example, there are types corresponding to Google
@@ -575,7 +592,7 @@ public class AccountManager {
public boolean addAccountExplicitly(Account account, String password, Bundle userdata) {
if (account == null) throw new IllegalArgumentException("account is null");
try {
- return mService.addAccount(account, password, userdata);
+ return mService.addAccountExplicitly(account, password, userdata);
} catch (RemoteException e) {
// won't ever happen
throw new RuntimeException(e);
@@ -1123,7 +1140,7 @@ public class AccountManager {
return new AmsTask(activity, handler, callback) {
public void doWork() throws RemoteException {
- mService.addAcount(mResponse, accountType, authTokenType,
+ mService.addAccount(mResponse, accountType, authTokenType,
requiredFeatures, activity != null, optionsIn);
}
}.start();
diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
index 5358bc7..2aba163 100644
--- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java
+++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
@@ -18,9 +18,14 @@ package android.accounts;
import com.google.android.collect.Sets;
import android.app.Activity;
+import android.app.ActivityManagerNative;
import android.content.Intent;
import android.os.Bundle;
+import android.os.IBinder;
import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
@@ -29,6 +34,7 @@ import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
+import android.widget.Toast;
import com.android.internal.R;
@@ -119,6 +125,9 @@ public class ChooseTypeAndAccountActivity extends Activity
private Parcelable[] mExistingAccounts = null;
private int mSelectedItemIndex;
private Button mOkButton;
+ private int mCallingUid;
+ private String mCallingPackage;
+ private boolean mDisallowAddAccounts;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -128,6 +137,24 @@ public class ChooseTypeAndAccountActivity extends Activity
+ savedInstanceState + ")");
}
+ String message = null;
+
+ try {
+ IBinder activityToken = getActivityToken();
+ mCallingUid = ActivityManagerNative.getDefault().getLaunchedFromUid(activityToken);
+ mCallingPackage = ActivityManagerNative.getDefault().getLaunchedFromPackage(
+ activityToken);
+ if (mCallingUid != 0 && mCallingPackage != null) {
+ Bundle restrictions = UserManager.get(this)
+ .getUserRestrictions(new UserHandle(UserHandle.getUserId(mCallingUid)));
+ mDisallowAddAccounts =
+ restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false);
+ }
+ } catch (RemoteException re) {
+ // Couldn't figure out caller details
+ Log.w(getClass().getSimpleName(), "Unable to get caller identity \n" + re);
+ }
+
// save some items we use frequently
final Intent intent = getIntent();
@@ -179,6 +206,11 @@ public class ChooseTypeAndAccountActivity extends Activity
// If there are no relevant accounts and only one relevant account type go directly to
// add account. Otherwise let the user choose.
if (mAccounts.isEmpty()) {
+ if (mDisallowAddAccounts) {
+ setContentView(R.layout.app_not_authorized);
+ setTitle(R.string.error_message_title);
+ return;
+ }
if (mSetOfRelevantAccountTypes.size() == 1) {
runAddAccountForAuthenticator(mSetOfRelevantAccountTypes.iterator().next());
} else {
@@ -296,7 +328,8 @@ public class ChooseTypeAndAccountActivity extends Activity
}
if (accountName == null || accountType == null) {
- Account[] currentAccounts = AccountManager.get(this).getAccounts();
+ Account[] currentAccounts = AccountManager.get(this).getAccountsForPackage(
+ mCallingPackage, mCallingUid);
Set<Account> preExistingAccounts = new HashSet<Account>();
for (Parcelable accountParcel : mExistingAccounts) {
preExistingAccounts.add((Account) accountParcel);
@@ -347,7 +380,8 @@ public class ChooseTypeAndAccountActivity extends Activity
AccountManager.KEY_INTENT);
if (intent != null) {
mPendingRequest = REQUEST_ADD_ACCOUNT;
- mExistingAccounts = AccountManager.get(this).getAccounts();
+ mExistingAccounts = AccountManager.get(this).getAccountsForPackage(mCallingPackage,
+ mCallingUid);
intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_NEW_TASK);
startActivityForResult(intent, REQUEST_ADD_ACCOUNT);
return;
@@ -424,12 +458,14 @@ public class ChooseTypeAndAccountActivity extends Activity
private String[] getListOfDisplayableOptions(ArrayList<Account> accounts) {
// List of options includes all accounts found together with "Add new account" as the
// last item in the list.
- String[] listItems = new String[accounts.size() + 1];
+ String[] listItems = new String[accounts.size() + (mDisallowAddAccounts ? 0 : 1)];
for (int i = 0; i < accounts.size(); i++) {
listItems[i] = accounts.get(i).name;
}
- listItems[accounts.size()] = getResources().getString(
- R.string.add_account_button_label);
+ if (!mDisallowAddAccounts) {
+ listItems[accounts.size()] = getResources().getString(
+ R.string.add_account_button_label);
+ }
return listItems;
}
@@ -439,7 +475,8 @@ public class ChooseTypeAndAccountActivity extends Activity
* allowable accounts, if provided.
*/
private ArrayList<Account> getAcceptableAccountChoices(AccountManager accountManager) {
- final Account[] accounts = accountManager.getAccounts();
+ final Account[] accounts = accountManager.getAccountsForPackage(mCallingPackage,
+ mCallingUid);
ArrayList<Account> accountsToPopulate = new ArrayList<Account>(accounts.length);
for (Account account : accounts) {
if (mSetOfAllowableAccounts != null
diff --git a/core/java/android/accounts/IAccountManager.aidl b/core/java/android/accounts/IAccountManager.aidl
index 47b257d..8141813 100644
--- a/core/java/android/accounts/IAccountManager.aidl
+++ b/core/java/android/accounts/IAccountManager.aidl
@@ -31,10 +31,11 @@ interface IAccountManager {
String getUserData(in Account account, String key);
AuthenticatorDescription[] getAuthenticatorTypes();
Account[] getAccounts(String accountType);
+ Account[] getAccountsForPackage(String packageName, int uid);
Account[] getAccountsAsUser(String accountType, int userId);
void hasFeatures(in IAccountManagerResponse response, in Account account, in String[] features);
void getAccountsByFeatures(in IAccountManagerResponse response, String accountType, in String[] features);
- boolean addAccount(in Account account, String password, in Bundle extras);
+ boolean addAccountExplicitly(in Account account, String password, in Bundle extras);
void removeAccount(in IAccountManagerResponse response, in Account account);
void invalidateAuthToken(String accountType, String authToken);
String peekAuthToken(in Account account, String authTokenType);
@@ -47,7 +48,7 @@ interface IAccountManager {
void getAuthToken(in IAccountManagerResponse response, in Account account,
String authTokenType, boolean notifyOnAuthFailure, boolean expectActivityLaunch,
in Bundle options);
- void addAcount(in IAccountManagerResponse response, String accountType,
+ void addAccount(in IAccountManagerResponse response, String accountType,
String authTokenType, in String[] requiredFeatures, boolean expectActivityLaunch,
in Bundle options);
void updateCredentials(in IAccountManagerResponse response, in Account account,