Google Play Services - force to show permission window (grant access) - android

I'm using Google Play Services in my apps but lately I found something strange and I don't know how to deal with it.
If you are using Google Play Services you know that for the fist time, before you'll generate token you need to give your app permission (grant access) to use selected API.
After that, your app will be visible here: https://accounts.google.com/IssuedAuthSubTokens
And my app is there. Everything was working. I wanted to test it from the scratch, I revoke access to my app and ... it stops working. I can't force Google Play Services to show this window after revoking access to my app. I don't have permission to Google API but Google should show me permission window to re-add it.
Is there a way to show this window again?
I'm using GoogleAccountCredential.usingOAuth2 function to get user token and data (with all exceptions like UserRecoverableAuthIOException, startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION) ...).
As I understand, GoogleAccountCredential uses the Google Play Services to manage the OAuth2 flow and all you need to provide is the username. After revoking access it's not working.

Using Google Play Services:
http://developer.android.com/reference/com/google/android/gms/auth/GoogleAuthUtil.html
Add https://www.googleapis.com/auth/userinfo.profile to your scope.
Example:
String scope="oauth2:https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile"
final String token = GoogleAuthUtil.getToken(context, "xxxx#gmail.com", scope);
OR "brute force"
Intent res = new Intent();
res.addCategory("account:xxxx#gmail.com");
res.addCategory("scope:oauth2:https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile");
res.putExtra("service", "oauth2:https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile");
Bundle extra= new Bundle();
extra.putString("androidPackageName","com.your.package");
res.putExtra("callerExtras",extra);
res.putExtra("androidPackageName","com.your.package");
res.putExtra("authAccount","xxxx#gmail.com");
String mPackage = "com.google.android.gms";
String mClass = "com.google.android.gms.auth.TokenActivity";
res.setComponent(new ComponentName(mPackage,mClass));
startActivityForResult(res,100);
Now, when you revoke the access here https://accounts.google.com/IssuedAuthSubTokens the application shows you the window for permission again in the device.

Related

Exact Behaviour of RideRequest Widget

