Unverified Commit f9d6c822 authored by Lucio Maciel's avatar Lucio Maciel Committed by GitHub

Merge pull request #969 from RocketChat/new/login-with-google

[NEW] Login with Google (OAuth).
parents a62ab7fe 35b4b62b
...@@ -29,6 +29,7 @@ private const val TYPE_LOGIN_USER_EMAIL = 0 ...@@ -29,6 +29,7 @@ private const val TYPE_LOGIN_USER_EMAIL = 0
private const val TYPE_LOGIN_CAS = 1 private const val TYPE_LOGIN_CAS = 1
private const val TYPE_LOGIN_OAUTH = 2 private const val TYPE_LOGIN_OAUTH = 2
private const val SERVICE_NAME_GITHUB = "github" private const val SERVICE_NAME_GITHUB = "github"
private const val SERVICE_NAME_GOOGLE = "google"
private const val SERVICE_NAME_GILAB = "gitlab" private const val SERVICE_NAME_GILAB = "gitlab"
class LoginPresenter @Inject constructor(private val view: LoginView, class LoginPresenter @Inject constructor(private val view: LoginView,
...@@ -133,9 +134,13 @@ class LoginPresenter @Inject constructor(private val view: LoginView, ...@@ -133,9 +134,13 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
} }
} }
if (settings.isGoogleAuthenticationEnabled()) { if (settings.isGoogleAuthenticationEnabled()) {
val clientId = getOauthClientId(services, SERVICE_NAME_GOOGLE)
if (clientId != null) {
view.setupGoogleButtonListener(UrlHelper.getGoogleOauthUrl(clientId, currentServer, state), state)
view.enableLoginByGoogle() view.enableLoginByGoogle()
totalSocialAccountsEnabled++ totalSocialAccountsEnabled++
} }
}
if (settings.isLinkedinAuthenticationEnabled()) { if (settings.isLinkedinAuthenticationEnabled()) {
view.enableLoginByLinkedin() view.enableLoginByLinkedin()
totalSocialAccountsEnabled++ totalSocialAccountsEnabled++
......
...@@ -117,9 +117,19 @@ interface LoginView : LoadingView, MessageView, InternetView { ...@@ -117,9 +117,19 @@ interface LoginView : LoadingView, MessageView, InternetView {
/** /**
* Shows the "login by Google" view if it is enable by the server settings. * Shows the "login by Google" view if it is enable by the server settings.
*
* REMARK: We must set up the Google button listener before enabling it [setupGoogleButtonListener].
*/ */
fun enableLoginByGoogle() fun enableLoginByGoogle()
/**
* Setups the Google button when tapped.
*
* @param googleUrl The Google OAuth URL to authenticate with.
* @param state A random string generated by the app, which you'll verify later (to protect against forgery attacks).
*/
fun setupGoogleButtonListener(googleUrl: String, state: String)
/** /**
* Shows the "login by Linkedin" view if it is enable by the server settings. * Shows the "login by Linkedin" view if it is enable by the server settings.
*/ */
......
...@@ -219,6 +219,14 @@ class LoginFragment : Fragment(), LoginView { ...@@ -219,6 +219,14 @@ class LoginFragment : Fragment(), LoginView {
button_google.isClickable = true button_google.isClickable = true
} }
// TODO: Use custom tabs instead of web view. See https://github.com/RocketChat/Rocket.Chat.Android/issues/968
override fun setupGoogleButtonListener(googleUrl: String, state: String) {
button_google.setOnClickListener {
startActivityForResult(context?.oauthWebViewIntent(googleUrl, state), REQUEST_CODE_FOR_OAUTH)
activity?.overridePendingTransition(R.anim.slide_up, R.anim.hold)
}
}
override fun enableLoginByLinkedin() { override fun enableLoginByLinkedin() {
button_linkedin.isClickable = true button_linkedin.isClickable = true
} }
......
...@@ -42,9 +42,20 @@ object UrlHelper { ...@@ -42,9 +42,20 @@ object UrlHelper {
* @param state An unguessable random string used to protect against forgery attacks. * @param state An unguessable random string used to protect against forgery attacks.
* @return The Github Oauth URL. * @return The Github Oauth URL.
*/ */
// TODO: Fix github url.
fun getGithubOauthUrl(clientId: String, state: String): String = fun getGithubOauthUrl(clientId: String, state: String): String =
"https://github.com/login/oauth/authorize?scope=user:email&client_id=$clientId&state=$state" "https://github.com/login/oauth/authorize?scope=user:email&client_id=$clientId&state=$state"
/**
* Returns the Google Oauth URL.
*
* @param clientId The Google client ID.
* @param serverUrl The server URL.
* @param state An unguessable random string used to protect against forgery attacks.
* @return The Google Oauth URL.
*/
fun getGoogleOauthUrl(clientId: String, serverUrl: String, state: String) =
"https://accounts.google.com/o/oauth2/v2/auth?client_id=$clientId&redirect_uri=${removeTrailingSlash(serverUrl)}/_oauth/google?close&response_type=code&state=$state&scope=email%20profile"
/** /**
* Returns the Gitlab Oauth URL. * Returns the Gitlab Oauth URL.
* *
......
...@@ -34,6 +34,8 @@ const val INTENT_OAUTH_CREDENTIAL_SECRET = "credential_secret" ...@@ -34,6 +34,8 @@ const val INTENT_OAUTH_CREDENTIAL_SECRET = "credential_secret"
class OauthWebViewActivity : AppCompatActivity() { class OauthWebViewActivity : AppCompatActivity() {
private lateinit var webPageUrl: String private lateinit var webPageUrl: String
private lateinit var state: String private lateinit var state: String
private var isWebViewSetUp: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
...@@ -50,7 +52,10 @@ class OauthWebViewActivity : AppCompatActivity() { ...@@ -50,7 +52,10 @@ class OauthWebViewActivity : AppCompatActivity() {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
if (!isWebViewSetUp) {
setupWebView() setupWebView()
isWebViewSetUp = true
}
} }
override fun onBackPressed() { override fun onBackPressed() {
...@@ -62,14 +67,20 @@ class OauthWebViewActivity : AppCompatActivity() { ...@@ -62,14 +67,20 @@ class OauthWebViewActivity : AppCompatActivity() {
} }
private fun setupToolbar() { private fun setupToolbar() {
toolbar.title = getString(R.string.title_authentication) with(toolbar) {
toolbar.setNavigationIcon(R.drawable.ic_close_white_24dp) title = getString(R.string.title_authentication)
toolbar.setNavigationOnClickListener { closeView() } setNavigationIcon(R.drawable.ic_close_white_24dp)
setNavigationOnClickListener { closeView() }
}
} }
@SuppressLint("SetJavaScriptEnabled") @SuppressLint("SetJavaScriptEnabled")
private fun setupWebView() { private fun setupWebView() {
web_view.settings.javaScriptEnabled = true with(web_view.settings) {
javaScriptEnabled = true
// TODO This is required to make Google OAuth work, but we shoud use Custom Tabs instead. See https://github.com/RocketChat/Rocket.Chat.Android/issues/968
userAgentString = "Mozilla/5.0 (Linux; Android 4.1.1; Galaxy Nexus Build/JRO03C) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19"
}
web_view.webViewClient = object : WebViewClient() { web_view.webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView, url: String) { override fun onPageFinished(view: WebView, url: String) {
if (url.contains(JSON_CREDENTIAL_TOKEN) && url.contains(JSON_CREDENTIAL_SECRET)) { if (url.contains(JSON_CREDENTIAL_TOKEN) && url.contains(JSON_CREDENTIAL_SECRET)) {
......
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