Added authentication system

This commit is contained in:
r.kuznetsov 2017-09-22 14:07:18 +03:00 committed by Aleksandr Zatsepin
parent 416dfdffd3
commit 343134145b
9 changed files with 247 additions and 0 deletions

View file

@ -1483,4 +1483,19 @@ Java_com_mapswithme_maps_Framework_nativeGetSearchBanners(JNIEnv * env, jclass)
{
return usermark_helper::ToBannersArray(env, frm()->GetAdsEngine().GetSearchBanners());
}
JNIEXPORT void JNICALL
Java_com_mapswithme_maps_Framework_nativeAuthenticateUser(JNIEnv * env, jclass,
jstring socialToken,
jint socialTokenType)
{
auto const tokenStr = jni::ToNativeString(env, socialToken);
frm()->GetUser().Authenticate(tokenStr, static_cast<User::SocialTokenType>(socialTokenType));
}
JNIEXPORT jboolean JNICALL
Java_com_mapswithme_maps_Framework_nativeIsUserAuthenticated()
{
return frm()->GetUser().IsAuthenticated();
}
} // extern "C"

View file

@ -77,6 +77,13 @@ public class Framework
public static final int ROUTE_REBUILD_AFTER_POINTS_LOADING = 0;
@Retention(RetentionPolicy.SOURCE)
@IntDef({ SOCIAL_TOKEN_FACEBOOK, SOCIAL_TOKEN_GOOGLE })
public @interface SocialTokenType {}
public static final int SOCIAL_TOKEN_FACEBOOK = 0;
public static final int SOCIAL_TOKEN_GOOGLE = 1;
@SuppressWarnings("unused")
public interface MapObjectListener
{
@ -370,4 +377,8 @@ public class Framework
public static native void nativeDeleteSavedRoutePoints();
public static native Banner[] nativeGetSearchBanners();
public static native void nativeAuthenticateUser(@NonNull String socialToken,
@SocialTokenType int socialTokenType);
public static native boolean nativeIsUserAuthenticated();
}

View file

@ -87,6 +87,7 @@ else
#define LOCALS_API_KEY ""
#define LOCALS_API_URL ""
#define LOCALS_PAGE_URL ""
#define PASSPORT_URL ""
' > "$PRIVATE_HEADER"
echo 'ext {

View file

