Rebase Auth management

This commit is contained in:
mar-v-in 2015-03-10 00:06:49 +01:00
parent 1a21205221
commit cef1ce27a2
6 changed files with 304 additions and 183 deletions

View File

@ -19,7 +19,6 @@ package org.microg.gms.auth;
import android.accounts.Account;
import android.accounts.AccountAuthenticatorActivity;
import android.accounts.AccountManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
@ -36,19 +35,29 @@ import android.widget.ListView;
import android.widget.TextView;
import com.google.android.gms.R;
import com.squareup.wire.Wire;
import org.microg.gms.common.PackageUtils;
import org.microg.gms.people.PeopleManager;
import java.io.IOException;
import static android.accounts.AccountManager.KEY_ACCOUNT_NAME;
import static android.accounts.AccountManager.KEY_ACCOUNT_TYPE;
import static android.accounts.AccountManager.KEY_ANDROID_PACKAGE_NAME;
import static android.accounts.AccountManager.KEY_AUTHTOKEN;
import static android.accounts.AccountManager.KEY_CALLER_UID;
public class AskPermissionActivity extends AccountAuthenticatorActivity {
public static final String EXTRA_FROM_ACCOUNT_MANAGER = "from_account_manager";
public static final String EXTRA_CONSENT_DATA = "consent_data";
private static final String TAG = "GmsAuthAskPermission";
private Account account;
private String packageName;
private String service;
private AuthManager authManager;
private ConsentData consentData;
private boolean fromAccountManager = false;
@Override
@ -63,13 +72,21 @@ public class AskPermissionActivity extends AccountAuthenticatorActivity {
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
getWindow().setAttributes(lp);
account = new Account(getIntent().getStringExtra(AccountManager.KEY_ACCOUNT_NAME),
getIntent().getStringExtra(AccountManager.KEY_ACCOUNT_TYPE));
packageName = getIntent().getStringExtra(AccountManager.KEY_ANDROID_PACKAGE_NAME);
service = getIntent().getStringExtra(AccountManager.KEY_AUTHTOKEN);
account = new Account(getIntent().getStringExtra(KEY_ACCOUNT_NAME),
getIntent().getStringExtra(KEY_ACCOUNT_TYPE));
packageName = getIntent().getStringExtra(KEY_ANDROID_PACKAGE_NAME);
service = getIntent().getStringExtra(KEY_AUTHTOKEN);
if (getIntent().hasExtra(EXTRA_CONSENT_DATA)) {
try {
consentData = new Wire().parseFrom(getIntent().getByteArrayExtra(EXTRA_CONSENT_DATA), ConsentData.class);
Log.d(TAG, "Consent: " + consentData);
} catch (Exception ignored) {
}
}
if (getIntent().hasExtra(EXTRA_FROM_ACCOUNT_MANAGER)) fromAccountManager = true;
int callerUid = getIntent().getIntExtra(AccountManager.KEY_CALLER_UID, 0);
int callerUid = getIntent().getIntExtra(KEY_CALLER_UID, 0);
PackageUtils.checkPackageUid(this, packageName, callerUid);
authManager = new AuthManager(this, account.name, packageName, service);
// receive package info
PackageManager packageManager = getPackageManager();
@ -126,7 +143,7 @@ public class AskPermissionActivity extends AccountAuthenticatorActivity {
}
public void onAllow() {
AuthManager.storePermission(this, account, packageName, service);
authManager.setPermitted(true);
findViewById(android.R.id.button1).setEnabled(false);
findViewById(android.R.id.button2).setEnabled(false);
findViewById(R.id.progress_bar).setVisibility(View.VISIBLE);
@ -134,27 +151,13 @@ public class AskPermissionActivity extends AccountAuthenticatorActivity {
new Thread(new Runnable() {
@Override
public void run() {
Context context = AskPermissionActivity.this;
String sig = PackageUtils.firstSignatureDigest(context, packageName);
AuthRequest request = new AuthRequest().fromContext(context)
.email(account.name)
.token(AccountManager.get(context).getPassword(account))
.service(service)
.app(packageName, sig)
.hasPermission();
if (fromAccountManager) {
request.callerIsGms().calledFromAccountManager();
} else {
request.callerIsApp();
}
try {
AuthResponse response = request.getResponse();
AuthManager.storeResponse(context, account, packageName, sig, service, response);
AuthResponse response = authManager.requestAuth(fromAccountManager);
Bundle result = new Bundle();
result.putString(AccountManager.KEY_AUTHTOKEN, response.auth);
result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
result.putString(AccountManager.KEY_ANDROID_PACKAGE_NAME, packageName);
result.putString(KEY_AUTHTOKEN, response.auth);
result.putString(KEY_ACCOUNT_NAME, account.name);
result.putString(KEY_ACCOUNT_TYPE, account.type);
result.putString(KEY_ANDROID_PACKAGE_NAME, packageName);
result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
setAccountAuthenticatorResult(result);
} catch (IOException e) {
@ -167,6 +170,7 @@ public class AskPermissionActivity extends AccountAuthenticatorActivity {
}
public void onDeny() {
authManager.setPermitted(false);
finish();
}
@ -179,6 +183,36 @@ public class AskPermissionActivity extends AccountAuthenticatorActivity {
return service.startsWith("oauth2:") || service.startsWith("oauth:");
}
private String getScopeLabel(String scope) {
if (consentData != null) {
for (ConsentData.ScopeDetails scopeDetails : consentData.scopes) {
if (scope.equals(scopeDetails.id)) {
return scopeDetails.title;
}
}
}
String labelResourceId = "permission_scope_";
String escapedScope = scope.replace("/", "_").replace("-", "_");
if (scope.startsWith("https://")) {
labelResourceId += escapedScope.substring(8);
} else {
labelResourceId += escapedScope;
}
int labelResource = getResources().getIdentifier(labelResourceId, "string", getPackageName());
if (labelResource != 0) {
return getString(labelResource);
}
return "unknown";
}
private String getServiceLabel(String service) {
int labelResource = getResources().getIdentifier("permission_service_" + service + "_label", "string", getPackageName());
if (labelResource != 0) {
return getString(labelResource);
}
return "unknown";
}
private class PermissionAdapter extends BaseAdapter {
@Override
@ -206,20 +240,11 @@ public class AskPermissionActivity extends AccountAuthenticatorActivity {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
String item = getItem(position);
String label = "unknown";
String labelResourceId;
String label;
if (isOAuth()) {
if (item.startsWith("https://")) {
labelResourceId = "permission_scope_" + item.substring(8).replace("/", "_").replace("-", "_");
} else {
labelResourceId = "permission_scope_" + item.replace("/", "_").replace("-", "_");
}
label = getScopeLabel(item);
} else {
labelResourceId = "permission_service_" + item + "_label";
}
int labelResource = getResources().getIdentifier(labelResourceId, "string", getPackageName());
if (labelResource != 0) {
label = getString(labelResource);
label = getServiceLabel(item);
}
View view = convertView;
if (view == null) {

View File

@ -20,96 +20,186 @@ import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.preference.PreferenceManager;
import android.util.Log;
import org.microg.gms.common.Constants;
import org.microg.gms.common.PackageUtils;
import java.io.IOException;
import static android.content.pm.ApplicationInfo.FLAG_SYSTEM;
import static android.content.pm.ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
public class AuthManager {
private static final String TAG = "GmsAuthManager";
public static final String PERMISSION_TREE_BASE = "com.google.android.googleapps.permission.GOOGLE_AUTH.";
private static final String PREF_KEY_TRUST_GOOGLE = "auth_manager_trust_google";
public static void storeResponse(Context context, Account account, String packageName,
String sig, String service, AuthResponse response) {
if (service.startsWith("weblogin:")) return;
AccountManager accountManager = AccountManager.get(context);
if (response.accountId != null)
accountManager.setUserData(account, "GoogleUserId", response.accountId);
if (response.Sid != null)
accountManager.setAuthToken(account, buildTokenKey(packageName, sig, "SID"), response.Sid);
if (response.LSid != null)
accountManager.setAuthToken(account, buildTokenKey(packageName, sig, "LSID"), response.LSid);
if (response.expiry > 0)
accountManager.setUserData(account, buildExpireKey(packageName, sig, service), Long.toString(response.expiry));
if (response.auth != null && response.expiry != 0 && response.storeConsentRemotely) {
accountManager.setAuthToken(account, buildTokenKey(packageName, sig, service), response.auth);
accountManager.setUserData(account, buildPermKey(packageName, sig, service), "1");
}
private final Context context;
private final String accountName;
private final String packageName;
private final String service;
private AccountManager accountManager;
private Account account;
private String packageSignature;
public AuthManager(Context context, String accountName, String packageName, String service) {
this.context = context;
this.accountName = accountName;
this.packageName = packageName;
this.service = service;
}
public static String getToken(Context context, Account account, String packageName,
String sig, String service) {
if (service.startsWith("weblogin:")) return null;
AccountManager accountManager = AccountManager.get(context);
return accountManager.peekAuthToken(account, buildTokenKey(packageName, sig, service));
public AccountManager getAccountManager() {
if (accountManager == null)
accountManager = AccountManager.get(context);
return accountManager;
}
public static boolean isPermitted(Context context, Account account, String packageName,
String sig, String service) {
if (service.startsWith("audience:server:client_id:")) {
// https://developers.google.com/accounts/docs/CrossClientAuth
Log.d(TAG, "Always permitting scope: " + service);
return true;
} else if (service.startsWith("weblogin:")) {
if (Constants.GMS_PACKAGE_SIGNATURE_SHA1.equals(sig)) {
Log.d(TAG, "Permitting weblogin, is Google singed app!");
return true;
}
return false;
} else if (!service.startsWith("oauth:") && !service.startsWith("oauth2:")) {
public Account getAccount() {
if (account == null)
account = new Account(accountName, "com.google");
return account;
}
public String getPackageSignature() {
if (packageSignature == null)
packageSignature = PackageUtils.firstSignatureDigest(context, packageName);
return packageSignature;
}
public String buildTokenKey(String service) {
return packageName + ":" + getPackageSignature() + ":" + service;
}
public String buildTokenKey() {
return buildTokenKey(service);
}
public String buildPermKey() {
return "perm." + buildTokenKey();
}
public void setPermitted(boolean value) {
setUserData(buildPermKey(), value ? "1" : "0");
}
public boolean isPermitted() {
if (!service.startsWith("oauth")) {
if (context.getPackageManager().checkPermission(PERMISSION_TREE_BASE + service, packageName) == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Permitting, permission is present");
return true;
}
}
AccountManager accountManager = AccountManager.get(context);
String perm = accountManager.getUserData(account, buildPermKey(packageName, sig, service));
String perm = getUserData(buildPermKey());
if (!"1".equals(perm)) {
Log.d(TAG, "Not permitting, permission not stored for " + packageName + ": " + service);
return false;
}
String exp = accountManager.getUserData(account, buildExpireKey(packageName, sig, service));
if (exp != null) {
long expLong = Long.parseLong(exp);
if (expLong < System.currentTimeMillis() / 1000L) {
Log.d(TAG, "Permission for " + packageName + " / " + service + " present, but expired");
return false;
}
}
return true;
}
public static void storePermission(Context context, Account account, String packageName, String service) {
storePermission(context, account, packageName, PackageUtils.firstSignatureDigest(context, packageName), service);
public void setExpiry(long expiry) {
setUserData(buildExpireKey(), Long.toString(expiry));
}
public static void storePermission(Context context, Account account, String packageName,
String sig, String service) {
AccountManager accountManager = AccountManager.get(context);
accountManager.setUserData(account, buildPermKey(packageName, sig, service), "1");
public String getUserData(String key) {
return getAccountManager().getUserData(getAccount(), key);
}
public static String buildTokenKey(String packageName, String sig, String service) {
public void setUserData(String key, String value) {
getAccountManager().setUserData(getAccount(), key, value);
}
public String peekAuthToken() {
return getAccountManager().peekAuthToken(getAccount(), buildTokenKey());
}
public String getAuthToken() {
if (service.startsWith("weblogin:")) return null;
return packageName + ":" + sig + ":" + service;
if (getExpiry() != -1 && getExpiry() < System.currentTimeMillis() / 1000L) {
Log.d(TAG, "token present, but expired");
return null;
}
return peekAuthToken();
}
private static String buildPermKey(String packageName, String sig, String service) {
return "perm." + packageName + ":" + sig + ":" + service;
public String buildExpireKey() {
return "EXP." + buildTokenKey();
}
private static String buildExpireKey(String packageName, String sig, String service) {
return "EXP." + packageName + ":" + sig + ":" + service;
public long getExpiry() {
String exp = getUserData(buildExpireKey());
if (exp == null) return -1;
return Long.parseLong(exp);
}
public void setAuthToken(String auth) {
setAuthToken(service, auth);
}
public void setAuthToken(String service, String auth) {
getAccountManager().setAuthToken(getAccount(), buildTokenKey(service), auth);
}
public void storeResponse(AuthResponse response) {
if (service.startsWith("weblogin:")) return;
if (response.accountId != null)
setUserData("GoogleUserId", response.accountId);
if (response.Sid != null)
setAuthToken("SID", response.Sid);
if (response.LSid != null)
setAuthToken("LSID", response.LSid);
if (response.expiry > 0)
setExpiry(response.expiry);
if (response.auth != null && response.expiry != 0 && response.storeConsentRemotely)
setAuthToken(response.auth);
}
public static boolean isTrustGooglePermitted(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context).getBoolean(PREF_KEY_TRUST_GOOGLE, true);
}
private boolean isSystemApp() {
try {
int flags = context.getPackageManager().getApplicationInfo(packageName, 0).flags;
return (flags & FLAG_SYSTEM) > 0 || (flags & FLAG_UPDATED_SYSTEM_APP) > 0;
} catch (PackageManager.NameNotFoundException e) {
return false;
}
}
public AuthResponse requestAuth(boolean legacy) throws IOException {
if (isPermitted() || isTrustGooglePermitted(context)) {
String token = getAuthToken();
if (token != null) {
AuthResponse response = new AuthResponse();
response.issueAdvice = "stored";
response.auth = token;
return response;
}
}
AuthRequest request = new AuthRequest().fromContext(context)
.app(packageName, getPackageSignature())
.email(accountName)
.token(getAccountManager().getPassword(account))
.service(service);
if (isSystemApp()) request.systemPartition();
if (isPermitted()) request.hasPermission();
if (legacy) {
request.callerIsGms().calledFromAccountManager();
} else {
request.callerIsApp();
}
AuthResponse response = request.getResponse();
if (!isPermitted() && !isTrustGooglePermitted(context)) {
response.auth = null;
} else {
storeResponse(response);
}
return response;
}
public String getService() {
return service;
}
}

View File

@ -16,12 +16,11 @@
package org.microg.gms.auth;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Base64;
import android.util.Log;
import com.google.android.auth.IAuthManagerService;
@ -30,13 +29,18 @@ import com.google.android.gms.auth.AccountChangeEventsResponse;
import org.microg.gms.common.PackageUtils;
import static android.accounts.AccountManager.KEY_ACCOUNT_NAME;
import static android.accounts.AccountManager.KEY_ACCOUNT_TYPE;
import static android.accounts.AccountManager.KEY_ANDROID_PACKAGE_NAME;
import static android.accounts.AccountManager.KEY_AUTHTOKEN;
import static org.microg.gms.auth.AskPermissionActivity.EXTRA_CONSENT_DATA;
public class AuthManagerServiceImpl extends IAuthManagerService.Stub {
private static final String TAG = "GmsAuthManagerSvc";
public static final String GOOGLE_ACCOUNT_TYPE = "com.google";
public static final String KEY_AUTHORITY = "authority";
public static final String KEY_ANDROID_PACKAGE_NAME = "androidPackageName";
public static final String KEY_CALLBACK_INTENT = "callback_intent";
public static final String KEY_CALLER_UID = "callerUid";
public static final String KEY_CLIENT_PACKAGE_NAME = "clientPackageName";
@ -50,7 +54,7 @@ public class AuthManagerServiceImpl extends IAuthManagerService.Stub {
public static final String KEY_ERROR = "Error";
public static final String KEY_USER_RECOVERY_INTENT = "userRecoveryIntent";
private Context context;
private final Context context;
public AuthManagerServiceImpl(Context context) {
this.context = context;
@ -64,42 +68,36 @@ public class AuthManagerServiceImpl extends IAuthManagerService.Stub {
boolean notify = extras.getBoolean(KEY_HANDLE_NOTIFICATION, false);
Log.d(TAG, "getToken: account:" + accountName + " scope:" + scope + " extras:" + extras + ", notify: " + notify);
Account account = new Account(accountName, GOOGLE_ACCOUNT_TYPE);
String sig = PackageUtils.firstSignatureDigest(context, packageName);
if (!AuthManager.isPermitted(context, account, packageName, sig, scope)) {
Bundle result = new Bundle();
result.putString(KEY_ERROR, "Unknown");
Intent i = new Intent(context, AskPermissionActivity.class);
i.putExtras(extras);
i.putExtra(AccountManager.KEY_ANDROID_PACKAGE_NAME, packageName);
i.putExtra(AccountManager.KEY_ACCOUNT_TYPE, account.type);
i.putExtra(AccountManager.KEY_ACCOUNT_NAME, account.name);
i.putExtra(AccountManager.KEY_AUTHTOKEN, scope);
if (notify) {
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
} else {
result.putParcelable(KEY_USER_RECOVERY_INTENT, i);
}
return result;
}
AuthManager authManager = new AuthManager(context, accountName, packageName, scope);
try {
AuthResponse response = new AuthRequest().fromContext(context)
.app(packageName, sig)
.callerIsApp()
.email(accountName)
.token(AccountManager.get(context).getPassword(account))
.service(scope)
.getResponse();
AuthManager.storeResponse(context, account, packageName, sig, scope, response);
Log.d("getToken", response.auth);
Bundle result = new Bundle();
result.putString(KEY_AUTH_TOKEN, response.auth);
result.putString(KEY_ERROR, "Unknown");
return result;
AuthResponse res = authManager.requestAuth(false);
if (res.auth != null) {
Log.d(TAG, "getToken: " + res.auth);
Bundle result = new Bundle();
result.putString(KEY_AUTH_TOKEN, res.auth);
result.putString(KEY_ERROR, "OK");
return result;
} else {
Bundle result = new Bundle();
result.putString(KEY_ERROR, "Unknown");
Intent i = new Intent(context, AskPermissionActivity.class);
i.putExtras(extras);
i.putExtra(KEY_ANDROID_PACKAGE_NAME, packageName);
i.putExtra(KEY_ACCOUNT_TYPE, GOOGLE_ACCOUNT_TYPE);
i.putExtra(KEY_ACCOUNT_NAME, accountName);
i.putExtra(KEY_AUTHTOKEN, scope);
if (res.consentDataBase64 != null)
i.putExtra(EXTRA_CONSENT_DATA, Base64.decode(res.consentDataBase64, Base64.DEFAULT));
if (notify) {
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
} else {
result.putParcelable(KEY_USER_RECOVERY_INTENT, i);
}
return result;
}
} catch (Exception e) {
Log.w("AuthManagerService", e);
Log.w(TAG, e);
throw new RemoteException(e.getMessage());
}
}

View File

@ -57,6 +57,12 @@ public class AuthResponse {
public long expiry = -1;
@ResponseField("storeConsentRemotely")
public boolean storeConsentRemotely = true;
@ResponseField("Permission")
public String permission;
@ResponseField("ScopeConsentDetails")
public String scopeConsentDetails;
@ResponseField("ConsentDataBase64")
public String consentDataBase64;
public static AuthResponse parse(String result) {
AuthResponse response = new AuthResponse();

View File

@ -47,6 +47,9 @@ import org.microg.gms.people.PeopleManager;
import java.util.Locale;
import static org.microg.gms.common.Constants.GMS_PACKAGE_NAME;
import static org.microg.gms.common.Constants.GMS_PACKAGE_SIGNATURE_SHA1;
public class LoginActivity extends AssistantActivity {
public static final String TMPL_NEW_ACCOUNT = "new_account";
public static final String EXTRA_TMPL = "tmpl";
@ -192,10 +195,11 @@ public class LoginActivity extends AssistantActivity {
}
private void retrieveGmsToken(final Account account) {
final String service = "ac2dm";
final AuthManager authManager = new AuthManager(this, account.name, GMS_PACKAGE_NAME, "ac2dm");
authManager.setPermitted(true);
new AuthRequest().fromContext(this)
.appIsGms()
.service(service)
.service(authManager.getService())
.email(account.name)
.token(AccountManager.get(this).getPassword(account))
.systemPartition()
@ -205,9 +209,7 @@ public class LoginActivity extends AssistantActivity {
.getResponseAsync(new HttpFormClient.Callback<AuthResponse>() {
@Override
public void onResponse(AuthResponse response) {
AuthManager.storeResponse(LoginActivity.this, account,
Constants.GMS_PACKAGE_NAME, Constants.GMS_PACKAGE_SIGNATURE_SHA1,
service, response);
authManager.storeResponse(response);
PeopleManager.loadUserInfo(LoginActivity.this, account);
finish();
}

View File

@ -19,26 +19,34 @@ package org.microg.gms.auth.loginservice;
import android.accounts.AbstractAccountAuthenticator;
import android.accounts.Account;
import android.accounts.AccountAuthenticatorResponse;
import android.accounts.AccountManager;
import android.accounts.NetworkErrorException;
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Base64;
import android.util.Log;
import com.google.android.gms.R;
import org.microg.gms.auth.AskPermissionActivity;
import org.microg.gms.auth.AuthManager;
import org.microg.gms.auth.AuthRequest;
import org.microg.gms.auth.AuthResponse;
import org.microg.gms.auth.login.LoginActivity;
import org.microg.gms.common.PackageUtils;
import java.io.IOException;
import java.util.Arrays;
import static android.accounts.AccountManager.ACTION_AUTHENTICATOR_INTENT;
import static android.accounts.AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE;
import static android.accounts.AccountManager.KEY_ACCOUNT_NAME;
import static android.accounts.AccountManager.KEY_ACCOUNT_TYPE;
import static android.accounts.AccountManager.KEY_ANDROID_PACKAGE_NAME;
import static android.accounts.AccountManager.KEY_AUTHTOKEN;
import static android.accounts.AccountManager.KEY_BOOLEAN_RESULT;
import static android.accounts.AccountManager.KEY_CALLER_UID;
import static android.accounts.AccountManager.KEY_INTENT;
public class GoogleLoginService extends Service {
private static final String TAG = "GmsAuthLoginSvc";
@ -52,7 +60,7 @@ public class GoogleLoginService extends Service {
@Override
public IBinder onBind(Intent intent) {
if (intent.getAction().equals(android.accounts.AccountManager.ACTION_AUTHENTICATOR_INTENT)) {
if (intent.getAction().equals(ACTION_AUTHENTICATOR_INTENT)) {
return new AbstractAccountAuthenticator(this) {
@Override
public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
@ -94,7 +102,7 @@ public class GoogleLoginService extends Service {
public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account, String[] features) throws NetworkErrorException {
Log.d(TAG, "hasFeatures: " + account + ", " + Arrays.toString(features));
Bundle result = new Bundle();
result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
result.putBoolean(KEY_BOOLEAN_RESULT, true);
return result;
}
}.getIBinder();
@ -105,53 +113,45 @@ public class GoogleLoginService extends Service {
private Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) {
options.keySet();
Log.d(TAG, "getAuthToken: " + account + ", " + authTokenType + ", " + options);
String app = options.getString(AccountManager.KEY_ANDROID_PACKAGE_NAME);
PackageUtils.checkPackageUid(this, app, options.getInt(AccountManager.KEY_CALLER_UID), options.getInt(AccountManager.KEY_CALLER_UID));
String appSignature = PackageUtils.firstSignatureDigest(this, app);
if (!AuthManager.isPermitted(this, account, app, appSignature, authTokenType)) {
Bundle result = new Bundle();
Intent i = new Intent(this, AskPermissionActivity.class);
i.putExtras(options);
i.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
i.putExtra(AccountManager.KEY_ANDROID_PACKAGE_NAME, app);
i.putExtra(AccountManager.KEY_ACCOUNT_TYPE, account.type);
i.putExtra(AccountManager.KEY_ACCOUNT_NAME, account.name);
i.putExtra(AccountManager.KEY_AUTHTOKEN, authTokenType);
result.putParcelable(AccountManager.KEY_INTENT, i);
return result;
}
String token = AuthManager.getToken(this, account, app, appSignature, authTokenType);
if (token == null) {
try {
AuthRequest request = new AuthRequest().fromContext(this)
.email(account.name)
.token(AccountManager.get(this).getPassword(account))
.service(authTokenType)
.app(app, appSignature)
.callerIsGms()
.calledFromAccountManager()
.hasPermission();
AuthResponse r = request.getResponse();
AuthManager.storeResponse(this, account, app, appSignature, authTokenType, r);
token = r.auth;
} catch (IOException e) {
Log.w(TAG, e);
String app = options.getString(KEY_ANDROID_PACKAGE_NAME);
PackageUtils.checkPackageUid(this, app, options.getInt(KEY_CALLER_UID), options.getInt(KEY_CALLER_UID));
AuthManager authManager = new AuthManager(this, account.name, app, authTokenType);
try {
AuthResponse res = authManager.requestAuth(true);
if (res.auth != null) {
Log.d(TAG, "getAuthToken: " + res.auth);
Bundle result = new Bundle();
result.putString(KEY_ACCOUNT_TYPE, account.type);
result.putString(KEY_ACCOUNT_NAME, account.name);
result.putString(KEY_AUTHTOKEN, res.auth);
return result;
} else {
Bundle result = new Bundle();
Intent i = new Intent(this, AskPermissionActivity.class);
i.putExtras(options);
i.putExtra(KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
i.putExtra(KEY_ANDROID_PACKAGE_NAME, app);
i.putExtra(KEY_ACCOUNT_TYPE, account.type);
i.putExtra(KEY_ACCOUNT_NAME, account.name);
i.putExtra(KEY_AUTHTOKEN, authTokenType);
if (res.consentDataBase64 != null)
i.putExtra(AskPermissionActivity.EXTRA_CONSENT_DATA, Base64.decode(res.consentDataBase64, Base64.DEFAULT));
result.putParcelable(KEY_INTENT, i);
return result;
}
} catch (Exception e) {
Log.w(TAG, e);
return null;
}
Bundle result = new Bundle();
result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
result.putString(AccountManager.KEY_AUTHTOKEN, token);
return result;
}
private Bundle addAccount(AccountAuthenticatorResponse response, String authTokenType, String[] requiredFeatures, Bundle options) {
final Intent i = new Intent(GoogleLoginService.this, LoginActivity.class);
i.putExtras(options);
i.putExtra(LoginActivity.EXTRA_TMPL, LoginActivity.TMPL_NEW_ACCOUNT);
i.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
i.putExtra(KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
final Bundle result = new Bundle();
result.putParcelable(AccountManager.KEY_INTENT, i);
result.putParcelable(KEY_INTENT, i);
return result;
}
}