For the RideRequestWidget I have the following Code
RideParameters rideParams = new RideParameters.Builder()
.setProductId("83941b0d-4be1-4979-a9c0-f0af5ee2b89b")
.setPickupLocation(19.1136, 72.8679, "Uber HQ", "1455 Market Street, San Francisco")
.setDropoffLocation(19.1145, 72.8675, "Embarcadero", "One Embarcadero Center, San Francisco")
.build();
SessionConfiguration config = new SessionConfiguration.Builder()
.setClientId(AppController.UBER_CLIENT_ID)
.setServerToken(AppController.UBER_SERVER_TOKEN)
.build();
ServerTokenSession session = new ServerTokenSession(config);
holder.uberButton.setRideParameters(rideParams);
holder.uberButton.setRequestBehavior(new RideRequestActivityBehavior((Activity) mContext, 1234));
holder.uberButton.setSession(session);
holder.uberButton.setCallback(callback);
holder.uberButton.loadRideInformation();
Exactly from the Uber Docs.
I have some questions.
I have a phone on which Uber app is not installed. When the Ride Button is clicked , it nicely takes me to the webview and I can login and request for cab all seamlessly (ofcourse! sandbox). Things are fine till now. But I have another phone on which I installed the app (passing apk via email) on which I already have Uber app installed (and signed in). When I click on the Ride Button then it shows.
What's the reason for this?
What's the difference between implicit grant and oauth2. Is oauth2 preferable or it gives more functionality? or is it the same?
If oauth2 is preferable then Please! shed some information on 'redirect url'. Any samples will help me good!
My use case is simple: I purely want to help the user book a ride on his behalf!
EDIT:
I have the following further questions
When I use RideRequestWidget in the sandbox environment , it does NOT respect it. It simply deep links to my uber app (if installed) and I can actually book cabs.
I am logged into my Uber account (in the uber app) installed on my phone with the same credentials registered for my developer account. So According to the docs when I click on the riderequestwidget then it should deeplink and show me the view so I can book the cabs. But it shows the error mentioned (in the screen above)
If I sign out and then click on the widget so it deep links to the installed Uber app and I can practically enter 'ANY' ID (which is not registered to my developer's account) and it 'Logs me in'.
If the Uber App is installed, the Ride Request Widget will attempt to use Single Sign On to authorize the user. The authentication error could be any number of errors and you can check which by using onActivityResult and checking the intent extras for “authentication_error”. Most likely the error is you haven’t registered your application’s signature on the authorizations page of developer.uber.com. Check your logs for the application signature in an error, or generate it on your own via the instructions in the Login section of the Rides Android SDK README.
Implicit Grant is a flow type for OAuth2. A redirect URL may be used by your backend to get an access token with different flows. For the purposes of Implicit Grant, as long as the redirect URL you have registered on the authorizations page matches what you have in the SDK it should work (you could even have).

Can't set Google Account Credential in Android

I'm trying to use the Google Drive REST API - using the exact sample code found at Android REST Quickstart. However I cannot set an account name for the Google Account Credential object in the the onActivityResult method.
I don't get it as I've triple checked that mCredential.setSelectedAccountName(accountName); is definitely being passed an email string for the account name, but when I try and use mCredential.getSelectedAccountName() it always returns null immediately after it has supposedly been set. This means that the account picker is constantly being called but never sets an account name.
Someone please help as this is driving me crazy!
If You are running your application on android version 6.+ then make sure that your app has all the required permission allowed. You can check this by going Setting->apps->your_app->apps permission.

how to add google account programmatically in android with one click in background?

i am trying to add google account programmatically to android using a app that takes username and password and logins the user in background. But i m having problem as it is showing error...
Error: Caller uid 10024 is different than authenticator's uid .
I had already included all permissions and authenticator xml but it is not responding...
plz help i want to add google account in backgroundwith one click ..
Thanks in advance..
Account acc = new Account("mygmailid#gmail.com", "com.google");
AccountManager am = AccountManager.get(this);
Bundle userdata = new Bundle();
userdata.putString("SERVER", "extra");
if (am.addAccountExplicitly(acc, "mypass", userdata)) {
// success message..
}
Basically this would be impossible to do because adding an new google account without the prior information of the user itself would definetely be a kind of malware or theft app.
Therefore according to Google this would lead to violate the user freedom and its trust towards Android operating system.
But you can add new google account and can ask user to enter the password for that account. So there will be no permission violation.

GoogleAccountCredential reuse auth - Google Drive

I'm using this method to auth to Google Drive:
https://developers.google.com/drive/quickstart-android
Choosing account is working great. Now I want to store user credentials in prefs. I can save account name and then resore it. I want to reuse credentials for future use.
Is it possible to reauth using Google Play Services and GoogleAccountCredential?
This is my scenario:
StartActivity
Search for savedCredentials
If NOT -> show ACCOUNT PICKER (this is working)
If I choose account - saveCredentians to preferences.
Now I close my app and run again.
StartActivity
Search for savedCredentials
YES - there are saved credentials. I want to use them.
I'm trying something like this:
credential = GoogleAccountCredential.usingOAuth2(GoogleDriveBackup.this, DriveScopes.DRIVE_FILE);
//use saved account (stored[0] is OK)
credential.setSelectedAccountName(stored[0]);
credential.getToken();
service = getDriveService(credential);
Where:
private Drive getDriveService(GoogleAccountCredential credential) {
return new Drive.Builder(AndroidHttp.newCompatibleTransport(),
new GsonFactory(), credential).build();
}
This isn't working. I'm getting 500 Internal Server errors from GoogleJsonResponseExcelption. What's the best way to do that using Google Play Services for Android.
If what you are trying to do is avoiding that the user has to re-authorize your app then you don't need to save the credential Object. All yo need to do is save the Account the user chose using the account picker.
When re-creating a credential object the next time your app is used, the play services will know that the user has already granted you access before and you won't have to show the auth Intent (available in the Exception thrown).
You do need to provide a way for the user to change the account he chose though.

Where to revoke Google API permissions granted on Android?

I'm working with some sample code here:
http://code.google.com/p/google-api-java-client/source/browse/picasa-android-sample/src/main/java/com/google/api/services/samples/picasa/android/PicasaSample.java?repo=samples
I authorized access in my Android app, but I cannot find where to now revoke access, so I can run through it again. Uninstalling the APK does not seem to reset any permissions.
I believe if you go to https://accounts.google.com/IssuedAuthSubTokens it should list your application under "Connected Sites, Apps and Services" from there you can revoke access.
Two steps to trigger the authorization page again:
go to https://accounts.google.com/IssuedAuthSubTokens to revoke the app you want. This will clear the permissions from server side.
go to your android device's settings->Data and time: fast-forward your time by a day or two. This will force the current token to expire.
It's not possible via any public, official API.
See:
https://groups.google.com/forum/?fromgroups=#!topic/android-developers/gOVZ0DF7ccg
http://grokbase.com/t/gg/android-developers/121j6ypxkb/revoke-permissions-to-access-google-accounts
Even uninstalling and re-installing the app doesn't help.
This might be the way on a rooted device:
How do you force AccountManager to show the "Access Request" screen after a user has already allowed access?
You need to programmatically revoke the token. First, try out the example app posted at:
https://developers.google.com/drive/quickstart-android
This example app displays the dialog to let you pick an account, then takes a photo and then uploads it to Google Drive. One important thing I discovered is that this sample app will eventually fail. I discovered that the camera portion of the app causes crashes. So disable the camera part of the code and just replace the file with some file on an SD card and upload the file to Drive instead.
To revoke the permission to use Drive, you need to execute the following code:
String token = credential.getToken();
HttpRequestFactory factory = HTTP_TRANSPORT.createRequestFactory();
GoogleUrl url = new GoogleUrl("https://accounts.google.com/o/oauth2/revoke?token=" + token);
HttpRequest request = factory.buildGetRequest(url);
HttpResponse response = request.execute();
Refer to the sample code on how to access the credential variable. Also, you must run the above code in a thread that is not on the main thread or it will fail.
You also need to add the following permissions. The sample code fails to indicate these permissions and without them the app will crash:
<uses-permission android:name="android.permission.ACCOUNT_MANAGER" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
If Eclipse complains that some of those permissions are only granted to the system, just run Clean Project and it will remove the warning. After you have done this, you should uninstall the app and reboot the device. For more information about revoking tokens, see the section "Revoking a Token" at:
https://developers.google.com/accounts/docs/OAuth2WebServer
After struggling to revoke authorisation for Gmail API permissions granted on my Android app (still in debug), I worked out that it does appear on https://security.google.com/settings/security/permissions like #David Waters mentions (it's a new link but goes to the same place) but only if you've properly enabled the API via the Google Developers Console. This means properly adding your OAuth 2.0 client ID, even if the app is still in development and in Debug Mode.
There's a very good guide on how to add your credentials on the Android Quickstart guide on the Gmail API site (Steps 1 & 2).
Using Google Play Services:
http://developer.android.com/reference/com/google/android/gms/auth/GoogleAuthUtil.html
Add https://www.googleapis.com/auth/userinfo.profile to your scope.
Example:
String scope="oauth2:https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile"
final String token = GoogleAuthUtil.getToken(context, "xxxx#gmail.com", scope);
OR "brute force"
Intent res = new Intent();
res.addCategory("account:xxxx#gmail.com");
res.addCategory("scope:oauth2:https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile");
res.putExtra("service", "oauth2:https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile");
Bundle extra= new Bundle();
extra.putString("androidPackageName","com.your.package");
res.putExtra("callerExtras",extra);
res.putExtra("androidPackageName","com.your.package");
res.putExtra("authAccount","xxxx#gmail.com");
String mPackage = "com.google.android.gms";
String mClass = "com.google.android.gms.auth.TokenActivity";
res.setComponent(new ComponentName(mPackage,mClass));
startActivityForResult(res,100);
Now, when you revoke the access here https://accounts.google.com/IssuedAuthSubTokens the application shows you the window for permission again in the device.
You can revoke account permissons on ...
https://security.google.com/settings/security/permissions
You can get there by [Account Settings] > [Account Permissions]
Proof that this answer is the real deal:
Look into your AndroidManifest file.

Categories

Resources