Completed OAuth2 flow in OsmLoginFragment

Signed-off-by: Sergiy Kozyr <s.trump@gmail.com>
This commit is contained in:
Sergiy Kozyr 2024-08-02 16:08:06 +03:00
parent c1cf2b5c94
commit 9081d45d9a
7 changed files with 96 additions and 4 deletions

View file

@ -66,6 +66,27 @@ Java_app_organicmaps_editor_OsmOAuth_nativeAuthWithPassword(JNIEnv * env, jclass
return nullptr;
}
JNIEXPORT jstring JNICALL
Java_app_organicmaps_editor_OsmOAuth_nativeAuthWithOAuth2Code(JNIEnv * env, jclass clazz, jstring oauth2code)
{
OsmOAuth auth = OsmOAuth::ServerAuth();
try
{
auto token = auth.FinishAuthorization(ToNativeString(env, oauth2code));
if (!token.empty())
{
auth.SetAuthToken(token);
return ToJavaString(env, token);
}
LOG(LWARNING, ("nativeAuthWithOAuth2Code: invalid OAuth2 code"));
}
catch (std::exception const & ex)
{
LOG(LWARNING, ("nativeAuthWithOAuth2Code error ", ex.what()));
}
return nullptr;
}
JNIEXPORT jstring JNICALL
Java_app_organicmaps_editor_OsmOAuth_nativeGetOsmUsername(JNIEnv * env, jclass, jstring oauthToken)
{

View file

@ -1,14 +1,31 @@
package app.organicmaps.editor;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import app.organicmaps.base.BaseMwmFragmentActivity;
public class OsmLoginActivity extends BaseMwmFragmentActivity
{
public static final String EXTRA_OAUTH2CODE = "oauth2code";
@Override
protected Class<? extends Fragment> getFragmentClass()
{
return OsmLoginFragment.class;
}
public static void OAuth2Callback(@NonNull Activity activity, String oauth2code)
{
final Intent i = new Intent(activity, OsmLoginActivity.class);
Bundle args = new Bundle();
args.putString(EXTRA_OAUTH2CODE, oauth2code);
args.putBoolean(ProfileActivity.EXTRA_REDIRECT_TO_PROFILE, true);
i.putExtras(args);
activity.startActivity(i);
}
}

View file

@ -36,6 +36,8 @@ public class OsmLoginFragment extends BaseMwmToolbarFragment
private TextInputEditText mLoginInput;
private TextInputEditText mPasswordInput;
private String mArgOAuth2Code;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
@ -62,6 +64,19 @@ public class OsmLoginFragment extends BaseMwmToolbarFragment
final String dataVersion = DateUtils.getShortDateFormatter().format(Framework.getDataVersion());
((TextView) view.findViewById(R.id.osm_presentation))
.setText(getString(R.string.osm_presentation, dataVersion));
readArguments();
if (mArgOAuth2Code != null && !mArgOAuth2Code.isEmpty())
continueOAuth2Flow(mArgOAuth2Code);
}
private void readArguments()
{
final Bundle arguments = getArguments();
if (arguments == null)
return;
mArgOAuth2Code = arguments.getString(OsmLoginActivity.EXTRA_OAUTH2CODE);
}
private void login()
@ -82,7 +97,7 @@ public class OsmLoginFragment extends BaseMwmToolbarFragment
private void loginWithBrowser()
{
mLoginWebsiteButton.setEnabled(false);
enableInput(false);
String[] oauthParams = OsmOAuth.nativeOAuthParams();
Uri oauth2url = Uri.parse(oauthParams[0] + "/oauth2/authorize")
@ -108,6 +123,35 @@ public class OsmLoginFragment extends BaseMwmToolbarFragment
mLoginInput.setEnabled(enable);
mLoginButton.setEnabled(enable);
mLostPasswordButton.setEnabled(enable);
mLoginWebsiteButton.setEnabled(enable);
}
// This method is called by MwmActivity & UrlProcessor when "om://oauth2/osm/callback?code=XXX" is handled
private void continueOAuth2Flow(String oauth2code)
{
if (!isAdded())
return;
if (oauth2code == null || oauth2code.length()==0)
{
enableInput(true);
onAuthFail();
}
else
{
// Do not enable UI until we finish interaction with OAuth2 API
enableInput(false);
ThreadPool.getWorker().execute(() -> {
// Finish OAuth2 auth flow and get username for UI.
final String oauthToken = OsmOAuth.nativeAuthWithOAuth2Code(oauth2code);
final String username = (oauthToken == null) ? null : OsmOAuth.nativeGetOsmUsername(oauthToken);
UiThread.run(() -> {
enableInput(true);
processAuth(oauthToken, username);
});
});
}
}
private void processAuth(String oauthToken, String username)
@ -136,7 +180,7 @@ public class OsmLoginFragment extends BaseMwmToolbarFragment
{
OsmOAuth.setAuthorization(requireContext(), oauthToken, username);
final Bundle extras = requireActivity().getIntent().getExtras();
if (extras != null && extras.getBoolean("redirectToProfile", false))
if (extras != null && extras.getBoolean(ProfileActivity.EXTRA_REDIRECT_TO_PROFILE, false))
startActivity(new Intent(requireContext(), ProfileActivity.class));
requireActivity().finish();
}

View file

@ -114,6 +114,13 @@ public final class OsmOAuth
@Nullable
public static native String nativeAuthWithPassword(String login, String password);
/**
* @return string with OAuth2 token
*/
@WorkerThread
@Nullable
public static native String nativeAuthWithOAuth2Code(String oauth2code);
@WorkerThread
@Nullable
public static native String nativeGetOsmUsername(String oauthToken);

View file

@ -6,6 +6,8 @@ import app.organicmaps.base.BaseMwmFragmentActivity;
public class ProfileActivity extends BaseMwmFragmentActivity
{
public static final String EXTRA_REDIRECT_TO_PROFILE = "redirectToProfile";
@Override
protected Class<? extends Fragment> getFragmentClass()
{

View file

@ -93,7 +93,7 @@ public class ProfileFragment extends BaseMwmToolbarFragment
else
{
Intent intent = new Intent(requireContext(), OsmLoginActivity.class);
intent.putExtra("redirectToProfile", true);
intent.putExtra(ProfileActivity.EXTRA_REDIRECT_TO_PROFILE, true);
startActivity(intent);
requireActivity().finish();
}

View file

@ -19,6 +19,7 @@ import app.organicmaps.api.RoutePoint;
import app.organicmaps.bookmarks.data.BookmarkManager;
import app.organicmaps.bookmarks.data.FeatureId;
import app.organicmaps.bookmarks.data.MapObject;
import app.organicmaps.editor.OsmLoginActivity;
import app.organicmaps.routing.RoutingController;
import app.organicmaps.search.SearchActivity;
import app.organicmaps.search.SearchEngine;
@ -136,7 +137,7 @@ public class Factory
SearchEngine.INSTANCE.cancelInteractiveSearch();
final String oauth2code = Framework.nativeGetParsedOAuth2Code();
Log.i("TAG", oauth2code);
OsmLoginActivity.OAuth2Callback(target, oauth2code);
return true;
}