@ -68,6 +68,8 @@ set(
track.hpp
traffic_manager.cpp
traffic_manager.hpp
user.cpp
user.hpp
user_mark_container.cpp
user_mark_container.hpp
user_mark.cpp

View file

@ -12,6 +12,7 @@
#include "map/routing_mark.hpp"
#include "map/track.hpp"
#include "map/traffic_manager.hpp"
#include "map/user.hpp"
#include "drape_frontend/gui/skin.hpp"
#include "drape_frontend/drape_api.hpp"
@ -203,6 +204,8 @@ protected:
LocalAdsManager m_localAdsManager;
User m_user;
/// This function will be called by m_storage when latest local files
/// is downloaded.
void OnCountryFileDownloaded(storage::TCountryId const & countryId, storage::TLocalFilePtr const localFile);
@ -236,6 +239,9 @@ public:
df::DrapeApi & GetDrapeApi() { return m_drapeApi; }
User & GetUser() { return m_user; }
User const & GetUser() const { return m_user; }
/// Migrate to new version of very different data.
bool IsEnoughSpaceForMigrate() const;
storage::TCountryId PreMigrate(ms::LatLon const & position, storage::Storage::TChangeCountryFunction const & change,

View file

@ -38,6 +38,7 @@ HEADERS += \
taxi_delegate.hpp \
track.hpp \
traffic_manager.hpp \
user.hpp \
user_mark.hpp \
user_mark_container.hpp \
@ -72,6 +73,7 @@ SOURCES += \
taxi_delegate.cpp \
track.cpp \
traffic_manager.cpp \
user.cpp \
user_mark.cpp \
user_mark_container.cpp \

165
map/user.cpp Normal file
View file

@ -0,0 +1,165 @@
#include "map/user.hpp"
#include "platform/http_client.hpp"
#include "platform/platform.hpp"
#include "coding/url_encode.hpp"
#include "base/logging.hpp"
#include "3party/jansson/myjansson.hpp"
#include <chrono>
#include <sstream>
#include <thread>
#define STAGE_PASSPORT_SERVER
#include "private.h"
namespace
{
std::string const kMapsMeTokenKey = "MapsMeToken";
std::string const kServerUrl = PASSPORT_URL;
std::string AuthenticationUrl(std::string const & socialToken,
User::SocialTokenType socialTokenType)
{
if (kServerUrl.empty())
return {};
std::string socialTokenStr;
switch (socialTokenType)
{
case User::SocialTokenType::Facebook:
socialTokenStr = "facebook";
break;
case User::SocialTokenType::Google:
socialTokenStr = "google";
break;
default:
LOG(LWARNING, ("Unknown social token type"));
return {};
}
std::ostringstream ss;
ss << kServerUrl << "/register-by-token/" << socialTokenStr
<< "/?access_token=" << UrlEncode(socialToken);
return ss.str();
}
std::string ParseAccessToken(std::string const & src)
{
my::Json root(src.c_str());
std::string tokenStr;
FromJSONObject(root.get(), "access_token", tokenStr);
return tokenStr;
}
} // namespace
User::User()
{
Init();
}
User::~User()
{
std::lock_guard<std::mutex> lock(m_mutex);
m_needTerminate = true;
m_condition.notify_one();
}
void User::Init()
{
std::string token;
if (GetPlatform().GetSecureStorage().Load(kMapsMeTokenKey, token))
{
std::lock_guard<std::mutex> lock(m_mutex);
m_accessToken = token;
}
}
void User::ResetAccessToken()
{
std::lock_guard<std::mutex> lock(m_mutex);
m_accessToken.clear();
GetPlatform().GetSecureStorage().Remove(kMapsMeTokenKey);
}
bool User::IsAuthenticated() const
{
std::lock_guard<std::mutex> lock(m_mutex);
return !m_accessToken.empty();
}
std::string const & User::GetAccessToken() const
{
std::lock_guard<std::mutex> lock(m_mutex);
return m_accessToken;
}
void User::SetAccessToken(std::string const & accessToken)
{
std::lock_guard<std::mutex> lock(m_mutex);
m_accessToken = accessToken;
GetPlatform().GetSecureStorage().Save(kMapsMeTokenKey, m_accessToken);
}
void User::Authenticate(std::string const & socialToken, SocialTokenType socialTokenType)
{
std::string const url = AuthenticationUrl(socialToken, socialTokenType);
if (url.empty())
{
LOG(LWARNING, ("Passport service is unavailable."));
return;
}
{
std::lock_guard<std::mutex> lock(m_mutex);
if (m_authenticationInProgress)
return;
m_authenticationInProgress = true;
}
//TODO: refactor this after adding support of delayed tasks in WorkerThread.
m_workerThread.Push([this, url]()
{
uint8_t constexpr kAttemptsCount = 3;
uint32_t constexpr kWaitingInSeconds = 5;
uint32_t constexpr kDegradationScalar = 2;
uint32_t waitingTime = kWaitingInSeconds;
for (uint8_t i = 0; i < kAttemptsCount; ++i)
{
platform::HttpClient request(url);
request.SetRawHeader("Accept", "application/json");
// TODO: Now passport service uses redirection. If it becomes false, uncomment checking.
if (request.RunHttpRequest())// && !request.WasRedirected())
{
if (request.ErrorCode() == 200) // Ok.
{
SetAccessToken(ParseAccessToken(request.ServerResponse()));
break;
}
if (request.ErrorCode() == 403) // Forbidden.
{
ResetAccessToken();
break;
}
}
// Wait for some time and retry.
std::unique_lock<std::mutex> lock(m_mutex);
m_condition.wait_for(lock, std::chrono::seconds(waitingTime),
[this]{return m_needTerminate;});
if (m_needTerminate)
break;
waitingTime *= kDegradationScalar;
}
{
std::lock_guard<std::mutex> lock(m_mutex);
m_authenticationInProgress = false;
}
});
}

37
map/user.hpp Normal file
View file

@ -0,0 +1,37 @@
#pragma once
#include "base/worker_thread.hpp"
#include <condition_variable>
#include <mutex>
#include <string>
// This class is thread-safe.
class User
{
public:
enum SocialTokenType
{
Facebook,
Google
};
User();
~User();
void Authenticate(std::string const & socialToken, SocialTokenType socialTokenType);
bool IsAuthenticated() const;
void ResetAccessToken();
std::string const & GetAccessToken() const;
private:
void Init();
void SetAccessToken(std::string const & accessToken);
std::string m_accessToken;
mutable std::mutex m_mutex;
std::condition_variable m_condition;
bool m_needTerminate = false;
bool m_authenticationInProgress = false;
base::WorkerThread m_workerThread;
};

View file

@ -32,6 +32,8 @@
454649F21F2728CE00EF4064 /* local_ads_mark.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 454649F01F2728CE00EF4064 /* local_ads_mark.hpp */; };
45580ABE1E2CBD5E00CD535D /* benchmark_tools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45580ABC1E2CBD5E00CD535D /* benchmark_tools.cpp */; };
45580ABF1E2CBD5E00CD535D /* benchmark_tools.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 45580ABD1E2CBD5E00CD535D /* benchmark_tools.hpp */; };
45A2D9D51F7556EB003310A0 /* user.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45A2D9D31F7556EB003310A0 /* user.cpp */; };
45A2D9D61F7556EB003310A0 /* user.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 45A2D9D41F7556EB003310A0 /* user.hpp */; };
45D287671E966E3400587F05 /* liblocal_ads.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 45D287661E966E3400587F05 /* liblocal_ads.a */; };
670E39401C46C5C700E9C0A6 /* gps_tracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 670E393E1C46C5C700E9C0A6 /* gps_tracker.cpp */; };
670E39411C46C5C700E9C0A6 /* gps_tracker.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 670E393F1C46C5C700E9C0A6 /* gps_tracker.hpp */; };
@ -162,6 +164,8 @@
454649F01F2728CE00EF4064 /* local_ads_mark.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = local_ads_mark.hpp; sourceTree = "<group>"; };
45580ABC1E2CBD5E00CD535D /* benchmark_tools.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = benchmark_tools.cpp; sourceTree = "<group>"; };
45580ABD1E2CBD5E00CD535D /* benchmark_tools.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = benchmark_tools.hpp; sourceTree = "<group>"; };
45A2D9D31F7556EB003310A0 /* user.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = user.cpp; sourceTree = "<group>"; };
45A2D9D41F7556EB003310A0 /* user.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = user.hpp; sourceTree = "<group>"; };
45D287661E966E3400587F05 /* liblocal_ads.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblocal_ads.a; path = "../../../omim-build/xcode/Debug-iphonesimulator/liblocal_ads.a"; sourceTree = "<group>"; };
670E393E1C46C5C700E9C0A6 /* gps_tracker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gps_tracker.cpp; sourceTree = "<group>"; };
670E393F1C46C5C700E9C0A6 /* gps_tracker.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = gps_tracker.hpp; sourceTree = "<group>"; };
@ -435,6 +439,8 @@
675345BD1A4054AD00A0A8C3 /* map */ = {
isa = PBXGroup;
children = (
45A2D9D31F7556EB003310A0 /* user.cpp */,
45A2D9D41F7556EB003310A0 /* user.hpp */,
675345CB1A4054E800A0A8C3 /* address_finder.cpp */,
45201E921CE4AC90008A4842 /* api_mark_point.cpp */,
34921F611BFA0A6900737D6E /* api_mark_point.hpp */,
@ -523,6 +529,7 @@
3D47B2941F054BC5000828D2 /* taxi_delegate.hpp in Headers */,
3D47B2C81F20EF06000828D2 /* displayed_categories_modifiers.hpp in Headers */,
348AB57D1D7EE0C6009F8301 /* chart_generator.hpp in Headers */,
45A2D9D61F7556EB003310A0 /* user.hpp in Headers */,
F63421F91DF9BF9100A96868 /* reachable_by_taxi_checker.hpp in Headers */,
6753469E1A4054E800A0A8C3 /* user_mark_container.hpp in Headers */,
675346491A4054E800A0A8C3 /* bookmark_manager.hpp in Headers */,
@ -663,6 +670,7 @@
675346661A4054E800A0A8C3 /* ge0_parser.cpp in Sources */,
F6D2CE7E1EDEB7F500636DFD /* routing_manager.cpp in Sources */,
3D74ABBE1EA76F1D0063A898 /* local_ads_supported_types.cpp in Sources */,
45A2D9D51F7556EB003310A0 /* user.cpp in Sources */,
0C2B73DE1E92AB9900530BB8 /* local_ads_manager.cpp in Sources */,
F6B283071C1B03320081957A /* gps_track_storage.cpp in Sources */,
6753463A1A4054E800A0A8C3 /* address_finder.cpp in Sources */,