Commit 88174b75 authored by Yusuke Iwaki's avatar Yusuke Iwaki

FIX #68 add Google Login feature. refactor logic to show/hide OAuth Provider button.

parent d9217310
...@@ -15,7 +15,7 @@ import org.json.JSONException; ...@@ -15,7 +15,7 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import timber.log.Timber; import timber.log.Timber;
abstract class AbstractOAuthFragment extends AbstractWebViewFragment { public abstract class AbstractOAuthFragment extends AbstractWebViewFragment {
protected String serverConfigId; protected String serverConfigId;
protected String hostname; protected String hostname;
......
package chat.rocket.android.fragment.oauth; package chat.rocket.android.fragment.oauth;
import android.os.Bundle;
import android.util.Base64; import android.util.Base64;
import chat.rocket.android.model.ddp.MeteorLoginServiceConfiguration; import chat.rocket.android.model.ddp.MeteorLoginServiceConfiguration;
import java.nio.charset.Charset; import java.nio.charset.Charset;
...@@ -10,17 +9,6 @@ import timber.log.Timber; ...@@ -10,17 +9,6 @@ import timber.log.Timber;
public class GitHubOAuthFragment extends AbstractOAuthFragment { public class GitHubOAuthFragment extends AbstractOAuthFragment {
/**
* create new Fragment with ServerConfig-ID.
*/
public static GitHubOAuthFragment create(final String serverConfigId) {
Bundle args = new Bundle();
args.putString("serverConfigId", serverConfigId);
GitHubOAuthFragment fragment = new GitHubOAuthFragment();
fragment.setArguments(args);
return fragment;
}
@Override protected String getOAuthServiceName() { @Override protected String getOAuthServiceName() {
return "github"; return "github";
} }
......
package chat.rocket.android.fragment.oauth;
import android.util.Base64;
import chat.rocket.android.model.ddp.MeteorLoginServiceConfiguration;
import java.nio.charset.Charset;
import okhttp3.HttpUrl;
import org.json.JSONObject;
import timber.log.Timber;
public class GoogleOAuthFragment extends AbstractOAuthFragment {
@Override protected String getOAuthServiceName() {
return "google";
}
@Override protected String generateURL(MeteorLoginServiceConfiguration oauthConfig) {
final String clientId = oauthConfig.getClientId();
try {
String state = Base64.encodeToString(new JSONObject().put("loginStyle", "popup")
.put("credentialToken", "google" + System.currentTimeMillis())
.put("isCordova", true)
.toString()
.getBytes(Charset.forName("UTF-8")), Base64.NO_WRAP);
return new HttpUrl.Builder().scheme("https")
.host("accounts.google.com")
.addPathSegment("o")
.addPathSegment("oauth2")
.addPathSegment("auth")
.addQueryParameter("response_type", "code")
.addQueryParameter("client_id", clientId)
.addQueryParameter("scope", "profile email")
.addQueryParameter("redirect_uri", "https://" + hostname + "/_oauth/google?close")
.addQueryParameter("state", state)
.build()
.toString();
} catch (Exception exception) {
Timber.e(exception, "failed to generate Google OAUth URL");
}
return null;
}
}
package chat.rocket.android.fragment.oauth; package chat.rocket.android.fragment.oauth;
import android.os.Bundle;
import android.util.Base64; import android.util.Base64;
import chat.rocket.android.model.ddp.MeteorLoginServiceConfiguration; import chat.rocket.android.model.ddp.MeteorLoginServiceConfiguration;
import java.nio.charset.Charset; import java.nio.charset.Charset;
...@@ -9,17 +8,6 @@ import timber.log.Timber; ...@@ -9,17 +8,6 @@ import timber.log.Timber;
public class TwitterOAuthFragment extends AbstractOAuthFragment { public class TwitterOAuthFragment extends AbstractOAuthFragment {
/**
* create new Fragment with ServerConfig-ID.
*/
public static TwitterOAuthFragment create(final String serverConfigId) {
Bundle args = new Bundle();
args.putString("serverConfigId", serverConfigId);
TwitterOAuthFragment fragment = new TwitterOAuthFragment();
fragment.setArguments(args);
return fragment;
}
@Override protected String getOAuthServiceName() { @Override protected String getOAuthServiceName() {
return "twitter"; return "twitter";
} }
......
...@@ -3,17 +3,19 @@ package chat.rocket.android.fragment.server_config; ...@@ -3,17 +3,19 @@ package chat.rocket.android.fragment.server_config;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar; import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;
import chat.rocket.android.R; import chat.rocket.android.R;
import chat.rocket.android.fragment.oauth.GitHubOAuthFragment;
import chat.rocket.android.api.MethodCallHelper; import chat.rocket.android.api.MethodCallHelper;
import chat.rocket.android.fragment.oauth.TwitterOAuthFragment;
import chat.rocket.android.helper.TextUtils; import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.layouthelper.oauth.OAuthProviderInfo;
import chat.rocket.android.model.ddp.MeteorLoginServiceConfiguration; import chat.rocket.android.model.ddp.MeteorLoginServiceConfiguration;
import chat.rocket.android.realm_helper.RealmListObserver; import chat.rocket.android.realm_helper.RealmListObserver;
import chat.rocket.android.realm_helper.RealmStore; import chat.rocket.android.realm_helper.RealmStore;
import java.util.HashMap;
import java.util.List; import java.util.List;
import timber.log.Timber;
/** /**
* Login screen. * Login screen.
...@@ -68,30 +70,42 @@ public class LoginFragment extends AbstractServerConfigFragment { ...@@ -68,30 +70,42 @@ public class LoginFragment extends AbstractServerConfigFragment {
} }
private void onRenderAuthProviders(List<MeteorLoginServiceConfiguration> authProviders) { private void onRenderAuthProviders(List<MeteorLoginServiceConfiguration> authProviders) {
final View btnTwitter = rootView.findViewById(R.id.btn_login_with_twitter); HashMap<String, View> viewMap = new HashMap<>();
final View btnGitHub = rootView.findViewById(R.id.btn_login_with_github); HashMap<String, Boolean> supportedMap = new HashMap<>();
for (OAuthProviderInfo info : OAuthProviderInfo.LIST) {
viewMap.put(info.serviceName, rootView.findViewById(info.buttonId));
supportedMap.put(info.serviceName, false);
}
boolean hasTwitter = false;
boolean hasGitHub = false;
for (MeteorLoginServiceConfiguration authProvider : authProviders) { for (MeteorLoginServiceConfiguration authProvider : authProviders) {
if (!hasTwitter for (OAuthProviderInfo info : OAuthProviderInfo.LIST) {
&& "twitter".equals(authProvider.getService())) { if (!supportedMap.get(info.serviceName)
hasTwitter = true; && info.serviceName.equals(authProvider.getService())) {
btnTwitter.setOnClickListener(view -> { supportedMap.put(info.serviceName, true);
showFragmentWithBackStack(TwitterOAuthFragment.create(serverConfigId)); viewMap.get(info.serviceName).setOnClickListener(view -> {
}); Fragment fragment = null;
} try {
if (!hasGitHub fragment = info.fragmentClass.newInstance();
&& "github".equals(authProvider.getService())) { } catch (java.lang.InstantiationException | IllegalAccessException exception) {
hasGitHub = true; Timber.w(exception, "failed to create new Fragment");
btnGitHub.setOnClickListener(view -> { }
showFragmentWithBackStack(GitHubOAuthFragment.create(serverConfigId)); if (fragment != null) {
}); Bundle args = new Bundle();
args.putString("serverConfigId", serverConfigId);
fragment.setArguments(args);
showFragmentWithBackStack(fragment);
}
});
viewMap.get(info.serviceName).setVisibility(View.VISIBLE);
}
} }
} }
btnTwitter.setVisibility(hasTwitter ? View.VISIBLE : View.GONE); for (OAuthProviderInfo info : OAuthProviderInfo.LIST) {
btnGitHub.setVisibility(hasGitHub ? View.VISIBLE : View.GONE); if (!supportedMap.get(info.serviceName)) {
viewMap.get(info.serviceName).setVisibility(View.GONE);
}
}
} }
@Override public void onResume() { @Override public void onResume() {
......
package chat.rocket.android.layouthelper.oauth;
import chat.rocket.android.R;
import chat.rocket.android.fragment.oauth.AbstractOAuthFragment;
import chat.rocket.android.fragment.oauth.GitHubOAuthFragment;
import chat.rocket.android.fragment.oauth.GoogleOAuthFragment;
import chat.rocket.android.fragment.oauth.TwitterOAuthFragment;
import java.util.ArrayList;
public class OAuthProviderInfo {
public String serviceName;
public int buttonId;
public Class<? extends AbstractOAuthFragment> fragmentClass;
public OAuthProviderInfo(String serviceName, int buttonId,
Class<? extends AbstractOAuthFragment> fragmentClass) {
this.serviceName = serviceName;
this.buttonId = buttonId;
this.fragmentClass = fragmentClass;
}
public static ArrayList<OAuthProviderInfo> LIST = new ArrayList<OAuthProviderInfo>() {
{
add(new OAuthProviderInfo(
"twitter", R.id.btn_login_with_twitter, TwitterOAuthFragment.class));
add(new OAuthProviderInfo(
"github", R.id.btn_login_with_github, GitHubOAuthFragment.class));
add(new OAuthProviderInfo(
"google", R.id.btn_login_with_google, GoogleOAuthFragment.class));
}
};
}
...@@ -27,6 +27,15 @@ ...@@ -27,6 +27,15 @@
android:text="@string/fa_twitter" android:text="@string/fa_twitter"
android:textSize="16dp" /> android:textSize="16dp" />
<chat.rocket.android.widget.FontAwesomeButton
android:id="@+id/btn_login_with_facebook"
android:layout_width="48dp"
android:layout_height="48dp"
android:enabled="false"
android:layout_marginEnd="@dimen/margin_8"
android:text="@string/fa_facebook_official"
android:textSize="16dp" />
<chat.rocket.android.widget.FontAwesomeButton <chat.rocket.android.widget.FontAwesomeButton
android:id="@+id/btn_login_with_github" android:id="@+id/btn_login_with_github"
android:layout_width="48dp" android:layout_width="48dp"
...@@ -34,6 +43,15 @@ ...@@ -34,6 +43,15 @@
android:layout_marginEnd="@dimen/margin_8" android:layout_marginEnd="@dimen/margin_8"
android:text="@string/fa_github" android:text="@string/fa_github"
android:textSize="16dp" /> android:textSize="16dp" />
<chat.rocket.android.widget.FontAwesomeButton
android:id="@+id/btn_login_with_google"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginEnd="@dimen/margin_8"
android:text="@string/fa_google"
android:textSize="16dp" />
</LinearLayout> </LinearLayout>
<android.support.design.widget.TextInputLayout <android.support.design.widget.TextInputLayout
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
<string name="fa_chevron_down" translatable="false">&#xf078;</string> <string name="fa_chevron_down" translatable="false">&#xf078;</string>
<string name="fa_twitter" translatable="false">&#xf099;</string> <string name="fa_twitter" translatable="false">&#xf099;</string>
<string name="fa_github" translatable="false">&#xf09b;</string> <string name="fa_github" translatable="false">&#xf09b;</string>
<string name="fa_google" translatable="false">&#xf1a0;</string>
<string name="fa_facebook_official" translatable="false">&#xf230;</string>
<string name="fa_plus" translatable="false">&#xf067;</string> <string name="fa_plus" translatable="false">&#xf067;</string>
<string name="fa_sign_out" translatable="false">&#xf08b;</string> <string name="fa_sign_out" translatable="false">&#xf08b;</string>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment