This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
glasnost/glasnost-web/login.py

341 lines
13 KiB
Python

# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@easter-eggs.org>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
__doc__ = """Glasnost Login Python Web Page"""
__version__ = '$Revision$'[11:-2]
import glasnost.common.context as context
from glasnost.common.ObjectsCommon import ObjectCommon
import glasnost.common.slots as slots
import glasnost.common.tools_new as commonTools
import glasnost.common.xhtmlgenerator as X
from glasnost.web.ObjectsWeb import BaseObjectWebMixin
from glasnost.web.tools import *
class Login(BaseObjectWebMixin, ObjectCommon):
authenticationSlotNames = None
id_kindName = None
language_kindName = None
## login = None
## login_kind_balloonHelp = N_('Enter the username you use on this site.')
## login_kind_isRequired = 1
## login_kind_isTranslatable = 0
## login_kindName = 'String'
## login_kind_widget_fieldLabel = N_('Username')
## login_kind_widget_maxLength = 40
## login_kind_widget_size = 15
## login_kind_widgetName = 'InputText'
##
## password = None
## password_kind_balloonHelp = N_('Enter your password.')
## password_kind_isRequired = 1
## password_kindName = 'Password'
## password_kind_widget_fieldLabel = N_('Password')
## password_kind_widget_maxLength = 15
## password_kind_widget_size = 15
## password_kind_widgetName = 'InputPassword'
version_kindName = None
def getOrderedLayoutSlotNames(self, parentSlot = None):
slotNames = ObjectCommon.getSlotNames(self, parentSlot = parentSlot)
for slotName in self.authenticationSlotNames:
slotNames.remove(slotName)
slotNames += self.authenticationSlotNames
return slotNames
def getSlotNames(self, parentSlot = None):
slotNames = ObjectCommon.getSlotNames(self, parentSlot = parentSlot)
slotNames += self.authenticationSlotNames
return slotNames
def confirmEmailPassword(personId = '', nextUri = ''):
peopleWeb = getWebForServerRole('people')
person = peopleWeb.getObject(personId)
if not peopleWeb.canEmailPassword(person.id):
# FIXME: error message telling the user he can't email the password
return pageNotFound()
layout = X.array()
layout += X.div(_class = 'alert')(
_('Are you sure you want to send the password by email to %s?') \
% person.getFullName())
layout += X.br()
layout += X.buttonStandalone(
'send-by-email',
X.url('/login/emailPassword').add('personId', personId).add(
'nextUri', nextUri))
return writePageLayout(layout, _('Confirm Sending of Password by Email'),
canCache = 0)
def emailPassword(personId = '', nextUri = ''):
if not nextUri:
nextUri = '/'
peopleWeb = getWebForServerRole('people')
if not peopleWeb.hasObject(personId):
return pageNotFound()
person = peopleWeb.getObject(personId)
try:
peopleWeb._emailPassword(personId)
except faults.Fault:
return failure(
_('The sending of the password by email to %s has failed!') \
% person.getFullName(),
nextUri)
return success(
_('The password has been sent by email to %s!') \
% person.getFullName(),
nextUri)
def index(nextUri = '', access = '', again = '', error = '', **keywords):
req = context.getVar('req')
req.headers_out['Cache-Control'] = 'no-cache, must-revalidate'
req.headers_out['Pragma'] = 'no-cache'
if keywords is None:
keywords = {}
login = Login()
authenticationLoginPasswordProxy = getProxyForServerRole(
'authentication-login-password')
slotNamesAndKinds = authenticationLoginPasswordProxy.getSlotNamesAndKinds(
'login')
for slotName, kind in slotNamesAndKinds:
setattr(login, '%s_kind' % slotName, kind)
login.authenticationSlotNames = [
slotNameAndKind[0]
for slotNameAndKind in slotNamesAndKinds]
if not again:
login.initFields(keywords)
login.repairFields(keywords)
headerTitle = _('Login')
context.push(_level = 'index', layoutMode = 'edit')
try:
layout = X.array()
if access == 'forbidden':
layout += X.p(_(
'To access this part of the site, you need to sign in.'))
layout += login.getErrorLayout(error, keywords)
submitUrl = X.url('/login/submit')
if context.getVar('virtualHost').useHTTPS:
hostNameAndPort = commonTools.makeHttpHostNameAndPort(
context.getVar('httpHostName'),
context.getVar('httpPort'))
submitUrl = 'https://%s%s' % (hostNameAndPort, submitUrl)
form = X.form(action = submitUrl, enctype = 'multipart/form-data',
method = 'post')
layout += form
form += login.getEditLayout(keywords)
if nextUri:
form += X.div(X.input(name = 'nextUri', type = 'hidden',
value = nextUri))
form += X.div(_class = 'buttons-bar')(
X.span(_class = 'action-buttons-bar')(
X.buttonInForm('login', 'loginButton')),
#X.span(_class = 'other-action-buttons-bar')(
# X.buttonInForm('send-password-by-email', 'sendButton')),
)
return writePageLayout(layout, headerTitle)
finally:
context.pull(_level = 'index')
def logout(nextUri = ''):
session = context.getVar('session')
if session is not None:
# Don't delete the session, just remove userToken & userId from it.
# sessionToken = context.getVar('sessionToken')
# getProxyForServerRole('sessions').deleteSession(sessionToken)
# context.delVar('sessionToken')
# context.delVar('session')
if session.has_key('userId'):
del session['userId']
session['isDirty'] = 1
context.setVar('userId', '')
if session.has_key('userToken'):
del session['userToken']
session['isDirty'] = 1
context.setVar('userToken', '')
# if not context.getVar('sessionTokenInCookie', default = 0):
# # The sessionToken was not stored in a cookie, so don't try to use
# # the cookie when loging out.
# context.setVar('canUseCookie', 0)
if not nextUri:
nextUri = '/'
else:
nextUri = cleanUpUri(nextUri, ['sessionToken'])
canUseCookie = context.getVar('canUseCookie', default = 0)
if not canUseCookie:
nextUri = appendToUri(nextUri,
'sessionToken=' + context.getVar('sessionToken'))
return redirect(nextUri)
def submit(nextUri = '', **keywords):
if keywords is None:
keywords = {}
error = 0
login = Login()
authenticationProxy = getProxyForServerRole('authentication')
authenticationLoginPasswordProxy = getProxyForServerRole(
'authentication-login-password')
slotNamesAndKinds = authenticationLoginPasswordProxy.getSlotNamesAndKinds('login')
for slotName, kind in slotNamesAndKinds:
setattr(login, '%s_kind' % slotName, kind)
login.authenticationSlotNames = [
slotNameAndKind[0]
for slotNameAndKind in slotNamesAndKinds]
sendPasswordByEmail = isButtonSelected('sendButton', keywords)
if error:
keywords['again'] = '1'
keywords['error'] = '1'
elif sendPasswordByEmail:
slot = login.getSlot('login')
slot.getKind().submitField(slot, keywords)
else:
login.submitFields(keywords)
if keywords.has_key('again') and keywords['again']:
uri = X.url('login')
uri.add('nextUri', nextUri)
uri.addKeywords(keywords)
return redirect(uri)
peopleWeb = getWebForServerRole('people')
if sendPasswordByEmail:
from mod_python import apache
raise apache.SERVER_RETURN, apache.HTTP_NOT_IMPLEMENTED
if not peopleWeb.hasObjectByLogin(login.login):
keywords['login_error'] = 'wrongValue'
keywords['again'] = '1'
keywords['error'] = '1'
uri = X.url('login')
uri.add('nextUri', nextUri)
uri.addKeywords(keywords)
return redirect(uri)
person = peopleWeb.getObjectByLogin(login.login)
uri = X.url('login/confirmEmailPassword')
uri.add('personId', person.id)
uri.add('nextUri', nextUri)
return redirect(uri)
try:
userToken = authenticationProxy.getUserToken(
'login-password',
[getattr(login, slotName)
for slotName in login.authenticationSlotNames])
except faults.WrongLogin:
keywords['again'] = '1'
keywords['error'] = '1'
keywords['login_error'] = 'wrongValue'
uri = X.url('login')
uri.add('nextUri', nextUri)
uri.addKeywords(keywords)
return redirect(uri)
except faults.WrongPassword:
keywords['again'] = '1'
keywords['error'] = '1'
keywords['password_error'] = 'wrongValue'
uri = X.url('login')
uri.add('nextUri', nextUri)
uri.addKeywords(keywords)
return redirect(uri)
except:
if context.getVar('debug'):
raise
return accessForbidden()
session = context.getVar('session')
sessionToken = context.getVar('sessionToken')
oldSession = session
if session is None:
req = context.getVar('req')
sessionsProxy = getProxyForServerRole('sessions')
session = sessionsProxy.newSession(req.connection.remote_ip)
sessionToken = session['sessionToken']
context.setVar('sessionToken', sessionToken)
context.setVar('session', session)
context.setVar('userToken', userToken)
userId = getProxyForServerRole('authentication').getUserId()
session['userId'] = userId
context.setVar('userId', userId)
session['userToken'] = userToken
session['isDirty'] = 1
peopleWeb = getWebForServerRole('people')
#peopleWeb.setLoginTime(session['userToken'])
if not nextUri:
hostNameAndPort = commonTools.makeHttpHostNameAndPort(
context.getVar('httpHostName'),
context.getVar('httpPort'))
if not hostNameAndPort:
nextUri = '/'
else:
nextUri = 'http://%s/' % hostNameAndPort
if context.getVar('virtualHost').useHTTPS:
nextUri = nextUri.replace('http:', 'https:', 1)
else:
if context.getVar('virtualHost').useHTTPS:
nextUri = nextUri.replace('http:', 'https:', 1)
nextUri = cleanUpUri(nextUri, ['sessionToken'])
canUseCookie = context.getVar('canUseCookie', default = 0)
if not canUseCookie:
nextUri = appendToUri(nextUri, 'sessionToken=' + sessionToken)
return redirect(nextUri)
uri = X.url('define/testCookie')
uri.add('nextUri', nextUri)
uri.add('sessionToken', sessionToken)
context.setVar('canUseCookie', 0)
uri = uri.getAsUrl()
context.setVar('canUseCookie', 1)
return redirect(uri)