mirror of https://github.com/YTVanced/VancedMicroG
Rebase Auth management
This commit is contained in:
parent
1a21205221
commit
cef1ce27a2
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue