[android] Phone auth

This commit is contained in:
Arsentiy Milchakov 2018-04-11 19:41:40 +03:00 committed by Roman Kuznetsov
parent dcb9a778f9
commit cd8c347fd5
13 changed files with 223 additions and 22 deletions

View file

@ -409,6 +409,13 @@
<data android:scheme="@string/fb_login_protocol_scheme"/>
</intent-filter>
</activity>
<!-- authorisation by phone number-->
<activity
android:name="com.mapswithme.maps.auth.PhoneAuthActivity"
android:configChanges="orientation|screenLayout|screenSize|keyboardHidden"
android:windowSoftInputMode="adjustResize"
android:label="@string/authorization_button_sign_in"/>
<activity android:name="com.mopub.common.MoPubBrowser" android:configChanges="keyboardHidden|orientation|screenSize"/>
<activity
android:name=".search.FilterActivity"

View file

@ -1560,6 +1560,13 @@ Java_com_mapswithme_maps_Framework_nativeIsUserAuthenticated()
return frm()->GetUser().IsAuthenticated();
}
JNIEXPORT jstring JNICALL
Java_com_mapswithme_maps_Framework_nativeGetPhoneAuthUrl(JNIEnv * env, jclass, jstring redirectUrl)
{
return jni::ToJavaString(env,
frm()->GetUser().GetPhoneAuthUrl(jni::ToNativeString(env, redirectUrl)));
}
JNIEXPORT void JNICALL
Java_com_mapswithme_maps_Framework_nativeShowFeatureByLatLon(JNIEnv * env, jclass,
jdouble lat, jdouble lon)

View file

@ -18,16 +18,16 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/auth_dialog_padding_top"
android:layout_marginTop="@dimen/margin_half_plus_eight"
android:textAppearance="@style/MwmTextAppearance.Body3"
android:text="Easy sign in without login and password in a couple of seconds."
/>
<com.facebook.login.widget.LoginButton
xmlns:fb="http://schemas.android.com/apk/res-auto"
android:id="@+id/loging_button"
android:id="@+id/facebook_button"
android:layout_width="match_parent"
android:layout_height="@dimen/auth_dialog_facebook_btn_height"
android:layout_marginTop="@dimen/auth_dialog_padding_top"
android:layout_height="@dimen/height_primary_button"
android:layout_marginTop="@dimen/margin_base"
android:textSize="@dimen/text_size_body_3"
fb:com_facebook_login_text="@string/facebook"
android:paddingStart="@dimen/margin_base"
@ -37,4 +37,14 @@
android:paddingTop="@dimen/margin_half_plus"
android:paddingBottom="@dimen/margin_half_plus"
android:layout_gravity="center_horizontal"/>
<TextView
android:id="@+id/phone_button"
android:layout_width="match_parent"
android:layout_height="@dimen/height_primary_button"
android:layout_marginTop="@dimen/margin_base"
android:textAppearance="@style/MwmTextAppearance.Button"
android:textColor="?accentButtonTextColor"
android:background="?accentButtonBackground"
android:gravity="center"
android:text="@string/phone_number"/>
</LinearLayout>

View file

@ -227,8 +227,8 @@
<dimen name="rating_user_review_min_height">152dp</dimen>
<!-- Authorization-->
<dimen name="auth_dialog_padding_top">20dp</dimen>
<dimen name="auth_dialog_padding_bottom">28dp</dimen>
<dimen name="auth_dialog_padding_top">28dp</dimen>
<dimen name="auth_dialog_padding_bottom">24dp</dimen>
<dimen name="auth_dialog_facebook_btn_height">40dp</dimen>
<dimen name="divider_height">1dp</dimen>

View file

@ -410,6 +410,7 @@ public class Framework
@AuthTokenType int socialTokenType,
@NonNull AuthorizationListener listener);
public static native boolean nativeIsUserAuthenticated();
public static native String nativeGetPhoneAuthUrl(@NonNull String redirectUrl);
public static native void nativeShowFeatureByLatLon(double lat, double lon);

View file

