[gen] Added Config.discreetLogin allowing to put a discreet link on the main page for logging in, instead of the login form in the central strip, for sites where logged users do not represent the majority of visitors (only some admins).

This commit is contained in:
Gaetan Delannay 2013-05-10 12:16:57 +02:00
parent 8a0ee2c131
commit 820d3ef241
11 changed files with 94 additions and 86 deletions

View file

@ -38,4 +38,5 @@ class Object:
return res.encode('utf-8')
def __nonzero__(self):
return bool(self.__dict__)
def get(self, name, default=None): return getattr(self, name, default)
# ------------------------------------------------------------------------------

View file

@ -3013,6 +3013,10 @@ class Config:
self.activateForgotPassword = True
# Enable session timeout?
self.enableSessionTimeout = False
# If the following field is True, the login/password widget will be
# discreet. This is for sites where authentication is not foreseen for
# the majority of visitors (just for some administrators).
self.discreetLogin = False
# When using Ogone, place an instance of appy.gen.ogone.OgoneConfig in
# the field below.
self.ogone = None

View file

@ -604,6 +604,7 @@ class ZopeGenerator(Generator):
repls['languageSelector'] = self.config.languageSelector
repls['sourceLanguage'] = self.config.sourceLanguage
repls['enableSessionTimeout'] = self.config.enableSessionTimeout
repls['discreetLogin'] = self.config.discreetLogin
repls['ogone'] = repr(self.config.ogone)
repls['googleAnalyticsId'] = repr(self.config.googleAnalyticsId)
repls['activateForgotPassword'] = self.config.activateForgotPassword

View file

@ -89,9 +89,13 @@ class ToolMixin(BaseMixin):
'inline;filename="%s"' % res.name)
return res.content
def getAttr(self, name):
def getAttr(self, name, source='appy'):
'''Gets attribute named p_name.'''
return getattr(self.appy(), name, None)
if source == 'config':
obj = self.getProductConfig()
else:
obj = self.appy()
return getattr(obj, name, None)
def getAppName(self):
'''Returns the name of the application.'''

View file

@ -49,6 +49,7 @@ languageSelector = <!languageSelector!>
sourceLanguage = '<!sourceLanguage!>'
activateForgotPassword = <!activateForgotPassword!>
enableSessionTimeout = <!enableSessionTimeout!>
discreetLogin = <!discreetLogin!>
ogone = <!ogone!>
googleAnalyticsId = <!googleAnalyticsId!>

View file

@ -55,15 +55,15 @@ img { border: 0; vertical-align: middle }
border-style: solid; border-width: 1px; border-color: grey }
.top { height: 89px; margin-left: 3em; vertical-align: top }
.lang { margin-right: 6px }
.userStrip { background-color: #6282B3; height: 35px;
border-top: 3px solid #034984; border-bottom: 2px solid #034984 }
.userStrip { background-color: #6282B3; border-top: 3px solid #034984;
border-bottom: 2px solid #034984 }
.userStripText { padding: 0 0.3em 0 0.3em; color: white }
.userStrip a { color: #e7e7e7 }
.userStrip a:visited { color: #e7e7e7 }
.navigate { border-bottom: 1px solid #5F7983;
background-color: #dbdde1; font-weight: bold }
.navigate td { padding: 4px 9px }
.login { margin-top: 2px; margin-bottom: 2px; color: black }
.login { margin: 3px; color: black }
.buttons { margin-left: 4px }
.fakeButton { border: 1px solid #D7DEE4; background-color: #fde8e0;
padding: 0px 8px 2px;
@ -79,7 +79,7 @@ img { border: 0; vertical-align: middle }
.discreet { font-size: 90%; color: grey }
.title { color: #BA9440 }
.breadcrumb { color: #BA9440; font-size: 13px }
.lostPassword a { font-size: 90%; color: white; padding-left: 1em }
.lostPassword { font-size: 90%; color: white; padding-left: 1em }
.portlet { width: 150px; border-right: 1px solid #5F7983;
background-color: #ededed }
.portletContent { margin: 4px 9px }
@ -133,7 +133,7 @@ img { border: 0; vertical-align: middle }
.history th { font-style: italic; text-align: left; padding: 0 5px 0 5px }
.topSpace { margin-top: 15px }
.bottomSpace { margin-bottom: 15px }
.pageLink { padding-left: 8px }
.pageLink { margin-right: 8px }
.footer { font-size: 95% }
.footer td { background-color: #CBCBC9; border-top: 1px solid grey;
padding: 0.4em 1em 0.5em }

View file

@ -32,6 +32,15 @@ function setLoginVars() {
else emptyPassword.value = '0';
}
function showLoginForm() {
// Hide the login link.
var loginLink = document.getElementById('loginLink');
loginLink.style.display = "none";
// Displays the login form.
var loginFields = document.getElementById('loginFields');
loginFields.style.display = "inline";
}
var isIe = (navigator.appName == "Microsoft Internet Explorer");
function getElementsHavingName(tag, name) {

View file

@ -5,3 +5,4 @@ ul li { background-image: url("ui/lirtl.gif");
.portlet { border-right: none; border-left: 1px solid #5F7983 }
.lang { margin-right: 0px; margin-left: 6px; }
.cellGap { padding-left: 0.4em; padding-right: 0;}
.pageLink { margin-right: 0px; margin-left: 8px }

View file

@ -1 +1,2 @@
<span metal:define-macro="icons"></span>
<metal:i define-macro="icons"></metal:i>
<metal:l define-macro="links"></metal:l>

View file

@ -15,6 +15,7 @@
layoutType tool/getLayoutType;
contextObj python: tool.getPublishedObject(layoutType);
dir python: tool.getLanguageDirection(lang);
discreetLogin python: tool.getAttr('discreetLogin', source='config');
dleft python: (dir == 'ltr') and 'left' or 'right';
dright python: (dir == 'ltr') and 'right' or 'left';
x python: resp.setHeader('Content-type', 'text/html;;charset=UTF-8');
@ -39,7 +40,6 @@
type="text/javascript" tal:content="gaCode"></script>
<tal:comment replace="nothing">Grey background shown when popups are shown</tal:comment>
<div id="grey" class="grey"></div>
<tal:comment replace="nothing">Popup for confirming an action</tal:comment>
<div id="confirmActionPopup" class="popup">
<form id="confirmActionForm" method="post">
@ -81,38 +81,35 @@
<tr class="top" metal:define-slot="top">
<td tal:define="bannerName python: (dir == 'ltr') and 'banner' or 'bannerrtl'"
tal:attributes="style python: 'background-image: url(%s/ui/%s.jpg)' % (appUrl, bannerName)">
<table width="100%" style="margin-top: 4px">
<tr valign="top" tal:define="pages tool/getMainPages">
<tal:comment replace="nothing">Links to main pages</tal:comment>
<td tal:condition="pages"><a tal:repeat="page pages" class="pageLink"
<tal:comment replace="nothing">Top links</tal:comment>
<div style="margin-top: 4px"
tal:define="pages tool/getMainPages" tal:attributes="align dright">
<tal:comment replace="nothing">Icon "home"</tal:comment>
<a class="pageLink" tal:attributes="href appUrl; title python: _('app_home')">
<img tal:attributes="src string: $appUrl/ui/home.gif" style="margin-right: 3px"/>
</a>
<tal:comment replace="nothing">Additional links (or icons) from icons.pt</tal:comment>
<metal:call use-macro="app/ui/icons/macros/links"/>
<tal:comment replace="nothing">Top-level pages</tal:comment>
<a tal:repeat="page pages" class="pageLink"
tal:content="page/title" tal:attributes="href page/absolute_url"></a>
</td>
<tal:comment replace="nothing">Language selector (links or listbox)</tal:comment>
<td tal:condition="tool/showLanguageSelector" tal:attributes="align dright">
<tal:lgs define="languages tool/getLanguages;
defaultLanguage python: languages[0];
asLinks python: len(languages) &lt;= 8">
<table tal:condition="asLinks">
<tr>
<td tal:repeat="lang languages">
<a class="lang"
tal:attributes="href string: $appUrl/config/changeLanguage?language=$lang;
title python: tool.getLanguageName(lang)"
tal:content="python: lang"></a>
</td>
</tr>
</table>
<select tal:condition="not: asLinks"
<tal:comment replace="nothing">Connect link if discreet login</tal:comment>
<a id="loginLink" name="loginLink" onclick="showLoginForm()" class="pageLink" style="cursor:pointer"
tal:condition="python: isAnon and discreetLogin" tal:content="python: _('app_connect')">
</a>
<tal:comment replace="nothing">Language selector</tal:comment>
<tal:lg condition="tool/showLanguageSelector">
<select class="pageLink"
tal:define="languages tool/getLanguages;
defaultLanguage python: languages[0]"
tal:attributes="onchange string:window.location='$appUrl/config/changeLanguage?language=' + this.options[this.selectedIndex].value">
<option tal:repeat="lang languages"
tal:content="python: tool.getLanguageName(lang)"
tal:attributes="selected python:defaultLanguage == lang; value lang">
<option tal:repeat="lg languages"
tal:content="python: tool.getLanguageName(lg)"
tal:attributes="selected python:lang == lg; value lg">
</option>
</select>
</tal:lgs>
</td>
</tr>
</table>
</tal:lg>
</div>
</td>
</tr>
<tal:comment replace="nothing">The message strip</tal:comment>
@ -128,58 +125,46 @@
<td>
<table class="userStrip" width="100%">
<tr>
<td>
<tal:comment replace="nothing">The user login form for anonymous users</tal:comment>
<table align="center" tal:condition="python: isAnon and ('/temp_folder/' not in req['ACTUAL_URL'])"
class="login">
<tr>
<td>
<!-- Go home -->
<a tal:attributes="href appUrl; title python: _('app_home')">
<img tal:attributes="src string: $appUrl/ui/home.gif" style="margin-right: 3px"/>
</a>
<tal:comment replace="nothing">Additional icons can be added here by redefining icons.pt</tal:comment>
<metal:call use-macro="app/ui/icons/macros/icons"/>
</td>
<td class="userStripText">
<form name="loginform" method="post"
<td align="center"
tal:condition="python: isAnon and ('/temp_folder/' not in req['ACTUAL_URL'])">
<form id="loginForm" name="loginForm" method="post" class="login"
tal:attributes="action python: tool.absolute_url() + '/performLogin'">
<input type="hidden" name="js_enabled" id="js_enabled" value="0"/>
<input type="hidden" name="cookies_enabled" id="cookies_enabled" value=""/>
<input type="hidden" name="login_name" id="login_name" value=""/>
<input type="hidden" name="pwd_empty" id="pwd_empty" value="0"/>
<span tal:replace="python: _('app_login')"/>&nbsp;
<tal:comment replace="nothing">The login fields, directly shown or not (depends on discreetLogin)</tal:comment>
<span id="loginFields" name="loginFields"
tal:attributes="style python: discreetLogin and 'display:none' or 'display:block'">
<span class="userStripText" tal:content="python: _('app_login')"/>
<input type="text" name="__ac_name" id="__ac_name" value="" style="width: 142px"/>&nbsp;
<span tal:replace="python: _('app_password')"/>&nbsp;
<span class="userStripText" tal:content="python: _('app_password')"/>
<input type="password" name="__ac_password" id="__ac_password" style="width: 142px"/>
<input type="submit" name="submit" onclick="setLoginVars()"
tal:define="label python: _('app_connect')" tal:attributes="value label; alt label;"/>
tal:define="label python: _('app_connect')" tal:attributes="value label; alt label"/>
<tal:comment replace="nothing">Forgot password?</tal:comment>
<a class="lostPassword" href="javascript: openPopup('askPasswordReinitPopup')"
tal:condition="tool/showForgotPassword"
tal:content="python: _('forgot_password')">
</a>
</span>
</form>
</td>
<td class="lostPassword" tal:condition="tool/showForgotPassword">
<a href="javascript: openPopup('askPasswordReinitPopup')"
tal:content="python: _('forgot_password')"></a></td>
</tr>
</table>
<tal:comment replace="nothing">User info and controls for authenticated users</tal:comment>
<table tal:condition="not: isAnon" class="buttons" width="99%">
<td tal:condition="not: isAnon">
<table class="buttons" width="99%">
<tr>
<td>
<!-- Go home -->
<a tal:attributes="href appUrl; title python: _('app_home')">
<img tal:attributes="src string: $appUrl/ui/home.gif"/>
</a>
<!-- Config -->
<tal:comment replace="nothing">Config</tal:comment>
<a tal:condition="python: user.has_role('Manager')"
tal:attributes="href python: tool.getUrl(nav='');
title python: _('%sTool' % appName)">
<img tal:attributes="src string:$appUrl/ui/appyConfig.gif"/>
</a>
<tal:comment replace="nothing">Additional icons can be added here by redefining icons.pt</tal:comment>
<tal:comment replace="nothing">Additional icons from icons.pt</tal:comment>
<metal:call use-macro="app/ui/icons/macros/icons"/>
<!-- Logout -->
<tal:comment replace="nothing">Log out</tal:comment>
<a tal:attributes="href python: tool.absolute_url() + '/performLogout';
title python: _('app_logout')">
<img tal:attributes="src string: $appUrl/ui/logout.gif"/>

View file

@ -74,8 +74,9 @@ class UserWrapper(AbstractWrapper):
# The user for which we change the password is the currently logged
# user. So update the authentication cookie, too.
tool._updateCookie(login, newPassword)
loggedUser = self.user.getId() or 'system|anon'
self.log('Password %s by "%s" for "%s".' % \
(msgPart, self.user.getId(), login))
(msgPart, loggedUser, login))
return newPassword
def checkPassword(self, clearPassword):