From c1cf2b5c9432979177a201237f6b185fdcbb1755 Mon Sep 17 00:00:00 2001 From: Sergiy Kozyr Date: Fri, 2 Aug 2024 15:09:53 +0300 Subject: [PATCH] Implemented parsing of om://oauth2/osm/callback URLs Signed-off-by: Sergiy Kozyr --- .../src/main/cpp/app/organicmaps/Framework.cpp | 7 +++++++ .../main/java/app/organicmaps/Framework.java | 1 + .../java/app/organicmaps/api/RequestType.java | 3 ++- .../java/app/organicmaps/intent/Factory.java | 10 ++++++++++ map/framework.cpp | 5 +++++ map/framework.hpp | 1 + map/map_tests/mwm_url_tests.cpp | 7 +++++++ map/mwm_url.cpp | 18 ++++++++++++++++++ map/mwm_url.hpp | 8 ++++++++ 9 files changed, 59 insertions(+), 1 deletion(-) diff --git a/android/app/src/main/cpp/app/organicmaps/Framework.cpp b/android/app/src/main/cpp/app/organicmaps/Framework.cpp index fe3b5435cf..76d04b2df9 100644 --- a/android/app/src/main/cpp/app/organicmaps/Framework.cpp +++ b/android/app/src/main/cpp/app/organicmaps/Framework.cpp @@ -862,6 +862,13 @@ Java_app_organicmaps_Framework_nativeGetParsedAppName(JNIEnv * env, jclass) return (appName.empty()) ? nullptr : jni::ToJavaString(env, appName); } +JNIEXPORT jstring JNICALL +Java_app_organicmaps_Framework_nativeGetParsedOAuth2Code(JNIEnv * env, jclass) +{ + std::string const & code = frm()->GetParsedOAuth2Code(); + return jni::ToJavaString(env, code); +} + JNIEXPORT jstring JNICALL Java_app_organicmaps_Framework_nativeGetParsedBackUrl(JNIEnv * env, jclass) { diff --git a/android/app/src/main/java/app/organicmaps/Framework.java b/android/app/src/main/java/app/organicmaps/Framework.java index 2a076225c3..a5d65bbb96 100644 --- a/android/app/src/main/java/app/organicmaps/Framework.java +++ b/android/app/src/main/java/app/organicmaps/Framework.java @@ -239,6 +239,7 @@ public class Framework public static native ParsedRoutingData nativeGetParsedRoutingData(); public static native ParsedSearchRequest nativeGetParsedSearchRequest(); public static native @Nullable String nativeGetParsedAppName(); + public static native @Nullable String nativeGetParsedOAuth2Code(); @Nullable @Size(2) public static native double[] nativeGetParsedCenterLatLon(); public static native @Nullable String nativeGetParsedBackUrl(); diff --git a/android/app/src/main/java/app/organicmaps/api/RequestType.java b/android/app/src/main/java/app/organicmaps/api/RequestType.java index e90743a5bb..0634d305cf 100644 --- a/android/app/src/main/java/app/organicmaps/api/RequestType.java +++ b/android/app/src/main/java/app/organicmaps/api/RequestType.java @@ -6,7 +6,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.SOURCE) -@IntDef({RequestType.INCORRECT, RequestType.MAP, RequestType.ROUTE, RequestType.SEARCH, RequestType.CROSSHAIR}) +@IntDef({RequestType.INCORRECT, RequestType.MAP, RequestType.ROUTE, RequestType.SEARCH, RequestType.CROSSHAIR, RequestType.OAUTH2}) public @interface RequestType { // Represents url_scheme::ParsedMapApi::UrlType from c++ part. @@ -15,4 +15,5 @@ public @interface RequestType public static final int ROUTE = 2; public static final int SEARCH = 3; public static final int CROSSHAIR = 4; + public static final int OAUTH2 = 5; } diff --git a/android/app/src/main/java/app/organicmaps/intent/Factory.java b/android/app/src/main/java/app/organicmaps/intent/Factory.java index 2ddf4a28c6..46c10b4213 100644 --- a/android/app/src/main/java/app/organicmaps/intent/Factory.java +++ b/android/app/src/main/java/app/organicmaps/intent/Factory.java @@ -3,6 +3,7 @@ package app.organicmaps.intent; import android.content.ContentResolver; import android.content.Intent; import android.net.Uri; +import android.util.Log; import androidx.annotation.NonNull; import androidx.core.content.IntentCompat; @@ -128,6 +129,15 @@ public class Factory Framework.nativeSetViewportCenter(latlon[0], latlon[1], SEARCH_IN_VIEWPORT_ZOOM); } + return true; + } + case RequestType.OAUTH2: + { + SearchEngine.INSTANCE.cancelInteractiveSearch(); + + final String oauth2code = Framework.nativeGetParsedOAuth2Code(); + Log.i("TAG", oauth2code); + return true; } } diff --git a/map/framework.cpp b/map/framework.cpp index e81b282ceb..eff1b1b136 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -1738,6 +1738,11 @@ url_scheme::SearchRequest Framework::GetParsedSearchRequest() const return m_parsedMapApi.GetSearchRequest(); } +std::string Framework::GetParsedOAuth2Code() const +{ + return m_parsedMapApi.GetOAuth2Code(); +} + std::string const & Framework::GetParsedAppName() const { return m_parsedMapApi.GetAppName(); diff --git a/map/framework.hpp b/map/framework.hpp index e345b7d721..6b7ea84dbe 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -578,6 +578,7 @@ public: ParsedRoutingData GetParsedRoutingData() const; url_scheme::SearchRequest GetParsedSearchRequest() const; + std::string GetParsedOAuth2Code() const; std::string const & GetParsedAppName() const; std::string const & GetParsedBackUrl() const; ms::LatLon GetParsedCenterLatLon() const; diff --git a/map/map_tests/mwm_url_tests.cpp b/map/map_tests/mwm_url_tests.cpp index 6c0e0f1454..6763f1f32e 100644 --- a/map/map_tests/mwm_url_tests.cpp +++ b/map/map_tests/mwm_url_tests.cpp @@ -474,6 +474,13 @@ UNIT_TEST(AppNameTest) } } +UNIT_TEST(OAuth2Test) +{ + ParsedMapApi api("om://oauth2/osm/callback?code=THE_MEGA_CODE"); + TEST_EQUAL(api.GetRequestType(), UrlType::OAuth2, ()); + TEST_EQUAL(api.GetOAuth2Code(), "THE_MEGA_CODE", ()); +} + namespace { string generatePartOfUrl(url_scheme::MapPoint const & point) diff --git a/map/mwm_url.cpp b/map/mwm_url.cpp index 9eb3dbf8fc..b99e15109d 100644 --- a/map/mwm_url.cpp +++ b/map/mwm_url.cpp @@ -175,6 +175,22 @@ ParsedMapApi::UrlType ParsedMapApi::SetUrlAndParse(std::string const & raw) return m_requestType = UrlType::Crosshair; } + else if (type == "oauth2") + { + if (url.GetPath() != "osm/callback") + return m_requestType = UrlType::Incorrect; + + url.ForEachParam([this](auto const & key, auto const & value) + { + if (key == "code") + m_oauth2code = value; + }); + + if (m_oauth2code.empty()) + return m_requestType = UrlType::Incorrect; + else + return m_requestType = UrlType::OAuth2; + } else if (checkForGe0Link) { // The URL is prefixed by one of the kGe0Prefixes AND doesn't match any supported API call: @@ -386,6 +402,7 @@ void ParsedMapApi::Reset() m_mapPoints.clear(); m_routePoints.clear(); m_searchRequest = {}; + m_oauth2code = {}; m_globalBackUrl ={}; m_appName = {}; m_centerLatLon = ms::LatLon::Invalid(); @@ -467,6 +484,7 @@ std::string DebugPrint(ParsedMapApi::UrlType type) case ParsedMapApi::UrlType::Route: return "Route"; case ParsedMapApi::UrlType::Search: return "Search"; case ParsedMapApi::UrlType::Crosshair: return "Crosshair"; + case ParsedMapApi::UrlType::OAuth2: return "OAuth2"; } UNREACHABLE(); } diff --git a/map/mwm_url.hpp b/map/mwm_url.hpp index 6862d74794..b5bc22ada3 100644 --- a/map/mwm_url.hpp +++ b/map/mwm_url.hpp @@ -45,6 +45,7 @@ public: Route = 2, Search = 3, Crosshair = 4, + OAuth2 = 5, }; ParsedMapApi() = default; @@ -93,6 +94,12 @@ public: return m_searchRequest; } + std::string const & GetOAuth2Code() const + { + ASSERT_EQUAL(m_requestType, UrlType::OAuth2, ("Expected Search API")); + return m_oauth2code; + } + private: void ParseMapParam(std::string const & key, std::string const & value, bool & correctOrder); @@ -107,6 +114,7 @@ private: SearchRequest m_searchRequest; std::string m_globalBackUrl; std::string m_appName; + std::string m_oauth2code; ms::LatLon m_centerLatLon = ms::LatLon::Invalid(); std::string m_routingType; int m_version = 0;