From c132055c5dd06859b53d7fbc90d0ea016108d378 Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Wed, 28 Mar 2018 16:01:32 +0300 Subject: [PATCH] Added core support of login via phone number --- .../src/com/mapswithme/maps/Framework.java | 6 +- .../util/statistics/Statistics.java | 4 + .../Common/Statistics/StatisticsStrings.h | 1 + .../AuthorizationViewController.swift | 12 ++- .../Authorization/MWMAuthorizationViewModel.h | 3 +- .../MWMAuthorizationViewModel.mm | 4 + map/user.cpp | 76 +++++++++++++++---- map/user.hpp | 3 +- 8 files changed, 87 insertions(+), 22 deletions(-) diff --git a/android/src/com/mapswithme/maps/Framework.java b/android/src/com/mapswithme/maps/Framework.java index f1033377ff..8b9fa9d724 100644 --- a/android/src/com/mapswithme/maps/Framework.java +++ b/android/src/com/mapswithme/maps/Framework.java @@ -81,13 +81,15 @@ public class Framework public static final int ROUTE_REBUILD_AFTER_POINTS_LOADING = 0; @Retention(RetentionPolicy.SOURCE) - @IntDef({ SOCIAL_TOKEN_FACEBOOK, SOCIAL_TOKEN_GOOGLE, TOKEN_MAPSME }) + @IntDef({ SOCIAL_TOKEN_FACEBOOK, SOCIAL_TOKEN_GOOGLE, SOCIAL_TOKEN_PHONE, TOKEN_MAPSME }) public @interface AuthTokenType {} public static final int SOCIAL_TOKEN_FACEBOOK = 0; public static final int SOCIAL_TOKEN_GOOGLE = 1; - public static final int TOKEN_MAPSME = 2; + public static final int SOCIAL_TOKEN_PHONE = 2; + //TODO(@alexzatsepin): remove TOKEN_MAPSME from this list. + public static final int TOKEN_MAPSME = 3; @SuppressWarnings("unused") public interface MapObjectListener diff --git a/android/src/com/mapswithme/util/statistics/Statistics.java b/android/src/com/mapswithme/util/statistics/Statistics.java index f27ad5e1d1..4723d4196a 100644 --- a/android/src/com/mapswithme/util/statistics/Statistics.java +++ b/android/src/com/mapswithme/util/statistics/Statistics.java @@ -107,6 +107,7 @@ import static com.mapswithme.util.statistics.Statistics.ParamValue.GOOGLE; import static com.mapswithme.util.statistics.Statistics.ParamValue.HOLIDAY; import static com.mapswithme.util.statistics.Statistics.ParamValue.MAPSME; import static com.mapswithme.util.statistics.Statistics.ParamValue.OPENTABLE; +import static com.mapswithme.util.statistics.Statistics.ParamValue.PHONE; import static com.mapswithme.util.statistics.Statistics.ParamValue.SEARCH_BOOKING_COM; import static com.mapswithme.util.statistics.Statistics.ParamValue.VIATOR; @@ -395,6 +396,7 @@ public enum Statistics public static final String ANY = "any"; public static final String GOOGLE = "google"; public static final String MAPSME = "mapsme"; + public static final String PHONE = "phone"; } // Initialized once in constructor and does not change until the process restarts. @@ -982,6 +984,8 @@ public enum Statistics return FACEBOOK; case Framework.SOCIAL_TOKEN_GOOGLE: return GOOGLE; + case Framework.SOCIAL_TOKEN_PHONE: + return PHONE; case Framework.TOKEN_MAPSME: return MAPSME; default: diff --git a/iphone/Maps/Common/Statistics/StatisticsStrings.h b/iphone/Maps/Common/Statistics/StatisticsStrings.h index c0bc07864e..c5ea44152e 100644 --- a/iphone/Maps/Common/Statistics/StatisticsStrings.h +++ b/iphone/Maps/Common/Statistics/StatisticsStrings.h @@ -213,6 +213,7 @@ static NSString * const kStatOrientation = @"Orientation"; static NSString * const kStatOther = @"Other"; static NSString * const kStatOut = @"Out"; static NSString * const kStatPedestrian = @"Pedestrian"; +static NSString * const kStatPhone = @"Phone"; static NSString * const kStatPlacePage = @"placepage"; static NSString * const kStatPlacePageBannerBlank = @"Placepage_Banner_blank"; static NSString * const kStatPlacePageBannerClick = @"Placepage_Banner_click"; diff --git a/iphone/Maps/UI/Authorization/AuthorizationViewController.swift b/iphone/Maps/UI/Authorization/AuthorizationViewController.swift index 2587e3ee6f..1f63550f81 100644 --- a/iphone/Maps/UI/Authorization/AuthorizationViewController.swift +++ b/iphone/Maps/UI/Authorization/AuthorizationViewController.swift @@ -165,10 +165,18 @@ final class AuthorizationViewController: MWMViewController { dismiss(animated: true) completionHandler?(self) } + + private func getProviderStatStr(type: MWMSocialTokenType) -> String { + switch type { + case .facebook: return kStatFacebook + case .google: return kStatGoogle + case .phone: return kStatPhone + } + } private func process(error: Error, type: MWMSocialTokenType) { Statistics.logEvent(kStatUGCReviewAuthError, withParameters: [ - kStatProvider: type == .facebook ? kStatFacebook : kStatGoogle, + kStatProvider: getProviderStatStr(type: type), kStatError: error.localizedDescription, ]) textLabel.text = L("profile_authorization_error") @@ -176,7 +184,7 @@ final class AuthorizationViewController: MWMViewController { } private func process(token: String, type: MWMSocialTokenType) { - Statistics.logEvent(kStatUGCReviewAuthExternalRequestSuccess, withParameters: [kStatProvider: type == .facebook ? kStatFacebook : kStatGoogle]) + Statistics.logEvent(kStatUGCReviewAuthExternalRequestSuccess, withParameters: [kStatProvider: getProviderStatStr(type: type)]) ViewModel.authenticate(withToken: token, type: type, source: sourceComponent) { success in if success { self.successHandler?(type) diff --git a/iphone/Maps/UI/Authorization/MWMAuthorizationViewModel.h b/iphone/Maps/UI/Authorization/MWMAuthorizationViewModel.h index 50a479799f..44cfb7cb23 100644 --- a/iphone/Maps/UI/Authorization/MWMAuthorizationViewModel.h +++ b/iphone/Maps/UI/Authorization/MWMAuthorizationViewModel.h @@ -1,6 +1,7 @@ typedef NS_ENUM(NSInteger, MWMSocialTokenType) { MWMSocialTokenTypeGoogle, - MWMSocialTokenTypeFacebook + MWMSocialTokenTypeFacebook, + MWMSocialTokenTypePhone }; typedef NS_ENUM(NSInteger, MWMAuthorizationSource) { diff --git a/iphone/Maps/UI/Authorization/MWMAuthorizationViewModel.mm b/iphone/Maps/UI/Authorization/MWMAuthorizationViewModel.mm index bb2037c40a..898f41a7a4 100644 --- a/iphone/Maps/UI/Authorization/MWMAuthorizationViewModel.mm +++ b/iphone/Maps/UI/Authorization/MWMAuthorizationViewModel.mm @@ -66,6 +66,10 @@ provider = kStatFacebook; socialTokenType = User::SocialTokenType::Facebook; break; + case MWMSocialTokenTypePhone: + provider = kStatPhone; + socialTokenType = User::SocialTokenType::Phone; + break; } auto s = std::make_unique(); s->m_postCallAction = User::Subscriber::Action::RemoveSubscriber; diff --git a/map/user.cpp b/map/user.cpp index 545f8dd608..5b48f0f297 100644 --- a/map/user.cpp +++ b/map/user.cpp @@ -3,12 +3,16 @@ #include "platform/http_client.hpp" #include "platform/platform.hpp" +#include "coding/serdes_json.hpp" #include "coding/url_encode.hpp" +#include "coding/writer.hpp" #include "base/logging.hpp" #include "base/stl_helpers.hpp" #include "base/string_utils.hpp" +#include "base/visitor.hpp" + #include "3party/Alohalytics/src/alohalytics.h" #include "3party/jansson/myjansson.hpp" @@ -41,24 +45,28 @@ std::string AuthenticationUrl(std::string const & socialToken, if (kPassportServerUrl.empty()) return {}; - std::string socialTokenStr; + std::ostringstream ss; + ss << kPassportServerUrl; switch (socialTokenType) { case User::SocialTokenType::Facebook: - socialTokenStr = "facebook"; - break; - case User::SocialTokenType::Google: - socialTokenStr = "google-oauth2"; - break; - default: - LOG(LWARNING, ("Unknown social token type")); - return {}; + { + ss << "/register-by-token/facebook/?access_token=" << UrlEncode(socialToken) + << "&app=" << kAppName; + return ss.str(); + } + case User::SocialTokenType::Google: + { + ss << "/register-by-token/google-oauth2/?access_token=" << UrlEncode(socialToken) + << "&app=" << kAppName; + return ss.str(); + } + case User::SocialTokenType::Phone: + { + ss << "/otp/token/"; + return ss.str(); + } } - - std::ostringstream ss; - ss << kPassportServerUrl << "/register-by-token/" << socialTokenStr - << "/?access_token=" << UrlEncode(socialToken) << "&app=" << kAppName; - return ss.str(); } std::string UserDetailsUrl() @@ -121,6 +129,31 @@ std::vector DeserializeReviewIds(std::string const & reviewIdsSrc) } return result; } + +struct PhoneAuthRequestData +{ + std::string m_cliendId; + std::string m_code; + + explicit PhoneAuthRequestData(std::string const & code) + : m_cliendId("phone_device_app") + , m_code(code) + {} + + DECLARE_VISITOR(visitor(m_cliendId, "client_id"), + visitor(m_code, "code")) +}; + +template +std::string SerializeToJson(DataType const & data) +{ + std::string jsonStr; + using Sink = MemWriter; + Sink sink(jsonStr); + coding::SerializerJson serializer(sink); + serializer(data); + return jsonStr; +} } // namespace User::User() @@ -207,9 +240,20 @@ void User::Authenticate(std::string const & socialToken, SocialTokenType socialT if (!StartAuthentication()) return; - GetPlatform().RunTask(Platform::Thread::Network, [this, url]() + BuildRequestHandler phoneAuthParams; + if (socialTokenType == SocialTokenType::Phone) { - Request(url, nullptr, [this](std::string const & response) + phoneAuthParams = [socialToken](platform::HttpClient & request) + { + auto jsonData = SerializeToJson(PhoneAuthRequestData(socialToken)); + request.SetBodyData(jsonData, "application/json"); + }; + } + + GetPlatform().RunTask(Platform::Thread::Network, + [this, url, phoneAuthParams = std::move(phoneAuthParams)]() + { + Request(url, phoneAuthParams, [this](std::string const & response) { SetAccessToken(ParseAccessToken(response)); FinishAuthentication(); diff --git a/map/user.hpp b/map/user.hpp index 3d71fad871..cb7fc58b40 100644 --- a/map/user.hpp +++ b/map/user.hpp @@ -25,7 +25,8 @@ public: enum SocialTokenType { Facebook, - Google + Google, + Phone }; struct Subscriber