@ -6,7 +6,9 @@ import java.util.List;
class Constants
{
static final int REQ_CODE_GET_SOCIAL_TOKEN = 101;
static final int REQ_CODE_PHONE_AUTH_RESULT = 102;
static final String EXTRA_SOCIAL_TOKEN = "extra_social_token";
static final String EXTRA_PHONE_AUTH_TOKEN = "extra_phone_auth_token";
static final String EXTRA_TOKEN_TYPE = "extra_token_type";
static final String EXTRA_AUTH_ERROR = "extra_auth_error";
static final String EXTRA_IS_CANCEL = "extra_is_cancel";

View file

@ -0,0 +1,39 @@
package com.mapswithme.maps.auth;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import com.mapswithme.maps.R;
import com.mapswithme.maps.base.BaseMwmExtraTitleActivity;
import com.mapswithme.maps.base.OnBackPressListener;
public class PhoneAuthActivity extends BaseMwmExtraTitleActivity
{
public static void start(@NonNull Fragment fragment)
{
final Intent i = new Intent(fragment.getContext(), PhoneAuthActivity.class);
i.putExtra(EXTRA_TITLE, fragment.getString(R.string.authorization_button_sign_in));
fragment.startActivityForResult(i, Constants.REQ_CODE_PHONE_AUTH_RESULT);
}
@Override
public void onBackPressed()
{
FragmentManager manager = getSupportFragmentManager();
Fragment fragment = manager.findFragmentByTag(PhoneAuthFragment.class.getName());
if (fragment == null)
return;
if (!((OnBackPressListener) fragment).onBackPressed())
super.onBackPressed();
}
@Override
protected Class<? extends Fragment> getFragmentClass()
{
return PhoneAuthFragment.class;
}
}

View file

@ -0,0 +1,92 @@
package com.mapswithme.maps.auth;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import com.mapswithme.maps.Framework;
import com.mapswithme.maps.R;
import com.mapswithme.maps.base.BaseMwmFragment;
import com.mapswithme.maps.base.OnBackPressListener;
import com.mapswithme.util.UiUtils;
public class PhoneAuthFragment extends BaseMwmFragment implements OnBackPressListener
{
private static final String REDIRECT_URL = "https://localhost/";
@SuppressWarnings("NullableProblems")
@NonNull
private WebView mWebView;
@SuppressWarnings("NullableProblems")
@NonNull
private View mProgress;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment_web_view_with_progress, container, false);
}
@SuppressLint("SetJavaScriptEnabled")
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
if (savedInstanceState != null)
return;
mWebView = view.findViewById(R.id.webview);
mProgress = view.findViewById(R.id.progress);
mWebView.setWebViewClient(new WebViewClient()
{
@Override
public void onPageFinished(WebView view, String url)
{
UiUtils.show(mWebView);
UiUtils.hide(mProgress);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
if (url.contains(REDIRECT_URL + "?code="))
{
Intent returnIntent = new Intent();
returnIntent.putExtra(Constants.EXTRA_PHONE_AUTH_TOKEN,
url.substring((REDIRECT_URL + "?code=").length()));
getActivity().setResult(Activity.RESULT_OK, returnIntent);
getActivity().finish();
return true;
}
return super.shouldOverrideUrlLoading(view, url);
}
});
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.loadUrl(Framework.nativeGetPhoneAuthUrl(REDIRECT_URL));
}
@Override
public boolean onBackPressed()
{
if (!mWebView.canGoBack())
return false;
mWebView.goBack();
return true;
}
}

View file

@ -35,7 +35,16 @@ public class SocialAuthDialogFragment extends BaseMwmDialogFragment
private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.MISC);
private static final String TAG = SocialAuthDialogFragment.class.getSimpleName();
@NonNull
private final CallbackManager mCallbackManager = CallbackManager.Factory.create();
private final CallbackManager mFacebookCallbackManager = CallbackManager.Factory.create();
@Nullable
private String mPhoneAuthToken;
@NonNull
private final View.OnClickListener mPhoneClickListener = (View v) ->
{
PhoneAuthActivity.start(this);
};
@NonNull
@Override
@ -48,13 +57,17 @@ public class SocialAuthDialogFragment extends BaseMwmDialogFragment
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_auth_passport_dialog, container, false);
LoginButton button = view.findViewById(R.id.loging_button);
button.setReadPermissions(Constants.FACEBOOK_PERMISSIONS);
button.setFragment(this);
button.registerCallback(mCallbackManager, new FBCallback(this));
LoginButton facebookButton = view.findViewById(R.id.facebook_button);
facebookButton.setReadPermissions(Constants.FACEBOOK_PERMISSIONS);
facebookButton.setFragment(this);
facebookButton.registerCallback(mFacebookCallbackManager, new FBCallback(this));
View phoneButton = view.findViewById(R.id.phone_button);
phoneButton.setOnClickListener(mPhoneClickListener);
return view;
}
@ -62,10 +75,10 @@ public class SocialAuthDialogFragment extends BaseMwmDialogFragment
public void onResume()
{
super.onResume();
AccessToken token = AccessToken.getCurrentAccessToken();
AccessToken facebookToken = AccessToken.getCurrentAccessToken();
String tokenValue = null;
if (token != null)
tokenValue = token.getToken();
if (facebookToken != null)
tokenValue = facebookToken.getToken();
if (TextUtils.isEmpty(tokenValue))
{
@ -97,17 +110,32 @@ public class SocialAuthDialogFragment extends BaseMwmDialogFragment
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
mCallbackManager.onActivityResult(requestCode, resultCode, data);
if (data != null && requestCode == Constants.REQ_CODE_PHONE_AUTH_RESULT)
{
mPhoneAuthToken = data.getStringExtra(Constants.EXTRA_PHONE_AUTH_TOKEN);
dismiss();
}
mFacebookCallbackManager.onActivityResult(requestCode, resultCode, data);
}
@Override
public void onDismiss(DialogInterface dialog)
{
AccessToken token = AccessToken.getCurrentAccessToken();
int resultCode = token == null || TextUtils.isEmpty(token.getToken()) ? Activity.RESULT_CANCELED
: Activity.RESULT_OK;
sendResult(resultCode, token != null ? token.getToken() : null,
Framework.SOCIAL_TOKEN_FACEBOOK, null, true);
String token = mPhoneAuthToken;
@Framework.AuthTokenType
int tokenType = token != null ? Framework.SOCIAL_TOKEN_PHONE : Framework.SOCIAL_TOKEN_FACEBOOK;
if (token == null)
{
AccessToken facebookToken = AccessToken.getCurrentAccessToken();
token = facebookToken != null ? facebookToken.getToken() : null;
}
int resultCode = TextUtils.isEmpty(token) ? Activity.RESULT_CANCELED : Activity.RESULT_OK;
sendResult(resultCode, token, tokenType, null, true);
super.onDismiss(dialog);
}

View file

@ -19,7 +19,7 @@ public class CopyrightFragment extends BaseSettingsFragment
@Override
protected int getLayoutRes()
{
return R.layout.fragment_prefs_copyright;
return R.layout.fragment_web_view_with_progress;
}
@Override

View file

@ -7,6 +7,8 @@
#include "coding/url_encode.hpp"
#include "coding/writer.hpp"
#include "platform/preferred_languages.hpp"
#include "base/logging.hpp"
#include "base/stl_helpers.hpp"
#include "base/string_utils.hpp"
@ -398,6 +400,17 @@ void User::UploadUserReviews(std::string && dataStr, size_t numberOfUnsynchroniz
});
}
// static
std::string User::GetPhoneAuthUrl(std::string const & redirectUri)
{
std::ostringstream os;
os << kPassportServerUrl << "/oauth/authorize/?mode=phone_device&response_type=code"
<< "&locale=" << languages::GetCurrentNorm() << "&redirect_uri=" << UrlEncode(redirectUri)
<< "&client_id=" << kAppName;
return os.str();
}
void User::Request(std::string const & url, BuildRequestHandler const & onBuildRequest,
SuccessHandler const & onSuccess, ErrorHandler const & onError)
{

View file

@ -64,6 +64,8 @@ public:
void UploadUserReviews(std::string && dataStr, size_t numberOfUnsynchronized,
CompleteUploadingHandler const & onCompleteUploading);
static std::string GetPhoneAuthUrl(std::string const & redirectUri);
private:
void Init();
void SetAccessToken(std::string const & accessToken);