Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proguard issue of API ver 2.0.5 #58

Closed
fgoinai opened this issue Jun 15, 2016 · 4 comments
Closed

Proguard issue of API ver 2.0.5 #58

fgoinai opened this issue Jun 15, 2016 · 4 comments

Comments

@fgoinai
Copy link

fgoinai commented Jun 15, 2016

Some details: https://www.dropboxforum.com/hc/en-us/community/posts/206959906-Java-API-failure-after-Proguard-handling

Hi,

I found that if I use the recommendation proguard setting, i.e.

-dontwarn okhttp3.**
-dontwarn com.squareup.okhttp.**
-dontwarn com.google.appengine.**
-dontwarn javax.servlet.**`

The error will appear. All API throw same exception: Error in call to API function "users/API_PARAM": Invalid authorization value in HTTP header "Authorization": "Bearer". Expecting "Bearer "

06-15 10:05:00.623 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: java.util.concurrent.ExecutionException: com.dropbox.core.BadRequestException: Error in call to API function "users/get_current_account": Invalid authorization value in HTTP header "Authorization": "Bearer". Expecting "Bearer ".
06-15 10:05:00.623 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at java.util.concurrent.FutureTask.report(FutureTask.java:94)
06-15 10:05:00.623 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at java.util.concurrent.FutureTask.get(FutureTask.java:164)
06-15 10:05:00.623 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at hk.com.fgoproduction.getdroplets.Lib.Common.ThisApplication.runOnBgAndJoin(ThisApplication.kt:58)
06-15 10:05:00.623 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at hk.com.fgoproduction.getdroplets.Activity.MainActivity.threadExec(MainActivity.kt:187)
06-15 10:05:00.623 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at hk.com.fgoproduction.getdroplets.Activity.MainActivity.dropboxStatus(MainActivity.kt:176)
06-15 10:05:00.623 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at hk.com.fgoproduction.getdroplets.Activity.MainActivity.testAccessToken(MainActivity.kt:61)
06-15 10:05:00.623 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at hk.com.fgoproduction.getdroplets.Activity.MainActivity.onCreate(MainActivity.kt:43)
06-15 10:05:00.623 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at android.app.Activity.performCreate(Activity.java:6237)
06-15 10:05:00.623 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
06-15 10:05:00.623 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
06-15 10:05:00.623 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
06-15 10:05:00.623 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at android.app.ActivityThread.-wrap11(ActivityThread.java)
06-15 10:05:00.623 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
06-15 10:05:00.623 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at android.os.Handler.dispatchMessage(Handler.java:102)
06-15 10:05:00.623 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at android.os.Looper.loop(Looper.java:148)
06-15 10:05:00.623 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5417)
06-15 10:05:00.623 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at java.lang.reflect.Method.invoke(Native Method)
06-15 10:05:00.623 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
06-15 10:05:00.624 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
06-15 10:05:00.624 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: Caused by: com.dropbox.core.BadRequestException: Error in call to API function "users/get_current_account": Invalid authorization value in HTTP header "Authorization": "Bearer". Expecting "Bearer ".
06-15 10:05:00.624 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at com.dropbox.core.DbxRequestUtil.unexpectedStatus(DbxRequestUtil.java:285)
06-15 10:05:00.624 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at com.dropbox.core.v2.DbxRawClientV2$1.execute(DbxRawClientV2.java:107)
06-15 10:05:00.624 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at com.dropbox.core.v2.DbxRawClientV2.executeRetriable(DbxRawClientV2.java:252)
06-15 10:05:00.624 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at com.dropbox.core.v2.DbxRawClientV2.rpcStyle(DbxRawClientV2.java:97)
06-15 10:05:00.624 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at com.dropbox.core.v2.users.DbxUserUsersRequests.getCurrentAccount(DbxUserUsersRequests.java:120)
06-15 10:05:00.624 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at hk.com.fgoproduction.getdroplets.DropboxAPI.AFile.isDropboxOk(AFile.kt:139)
06-15 10:05:00.624 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at hk.com.fgoproduction.getdroplets.Activity.MainActivity$dropboxStatus$1.run(MainActivity.kt:176)
06-15 10:05:00.624 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
06-15 10:05:00.624 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
06-15 10:05:00.624 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
06-15 10:05:00.624 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
06-15 10:05:00.624 2823-2823/hk.com.fgoproduction.getdroplets W/System.err: at java.lang.Thread.run(Thread.java:818)

But if I add two proguard rules instead, all errors disappear.

-dontobfuscate
-dontshrink

Either one is lacked will cause the errors appear again. Any idea about on this instead of not using proguard?
I think proguard with dontobfuscate and dontshrink is useless at all.

@greg-db
Copy link
Contributor

greg-db commented Jun 15, 2016

Can you share some code that reproduces this? Thanks in advance!

@fgoinai
Copy link
Author

fgoinai commented Jun 16, 2016

Sure, my project body is located in here

@krieb
Copy link

krieb commented Jun 16, 2016

@fgoinai, I can't compile your GetDroplets-Pub app because its missing all the static resources (e.g. app/src/main/res). I am running gradle :assembleDebug. Am I missing a build step or were the resources omitted on accident/purpose?

So I've done some sleuthing, and here is what I've found:

  • Based on the errors you are encountering, it appears the access token must be empty or null:
Invalid authorization value in HTTP header "Authorization": "Bearer".  Expecting "Bearer <oauth2-access-token>".
ctx.getSharedPreferences(SETTING, Activity.MODE_PRIVATE).getString("access", null)
  • The DbxClientV2 constructor will eventually throw a NullPointerException if the access token is null, so we can assume we are not getting the default null value from Android's shared preferences. This must mean we have an empty string for our access token.
  • During the auth flow, your app parses the auth result JSON and stores it into the shared preferences object:
val tokenResult = JSON.parseObject(result, TokenResult::class.java)
val editor = share.value.edit()
editor.putString("access", tokenResult.access_token)
editor.apply()
  • The tokenResult.access_token parsed from the response could potentially be an empty string if ProGuard optimization messed with your JSON parser. I would suggest testing this to see if that is the case. Also, your app appears to log the OAuth response here, so I would check if the raw response looks correct as well.

Right now, the best I can guess is that the ProGuard optimization is causing a failure in your JSON parser for the auth result. This can happen when obfuscation is enabled since the TokenResult fields could get renamed. When the JSON parser attempts to decode the JSON response, it won't see the correct field names, and the default empty string value will be used instead. You will likely need to add a keep directive for your TokenResult class to avoid the field renaming:

-keep class hk.com.fgoproduction.getdroplets.Lib.OAuth.TokenResult { *; }

Try adding the keep directive and checking if tokenResult.access_token is null and let me know what you find.

@fgoinai
Copy link
Author

fgoinai commented Jun 18, 2016

Sorry about late reply and I have forgotten to push the resource.
After adding

-keep class hk.com.fgoproduction.getdroplets.Lib.OAuth.TokenResult { *; }
, the problem solved! Thank you very much for your help!

@krieb krieb closed this as completed Jun 30, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants