Commit bbf420a5 authored by Jérome Perrin's avatar Jérome Perrin

Google login in ERP5JS

Change login button to comply with Google's branding guidelines.

Add support for google login in ERP5JS.


See merge request nexedi/erp5!1166
parents b1da02b9 64c0bb5d
......@@ -36,6 +36,7 @@ elif code is not None:
method = getattr(context, "ERP5Site_createGoogleUserToOAuth", None)
if method is not None:
method(user_reference, user_dict)
return response.redirect(request.get("came_from") or context.absolute_url())
# XXX for ERP5JS web sites without a rewrite rule, we make sure there's a trailing /
return response.redirect(request.get("came_from") or context.absolute_url() + '/')
return handleError('')
......@@ -27,6 +27,9 @@
import uuid
import mock
import lxml
import urlparse
import httplib
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5Type.tests.utils import createZODBPythonScript
......@@ -89,8 +92,7 @@ def getUserEntry(access_token):
}
class TestGoogleLogin(ERP5TypeTestCase):
class GoogleLoginTestCase(ERP5TypeTestCase):
def afterSetUp(self):
"""
This is ran before anything, used to set the environment
......@@ -123,6 +125,8 @@ class TestGoogleLogin(ERP5TypeTestCase):
self.tic()
self.logout()
class TestGoogleLogin(GoogleLoginTestCase):
def test_redirect(self):
"""
Check URL generate to redirect to Google
......@@ -279,7 +283,9 @@ return credential_request
google_hash = self.portal.REQUEST.RESPONSE.cookies.get("__ac_google_hash")["value"]
self.assertEqual("b01533abb684a658dc71c81da4e67546", google_hash)
self.assertEqual(self.portal.absolute_url(), response)
absolute_url = self.portal.absolute_url()
self.assertNotEqual(absolute_url[-1], '/')
self.assertEqual(absolute_url + '/', response)
cache_dict = self.portal.Base_getBearerToken(google_hash, "google_server_auth_token_cache_factory")
self.assertEqual(CLIENT_ID, cache_dict["client_id"])
self.assertEqual(ACCESS_TOKEN, cache_dict["access_token"])
......@@ -300,3 +306,30 @@ return credential_request
person = credential_request.getDestinationDecisionValue()
google_login = person.objectValues(portal_types="Google Login")[0]
self.assertEqual(getUserId(None), google_login.getReference())
def test_logout(self):
resp = self.publish(self.portal.getId() + '/logout')
self.assertEqual(resp.getCookie("__ac_google_hash")['value'], 'deleted')
class TestERP5JSGoogleLogin(GoogleLoginTestCase):
def _getWebSite(self):
return self.portal.web_site_module.renderjs_runner
def test_login_form(self):
resp = self.publish(self._getWebSite().getPath() + '/login_form')
tree = lxml.etree.fromstring(resp.getBody(), parser=lxml.etree.HTMLParser())
google_login_link, = [
img.getparent().attrib['href']
for img in tree.findall('.//a/img')
if img.attrib['alt'] == 'Sign in with Google'
]
self.assertIn('/ERP5Site_redirectToGoogleLoginPage', google_login_link)
resp = self.publish(urlparse.urlparse(google_login_link).path)
# this request redirects to google
self.assertEqual(resp.getStatus(), httplib.FOUND)
self.assertIn('google.com', resp.getHeader('Location'))
def test_logout(self):
resp = self.publish(self._getWebSite().getPath() + '/WebSite_logout')
self.assertEqual(resp.getCookie("__ac_google_hash")['value'], 'deleted')
erp5_full_text_myisam_catalog
erp5_credential
\ No newline at end of file
erp5_credential
erp5_web_renderjs_ui
\ No newline at end of file
......@@ -1045,6 +1045,19 @@ div[data-gadget-scope='header'] .ui-header ul {
.gadget-content button[name='action_update']:active {
background-color: #a9a9a9;
}
.gadget-content .sign_in_with_google {
height: 46px;
width: 191px;
display: inline-block;
overflow: hidden;
margin-top: 6pt;
}
.gadget-content .sign_in_with_google img:hover {
margin-top: -46px;
}
.gadget-content .sign_in_with_google img:active {
margin-top: -92px;
}
@media not screen and (max-width: 85em) {
div[data-role='page']:not(.desktop-panel-hidden) .gadget-content {
margin-left: 180pt;
......
......@@ -262,8 +262,8 @@
</tuple>
<state>
<tuple>
<float>1579787106.93</float>
<string>UTC</string>
<float>1593579172.65</float>
<string>GMT+2</string>
</tuple>
</state>
</object>
......
"""
Default logout handler, overwritten to give website specific portal status message.
"""
portal = context.getPortalObject()
REQUEST = context.REQUEST
if REQUEST.has_key('portal_skin'):
context.portal_skins.clearSkinCookie()
portal.portal_skins.clearSkinCookie()
REQUEST.RESPONSE.expireCookie('__ac', path='/')
if getattr(portal.portal_skins, "erp5_oauth_google_login", None):
REQUEST.RESPONSE.expireCookie('__ac_google_hash', path='/')
if getattr(portal.portal_skins, "erp5_oauth_facebook_login", None):
REQUEST.RESPONSE.expireCookie('__ac_facebook_hash', path='/')
REQUEST.RESPONSE.setHeader('Location', came_from or context.getPermanentURL(context))
REQUEST.RESPONSE.setStatus(303)
# REQUEST.RESPONSE.redirect(came_from or context.getPermanentURL(context));
......@@ -1200,6 +1200,20 @@ div[data-gadget-scope='header'] .ui-header {
.renderPageSubmitButton(@grey);
}
.sign_in_with_google {
height: 46px;
width: 191px;
display: inline-block;
overflow: hidden;
margin-top: @margin-size;
}
.sign_in_with_google img:hover {
margin-top: -46px;
}
.sign_in_with_google img:active {
margin-top: -92px;
}
@media @desktop {
div[data-role='page']:not(.desktop-panel-hidden) & {
// Keep the panel always visible
......
......@@ -423,6 +423,22 @@ fieldset.bottom > .field > label {
border-width: 0;
}
.login a.google {
height: 46px;
width: 191px;
display: inline-block;
overflow: hidden;
}
.login a.google img:hover {
margin-top: -46px;
}
.login a.google img:active {
margin-top: -92px;
}
.content .field {
padding-bottom: 3px;
}
......
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