diff --git a/modules/webaccess/doc/admin/guide.html.wml b/modules/webaccess/doc/admin/guide.html.wml
index 2d266915b..74b94db9c 100644
--- a/modules/webaccess/doc/admin/guide.html.wml
+++ b/modules/webaccess/doc/admin/guide.html.wml
@@ -1,1005 +1,1013 @@
## $Id$
## This file is part of CDS Invenio.
## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 CERN.
##
## CDS Invenio 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.
##
## CDS Invenio 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 CDS Invenio; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="WebAccess Admin Guide" \
navtrail_previous_links="/admin/>Admin Area > /admin/webaccess/>WebAccess Admin " \
navbar_name="admin" \
navbar_select="webaccess-admin-guide"
Version <: print generate_pretty_revision_date_string('$Id$'); :>
WebAccess is a common RBAC, role based access control, for all of
CDS Invenio. This means that users are connected to roles that cover
different areas of access. I.e administrator of the photo
collection or system librarian. Users can be active in
different areas and of course connected to as many roles as needed.
The roles are connected to actions. An action identifies a task you
can perform in CDS Invenio. It can be defined to take any number of
arguments in order to more clearly describe what you are allowing
connected users to do.
For example the system librarian can be allowed to run bibwords on
the different indexes. To allow system librarians to run the
bibwords indexing on the field author we connect role system
librarian with action runbibwords using the argument
index='author'.
WebAccess is based on allowing users to perform actions. This means
that only allowed actions are stored in the access control engine's
database.
All the WebAccess Administration web pages have certain
features/design choices in common
- Divided into steps
The process of adding new authorizations/information is
stepwise. The subtitle contains information about wich step you are
on and what you are supposed to do.
- Restart from any wanted step
You can always start from an earlier step by simply clicking the
wanted button. This is not a way to undo changes! No information
about previous database is kept, so all changes are definite.
- Change or new entry must confirmed
On all the pages you will be asked to confirm the change, with
information about what kind of change you are about to perform.
- Links to other relevant admin areas on the right side
To make it easier to perform your administration tasks, we have
added a menu area on the right hand side of these pages. The menu
contain links to other relevant admin pages and change according to
the page you are on and the information you have selected.
I. Role area
II. Example - connecting role and user
I. Role area
Administration tasks starts in one of the administration areas. The
role area is the main area from where you can perform all your
managing tasks. The other admin areas are just other ways of
entering.
II. Example - connecting role and user
One of the important tasks that can be handled via the WebAccess Admin Web Interface
is the delegation of access rights to users. This is done by connecting them to the
different roles offered.
The task is divided into 5 simple and comprehensive steps. Below follows the pages from
the different steps with comments on the ongoing procedure.
- step 1 - select a role
You must first select the role you want to connect users to. All the available roles are
listed alfabetically in a select box. Just find the wanted role and select it. Then click on
the button saying "select role".
If you start from the Role Area, this step is already done, and you start directly on step 2.
- step 2 - search for users
As you can see, the subtitle of the page has now changed. The subtitle always tells you
which step you are on and what your current task is.
There can be possibly thousands of users using your online library, therefore it is important
to make it easier to identify the user you are looking for. Give part of, or the entire search
string and all users with partly matching e-mails will be listed on the next step.
You can also see that the right hand menu has changed. This area is always updated with links
to related admin areas.
start adding new authorizations to role superadmin.
- step 3 - select a user.
The select box contains all users with partly matching e-mail addresses. Select the one
you want to connect to the role and continue.
Notice the navigation trail that tells you were on the Administrator pages you are currently
working.
start adding new authorizations to role superadmin.
- step 4 - confirm to add user
All WebAccess Administrator web pages display the action you are about to peform, this
means explaining what kind of addition, change or update will be done to your access control
data.
If you are happy with your decision, simply confirm it.
start adding new authorizations to role superadmin.
- step 5 - confirm user added.
The user has now been added to this role. You can easily continue adding more users to this
role be restarting from step 2 or 3. You can also go directly to another area and keep working
on the same role.
start adding new authorizations to role superadmin.
- we are done
This example is very similar to all the other pages where you administrate WebAccess. The pages
are an easy gateway to maintaing access control rights and share a lot of features.
- divided into steps
- restart from any wanted step (not undo)
- changes must be confirmed
- link to other relevant areas
- prevent unwanted input
As an administrator with access to these pages you are free to manage the rights any way you want.
Here you can administrate the accounts and the access policy for your CDS Invenio installation.
- Access policy:
To change the access policy, the general config file (or
access_control_config.py) must be edited manually in a text
editor. The site can there be defined as opened or closed, you can
edit the access policy level for guest accounts, registered
accounts and decide when to warn the owner of the account when
something happens with it, either when it is created, deleted or
approved. The Apache server must be restarted after modifying
these settings.
The two levels for guest account, are:
0 - Allow guest accounts
1 - Do not allow guest accounts
The five levels for normal accounts, are:
0 - Allow user to create account, automatically activate new accounts
1 - Allow user to create account, administrator must activate account
2 - Only administrators can create account. User cannot edit the email address.
3 - Users cannot register or update account information (email/password)
4 - User cannot change default login method
You can configure CDS Invenio to send an email:
1. To an admin email-address when an account is created
2. To the owner of an account when it is created
3. To the owner of an account when it is activated
4. To the owner of an account when it is deleted
Define how open the site is:
0 = normal operation of the site
1 = read-only site, all write operations temporarily closed
2 = site fully closed
CFG_ACCESS_CONTROL_LEVEL_SITE = 0
Access policy for guests:
0 = Allow guests to search,
1 = Guests cannot search (all users must login)
CFG_ACCESS_CONTROL_LEVEL_GUESTS = 0
Access policy for accounts:
0 = Users can register, automatically acticate accounts
1 = Users can register, but admin must activate the accounts
2 = Users cannot register or change email address, only admin can register accounts.
3 = Users cannot register or update email address or password, only admin can register accounts.
4 = Same as 3, but user cannot change login method.
CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS = 0
Limit email addresses available to use when register a new account (example: cern.ch):
CFG_ACCESS_CONTROL_LIMIT_REGISTRATION_TO_DOMAIN = ""
Send an email when a new account is created by an user:
CFG_ACCESS_CONTROL_NOTIFY_ADMIN_ABOUT_NEW_ACCOUNTS = 0
Send an email to the user notifying when the account is created:
CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_NEW_ACCOUNT = 0
Send an email to the user notifying when the account is activated:
CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_ACTIVATION = 0
Send an email to the user notifying when the account is deleted/rejected:
CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_DELETION = 0
- Account overview:
Here you find an overview of the number of guest accounts, registered accounts and accounts
awaiting activation, with a link to the activation page.
- Create account:
For creating new accounts, the email address must be unique. If configured to do so, an email
will be sent to the given address when an account is created.
- Edit accounts:
For activating or rejecting accounts in addition to modifying them. An activated account can be
inactivated for a short period of time, but this will not warn the account owner. To find accounts
enter a part of the email address of the account and then search. This may take some time. If there
are more than the selected number of accounts per page, you can use the next/prev links to switch
pages. The accounts to search in can also be limited to only activated or not activated accounts.
- Edit account:
When editing one account, you can change the email address, password, delete the account, or modify
the baskets or alerts belonging to one account. Which login method should be the default for this
account can also be selected. To modify baskets or alerts, you need to login as the user, and
modify the desired data as a normal user. Remember to log out as the user when you are finished
editing.
CDS Invenio supports using external login systems to authenticate users.
When a user wants to login, the username and password given by the user is checked against the selected
system, if the user is authenticated by the external system, a valid email-address is returned to
CDS Invenio and used to recognize the user within CDS Invenio.
If a new user is trying to login without having an account, using an external login system, an account
is automatically created in CDS Invenio to recognize and store the users settings. The password for the
local account is randomly generated.
If you want the user to be unable to change login method and account username / password, forcing use
of certain external systems, set CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS to 4 as mentioned in the last paragraph.
If a user is changing login method from an external one to the internal, he also need to either change the
password before logging out, or ask to get the password sent by email, since the password is randomly
generated for the local account when using an external login method.
If a external login system is used, you may want to protect the users username / password using HTTPS.
To add new system, two changes must be made (for the time being):
- The name of the method, if it is default or not, and the classname must be added to the variable
CFG_EXTERNAL_AUTHENTICATION in access_control_config.py. Atleast one method must be marked as the
default one. The internal login method should be given with None as classname.
Example:
CFG_EXTERNAL_AUTHENTICATION = {"%s (internal)" % cdsname: (None, True), "CERN NICE (external)":
(AuthCernWrapper(), False)}
- A class must be created derived from the class external_authentication inside file
external_authentication.py. This class must include at least the
function auth_user. This function returns a valid email-address in CDS Invenio if the user
is authenticated, not necessarily the same entered by the user as username. If the user
is not authenticated, return None.
- The class could also provide four more methods: fetch_user_preferences, user_exists,
+ The class could also provide five more methods: fetch_user_preferences, user_exists,
fetch_user_groups_membership and fetch_all_users_groups_membership.
The first should take an email and eventually a password and should return a dictionary of keys
and value representing external preferences, infos or settings. If, for some reasons, you like
to force some kind of hiding for some particular field you should export the related key
prefixed by "HIDDEN_". Those fields won't be displayed in tables and pages regarding external
settings.
The second method should check through the external system if a particular email exists. If you
provide such a method then a user will be able to switch from and to this authorization method.
The third method should take an email and (if necessary) a password
and should return a dictionary of external_groups_names toghether with their description, for which
the user has a membership. Those groups will be merged into the groups system.
The user will be a member of those groups and will be able to use them in any place
where groups are useful, but won't be able to unsubscribe or to administrate them.
The fourth method should just return a dictionary of external groups as keys and touples containing
a group description and a list of email of users belonging to each groups. Those memberships
will be merged into the database in the way done by the previous method, but could
provide batch synchronization of groups.
+ The fifth method should just return the nickname as is known by the external authentication
+ system, given the usual email/username and the password.
Note: if your system has more than one external login methods then incoherence in the groups
memberships could happen when a user switch his login method. This will be fixed some times in the
future.
Example template:
from invenio.external_authentication import ExternalAuth, WebAccessExternalAuthError
class ExternalAuthFoo(ExternalAuth):
"""External authentication template example."""
def __init__(self):
"""Initialize stuff here."""
self.name = None
pass
def auth_user(self, username, password):
"""Authenticate user-supplied USERNAME and PASSWORD.
Return None if authentication failed, or the email address of the
person if the authentication was successful. In order to do
this you may perhaps have to keep a translation table between
usernames and email addresses.
Raise WebAccessExternalAuthError in case of external troubles.
"""
raise NotImplementedError
#return None
def user_exists(self, email):
"""Checks against external_authentication for existance of email.
@return True if the user exists, False otherwise
"""
raise NotImplementedError
def fetch_user_groups_membership(self, username, password=None):
"""Given a username, returns a dictionary of groups
and their description to which the user is subscribed.
Raise WebAccessExternalAuthError in case of troubles.
"""
raise NotImplementedError
#return {}
def fetch_user_preferences(self, username, password=None):
"""Given a username and a password, returns a dictionary of keys and
values, corresponding to external infos and settings.
userprefs = {"telephone": "2392489",
"address": "10th Downing Street"}
"""
raise NotImplementedError
#return {}
def fetch_all_users_groups_membership(self):
"""Fetch all the groups with a description, and users who belong to
each groups.
@return {'mygroup': ('description', ['email1', 'email2', ...]), ...}
"""
raise NotImplementedError
+ def fetch_user_nickname(self, username, password):
+ """Given a username and a password, returns the right nickname belonging
+ to that user (username could be an email).
+ """
+ raise NotImplementedError
+ #return Nickname
- end of file -
diff --git a/modules/webaccess/lib/access_control_config.py b/modules/webaccess/lib/access_control_config.py
index d04a67a20..b6bfffa36 100644
--- a/modules/webaccess/lib/access_control_config.py
+++ b/modules/webaccess/lib/access_control_config.py
@@ -1,155 +1,154 @@
## $Id$
##
## This file is part of CDS Invenio.
## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 CERN.
##
## CDS Invenio 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.
##
## CDS Invenio 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 CDS Invenio; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDS Invenio Access Control Config. """
__revision__ = \
"$Id$"
# pylint: disable-msg=C0301
import external_authentication_cern
from invenio.config import cdsname, sweburl, supportemail
# VALUES TO BE EXPORTED
# CURRENTLY USED BY THE FILES access_control_engine.py access_control_admin.py webaccessadmin_lib.py
# name of the role giving superadmin rights
SUPERADMINROLE = 'superadmin'
# name of the webaccess webadmin role
WEBACCESSADMINROLE = 'webaccessadmin'
# name of the action allowing roles to access the web administrator interface
WEBACCESSACTION = 'cfgwebaccess'
# name of the action allowing roles to delegate the rights to other roles
# ex: libraryadmin to delegate libraryworker
DELEGATEADDUSERROLE = 'accdelegaterole'
# max number of users to display in the drop down selects
MAXSELECTUSERS = 25
# max number of users to display in a page (mainly for user area)
MAXPAGEUSERS = 25
# Use external source for access control?
# Atleast one must be added
# Adviced not to change the name, since it is used to identify the account
# Format is: System name: (System class, Default True/Flase), atleast one
# must be default
-CFG_EXTERNAL_AUTHENTICATION = {"%s (internal)" % cdsname: (None, True)}
-#CFG_EXTERNAL_AUTHENTICATION = {"%s (internal)" % cdsname: (None, True), \
-# "CERN (external)": (external_authentication_cern.ExternalAuthCern(), False)}
-
+CFG_EXTERNAL_AUTHENTICATION = {"Local": (None, True)}
+#CFG_EXTERNAL_AUTHENTICATION = {"Local": (None, True), \
+# "CERN": (external_authentication_cern.ExternalAuthCern(), False)}
# default data for the add_default_settings function
# roles
# name description
DEF_ROLES = ((SUPERADMINROLE, 'superuser with all rights'),
('photoadmin', 'Photo collection administrator'),
(WEBACCESSADMINROLE, 'WebAccess administrator'))
# users
# list of e-mail addresses
DEF_USERS = []
# actions
# name desc allowedkeywords optional
DEF_ACTIONS = (
('cfgwebsearch', 'configure WebSearch', '', 'no'),
('cfgbibformat', 'configure BibFormat', '', 'no'),
('cfgwebsubmit', 'configure WebSubmit', '', 'no'),
('runbibindex', 'run BibIndex', '', 'no'),
('runbibupload', 'run BibUpload', '', 'no'),
('runwebcoll', 'run webcoll', 'collection', 'yes'),
('runbibformat', 'run BibFormat', 'format', 'yes'),
(WEBACCESSACTION, 'configure WebAccess', '', 'no'),
(DELEGATEADDUSERROLE, 'delegate subroles inside WebAccess', 'role', 'no'),
('runbibtaskex', 'run BibTaskEx example', '', 'no'),
('referee', 'referee document type doctype/category categ', 'doctype,categ', 'yes'),
('submit', 'use webSubmit', 'doctype,act', 'yes'),
('runbibrank', 'run BibRank', '', 'no'),
('cfgbibrank', 'configure BibRank', '', 'no'),
('cfgbibharvest', 'configure BibHarvest', '', 'no'),
('runoaiharvest', 'run oaiharvest task', '', 'no'),
('cfgwebcomment', 'configure WebComment', '', 'no'),
('runoaiarchive', 'run oaiarchive task', '', 'no'),
('runbibedit', 'run BibEdit', '', 'no'),
)
# authorizations
# role action arglistid optional arguments
DEF_AUTHS = (
(SUPERADMINROLE, 'cfgwebsearch', -1, 0, {}),
(SUPERADMINROLE, 'cfgbibformat', -1, 0, {}),
(SUPERADMINROLE, 'cfgwebsubmit', -1, 0, {}),
(SUPERADMINROLE, 'runbibindex', -1, 0, {}),
(SUPERADMINROLE, 'runbibupload', -1, 0, {}),
(SUPERADMINROLE, 'runbibformat', -1, 1, {}),
(SUPERADMINROLE, WEBACCESSACTION, -1, 0, {}),
('photoadmin', 'runwebcoll', -1, 0, {'collection': 'Pictures'}),
(WEBACCESSADMINROLE,WEBACCESSACTION, -1, 0, {}),
(SUPERADMINROLE, 'runtaskex', -1, 0, {}),
(SUPERADMINROLE, 'referee', -1, 1, {}),
(SUPERADMINROLE, 'submit', -1, 1, {}),
(SUPERADMINROLE, 'runbibrank', -1, 0, {}),
(SUPERADMINROLE, 'cfgbibrank', -1, 0, {}),
(SUPERADMINROLE, 'cfgbibharvest', -1, 0, {}),
(SUPERADMINROLE, 'runoaiharvest', -1, 0, {}),
(SUPERADMINROLE, 'cfgwebcomment', -1, 0, {}),
(SUPERADMINROLE, 'runoaiarchive', -1, 0, {}),
(SUPERADMINROLE, 'runbibedit', -1, 0, {}),
)
CFG_WEBACCESS_MSGS = {
0: 'Try to login with another account.' % (sweburl, sweburl, "%s"),
1: ' If you think this is not correct, please contact: %s' % (supportemail, supportemail),
2: ' If you have any questions, please write to %s' % (supportemail, supportemail),
3: 'Guest users are not allowed, please login.' % sweburl,
4: 'The site is temporarily closed for maintenance. Please come back soon.',
5: 'Authorization failure',
6: '%s temporarily closed' % cdsname,
7: 'This functionality is temporarily closed due to server maintenance. Please use only the search engine in the meantime.',
8: 'Functionality temporarily closed'
}
CFG_WEBACCESS_WARNING_MSGS = {
0: 'Authorization granted',
1: 'Error(1): You are not authorized to perform this action.',
2: 'Error(2): You are not authorized to perform any action.',
3: 'Error(3): The action %s does not exist.',
4: 'Error(4): Unexpected error occurred.',
5: 'Error(5): Missing mandatory keyword argument(s) for this action.',
6: 'Error(6): Guest accounts are not authorized to perform this action.',
7: 'Error(7): Not enough arguments, user ID and action name required.',
8: 'Error(8): Incorrect keyword argument(s) for this action.',
9: """Error(9): Account '%s' is not yet activated.""",
10: """Error(10): You were not authorized by the authentication method '%s'.""",
11: """Error(11): The selected login method '%s' is not the default method for this account, please try another one.""",
12: """Error(12): Selected login method '%s' does not exist.""",
13: """Error(13): Could not register '%s' account.""",
14: """Error(14): Could not login using '%s', because this user is unknown.""",
15: """Error(15): Could not login using your '%s' account, because you have introduced a wrong password.""",
16: """Error(16): External authentication troubles using '%s' (maybe temporary network problems).""",
}
diff --git a/modules/webaccess/lib/external_authentication.py b/modules/webaccess/lib/external_authentication.py
index 3016e80e4..781f26432 100644
--- a/modules/webaccess/lib/external_authentication.py
+++ b/modules/webaccess/lib/external_authentication.py
@@ -1,87 +1,100 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of CDS Invenio.
## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 CERN.
##
## CDS Invenio 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.
##
## CDS Invenio 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 CDS Invenio; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""External user authentication for CDS Invenio."""
__revision__ = \
"$Id$"
class WebAccessExternalAuthError(Exception):
"""Exception to signaling general external trouble."""
pass
class ExternalAuth:
"""External authentication template example."""
def __init__(self):
"""Initialize stuff here"""
self.name = None
+ # Set the following variable to True in order to import the externally
+ # provided nickname into Invenio during the first login of a user
+ # through this external authentication system.
+ # If the nickname is already taken into Invenio, then it won't be
+ # considered.
+ self.enforce_external_nicknames = False
pass
def auth_user(self, username, password):
"""Authenticate user-supplied USERNAME and PASSWORD. Return
None if authentication failed, or the email address of the
person if the authentication was successful. In order to do
this you may perhaps have to keep a translation table between
usernames and email addresses.
Raise WebAccessExternalAuthError in case of external troubles.
"""
raise NotImplementedError
#return None
def user_exists(self, email):
"""Check the external authentication system for existance of email.
@return True if the user exists, False otherwise
"""
raise NotImplementedError
- def fetch_user_groups_membership(self, username, password=None):
- """Given a username, returns a dictionary of groups
+ def fetch_user_groups_membership(self, username, password):
+ """Given a username and a password, returns a dictionary of groups
and their description to which the user is subscribed.
Raise WebAccessExternalAuthError in case of troubles.
"""
raise NotImplementedError
#return {}
+ def fetch_user_nickname(self, username, password):
+ """Given a username and a password, returns the right nickname belonging
+ to that user (username could be an email).
+ """
+ raise NotImplementedError
+ #return Nickname
+
def fetch_user_preferences(self, username, password=None):
"""Given a username and a password, returns a dictionary of keys and
values, corresponding to external infos and settings.
userprefs = {"telephone": "2392489",
"address": "10th Downing Street"}
(WEBUSER WILL erase all prefs that starts by EXTERNAL_ and will
store: "EXTERNAL_telephone"; all internal preferences can use whatever
name but starting with EXTERNAL). If a pref begins with HIDDEN_ it will
be ignored.
"""
raise NotImplementedError
#return {}
def fetch_all_users_groups_membership(self):
"""Fetch all the groups with a description, and users who belong to
each groups.
@return {'mygroup': ('description', ['email1', 'email2', ...]), ...}
"""
raise NotImplementedError
diff --git a/modules/webaccess/lib/external_authentication_cern.py b/modules/webaccess/lib/external_authentication_cern.py
index c1966be4c..fe6d6e448 100644
--- a/modules/webaccess/lib/external_authentication_cern.py
+++ b/modules/webaccess/lib/external_authentication_cern.py
@@ -1,120 +1,149 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of CDS Invenio.
## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 CERN.
##
## CDS Invenio 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.
##
## CDS Invenio 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 CDS Invenio; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""External user authentication for CERN NICE/CRA Invenio."""
__revision__ = \
"$Id$"
import httplib
import socket
from invenio.external_authentication import ExternalAuth, \
WebAccessExternalAuthError
from invenio.external_authentication_cern_wrapper import AuthCernWrapper
+
+# Tunable list of settings to be hidden
+CFG_EXTERNAL_AUTH_CERN_HIDDEN_SETTINGS = ['auth', 'respccid', 'ccid']
+# Tunable list of groups to be hidden
+CFG_EXTERNAL_AUTH_CERN_HIDDEN_GROUPS = ['All Exchange People']
+
class ExternalAuthCern(ExternalAuth):
"""
External authentication example for a custom HTTPS-based
authentication service (called "CERN NICE").
"""
def __init__(self):
"""Initialize stuff here"""
ExternalAuth.__init__(self)
try:
self.connection = AuthCernWrapper()
except (httplib.CannotSendRequest, socket.error, AttributeError, IOError, TypeError): # Let the user note that no connection is available
self.connection = None
def _try_twice(self, funct, params):
"""Try twice to execute funct on self.connection passing it params.
If for various reason the connection doesn't work it's restarted
"""
try:
ret = funct(self.connection, **params)
except (httplib.CannotSendRequest, socket.error, AttributeError, IOError, TypeError):
try:
self.connection = AuthCernWrapper()
ret = funct(self.connection, **params)
except (httplib.CannotSendRequest, socket.error, AttributeError, IOError, TypeError):
self.connection = None
raise WebAccessExternalAuthError
return ret
def auth_user(self, username, password):
"""
Check USERNAME and PASSWORD against CERN NICE/CRA database.
- Return None if authentication failed, email address of the
- person if authentication succeeded.
+ Return None if authentication failed, or the email address of the
+ person if the authentication was successful. In order to do
+ this you may perhaps have to keep a translation table between
+ usernames and email addresses.
+ It can also return a tuple (actually a couple) (email, nickname).
+ If it is the first time the user logs in Invenio the nickname is
+ stored alongside the email. If this nickname is unfortunatly already
+ in use it is discarded. Otherwise it is ignored.
+ Raise WebAccessExternalAuthError in case of external troubles.
"""
infos = self._try_twice(funct=AuthCernWrapper.get_user_info, \
params={"user_name":username, "password":password})
if "email" in infos:
return infos["email"]
else:
return None
def user_exists(self, email):
"""Checks against CERN NICE/CRA for existance of email.
@return True if the user exists, False otherwise
"""
users = self._try_twice(funct=AuthCernWrapper.list_users, \
params={"display_name":email})
return email.upper() in [user['email'].upper() for user in users]
- def fetch_user_groups_membership(self, email, password=None):
+ def fetch_user_groups_membership(self, email, password):
"""Fetch user groups membership from the CERN NICE/CRA account.
@return a dictionary of groupname, group description
"""
groups = self._try_twice(funct=AuthCernWrapper.get_groups_for_user, \
params={"user_name":email})
+ # Filtering out uncomfortable groups
+ groups = [group for group in groups if group not in CFG_EXTERNAL_AUTH_CERN_HIDDEN_GROUPS]
return dict(map(lambda x: (x, '@' in x and x + ' (Mailing list)' \
or x + ' (Group)'), groups))
+ def fetch_user_nickname(self, username, password):
+ """Given a username and a password, returns the right nickname belonging
+ to that user (username could be an email).
+ """
+ infos = self._try_twice(funct=AuthCernWrapper.get_user_info, \
+ params={"user_name":username, "password":password})
+ if "login" in infos:
+ return infos["login"]
+ else:
+ return None
+
def fetch_user_preferences(self, username, password=None):
"""Fetch user preferences/settings from the CERN Nice account.
the external key will be '1' if the account is external to NICE/CRA,
otherwise 0
@return a dictionary. Note: auth and respccid are hidden
"""
prefs = self._try_twice(funct=AuthCernWrapper.get_user_info, \
params={"user_name":username, "password":password})
ret = {}
+ try:
+ if int(prefs['auth']) == 3 \
+ and (int(prefs['respccid']) > 0 \
+ or not prefs['email'].endswith('@cern.ch')):
+ ret['external'] = '1'
+ else:
+ ret['external'] = '0'
+ except KeyError:
+ ret['external'] = '1'
for key, value in prefs.items():
- if key in ['auth', 'respccid', 'ccid']:
+ if key in CFG_EXTERNAL_AUTH_CERN_HIDDEN_SETTINGS:
ret['HIDDEN_' + key] = value
else:
ret[key] = value
- if int(ret['HIDDEN_auth']) == 3 \
- and (int(ret['HIDDEN_respccid']) > 0 \
- or not ret['email'].endswith('@cern.ch')):
- ret['external'] = '1'
- else:
- ret['external'] = '0'
return ret
diff --git a/modules/websession/lib/websession_templates.py b/modules/websession/lib/websession_templates.py
index 5e727955f..4a1caae34 100644
--- a/modules/websession/lib/websession_templates.py
+++ b/modules/websession/lib/websession_templates.py
@@ -1,2041 +1,2041 @@
## $Id$
## This file is part of CDS Invenio.
## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 CERN.
##
## CDS Invenio 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.
##
## CDS Invenio 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 CDS Invenio; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
__revision__ = "$Id$"
import urllib
import time
import cgi
import gettext
import string
import locale
from invenio.config import \
CFG_CERN_SITE, \
bibformat, \
cdslang, \
cdsname, \
cdsnameintl, \
supportemail, \
sweburl, \
version, \
weburl
from invenio.messages import gettext_set_language
from invenio.textutils import indent_text
from invenio.websession_config import CFG_WEBSESSION_GROUP_JOIN_POLICY
class Template:
def tmpl_lost_password_message(self, ln, supportemail):
"""
Defines the text that will be displayed on the 'lost password' page
Parameters:
- 'ln' *string* - The language to display the interface in
- 'supportemail' *string* - The email of the support team
"""
# load the right message language
_ = gettext_set_language(ln)
return _("If you have lost password for your CDS Invenio internal account, then please enter your email address below and the lost password will be emailed to you.") +\
"
" + \
_("Note that if you have been using an external login system (such as CERN NICE), then we cannot do anything and you have to ask there.") + " " + \
_("Alternatively, you can ask %s to change your login system from external to internal.") % ("""%(email)s""" % { 'email' : supportemail }) +\
"
"
def tmpl_back_form(self, ln, message, act, link):
"""
A standard one-message-go-back-link page.
Parameters:
- 'ln' *string* - The language to display the interface in
- 'message' *string* - The message to display
- 'act' *string* - The action to accomplish when going back
- 'link' *string* - The link text
"""
out = """
"""% {
'message' : message,
'act' : act,
'link' : link
}
return out
def tmpl_external_setting(self, ln, key, value):
_ = gettext_set_language(ln)
out = """
%s:
%s
""" % (key, value)
return out
def tmpl_external_user_settings(self, ln, html_settings):
_ = gettext_set_language(ln)
out = """
%(external_user_settings)s
%(html_settings)s
%(external_user_groups)s
%(consult_external_groups)s
""" % {
'external_user_settings' : _('External account settings'),
'html_settings' : html_settings,
'consult_external_groups' : _('You can consult the list of your external groups directly in the %(x_url_open)sgroups page%(x_url_close)s.') % {
'x_url_open' : '' % ln,
'x_url_close' : ''
},
'external_user_groups' : _('External user groups'),
}
return out
def tmpl_user_preferences(self, ln, email, email_disabled, password, password_disabled, nickname):
"""
Displays a form for the user to change his email/password.
Parameters:
- 'ln' *string* - The language to display the interface in
- 'email' *string* - The email of the user
- 'email_disabled' *boolean* - If the user has the right to edit his email
- 'password' *string* - The password of the user
- 'password_disabled' *boolean* - If the user has the right to edit his password
- 'nickname' *string* - The nickname of the user (empty string if user does not have it)
"""
# load the right message language
_ = gettext_set_language(ln)
out = """
%(edit_params)s
""" % {
'change_user' : _("If you want to change your email or set for the first time your nickname, please set new values in the form below."),
'edit_params' : _("Edit login credentials"),
'nickname_label' : _("Nickname"),
'nickname' : nickname,
'nickname_prefix' : nickname=='' and ' '+_("Example")+':johnd' or '',
'new_email' : _("New email address"),
'mandatory' : _("mandatory"),
'example' : _("Example"),
'note' : _("Note"),
'set_values' : _("Set new values"),
'email' : email,
'email_disabled' : email_disabled and "readonly" or "",
'sweburl': sweburl,
}
if not password_disabled:
out += """
""" % {
'change_pass' : _("If you want to change your password, please fill in the old one and set new values in the form below."),
'mandatory' : _("mandatory"),
'old_password' : _("Old password"),
'new_password' : _("New password"),
'optional' : _("optional"),
'note' : _("Note"),
'password_note' : _("The password phrase may contain punctuation, spaces, etc."),
'old_password_note' : _("You must fill the old password in order to set a new one."),
'retype_password' : _("Retype password"),
'set_values' : _("Set new password"),
'password' : password,
'password_disabled' : password_disabled and "disabled" or "",
'sweburl': sweburl,
}
return out
def tmpl_user_websearch_edit(self, ln, current = 10, show_latestbox = True, show_helpbox = True):
_ = gettext_set_language(ln)
out = """
""" % {
'update_settings' : _("Update settings"),
'select_group_records' : _("Number of search results per page"),
}
return out
def tmpl_user_external_auth(self, ln, methods, current, method_disabled):
"""
Displays a form for the user to change his authentication method.
Parameters:
- 'ln' *string* - The language to display the interface in
- 'methods' *array* - The methods of authentication
- 'method_disabled' *boolean* - If the user has the right to change this
- 'current' *string* - The currently selected method
"""
# load the right message language
_ = gettext_set_language(ln)
out = """
""" % {
'select_method' : _("Select method"),
}
return out
def tmpl_lost_password_form(self, ln, msg):
"""
Displays a form for the user to ask for his password sent by email.
Parameters:
- 'ln' *string* - The language to display the interface in
- 'msg' *string* - Explicative message on top of the form.
"""
# load the right message language
_ = gettext_set_language(ln)
out = """
""" % {
'msg' : msg,
'ln': ln,
'email' : _("Email address"),
'send' : _("Send lost password"),
}
return out
def tmpl_account_info(self, ln, uid, guest, CFG_CERN_SITE):
"""
Displays the account information
Parameters:
- 'ln' *string* - The language to display the interface in
- 'uid' *string* - The user id
- 'guest' *boolean* - If the user is guest
- 'CFG_CERN_SITE' *boolean* - If the site is a CERN site
"""
# load the right message language
_ = gettext_set_language(ln)
out = """
%(account_offer)s
""" % {
'account_offer' : _("%s offers you the possibility to personalize the interface, to set up your own personal library of documents, or to set up an automatic alert query that would run periodically and would notify you of search results by email.") % cdsnameintl[ln],
}
if not guest:
out += """
%(change_account)s""" % {
'ln' : ln,
'your_settings' : _("Your Settings"),
'change_account' : _("Set or change your account email address or password. Specify your preferences about the look and feel of the interface.")
}
out += """
%(basket_explain)s""" % {
'ln' : ln,
'your_searches' : _("Your Searches"),
'search_explain' : _("View all the searches you performed during the last 30 days."),
'your_baskets' : _("Your Baskets"),
'basket_explain' : _("With baskets you can define specific collections of items, store interesting records you want to access later or share with others."),
}
if guest:
out += self.tmpl_warning_guest_user(ln = ln, type = "baskets")
out += """
%(explain_alerts)s""" % {
'ln' : ln,
'your_alerts' : _("Your Alerts"),
'explain_alerts' : _("Subscribe to a search which will be run periodically by our service. The result can be sent to you via Email or stored in one of your baskets."),
}
if guest:
out += self.tmpl_warning_guest_user(type="alerts", ln = ln)
if CFG_CERN_SITE:
out += """
%(explain_loans)s""" % {
'your_loans' : _("Your Loans"),
'explain_loans' : _("Check out book you have on loan, submit borrowing requests, etc. Requires CERN ID."),
}
out += """
"""
return out
def tmpl_warning_guest_user(self, ln, type):
"""
Displays a warning message about the specified type
Parameters:
- 'ln' *string* - The language to display the interface in
- 'type' *string* - The type of data that will get lost in case of guest account (for the moment: 'alerts' or 'baskets')
"""
# load the right message language
_ = gettext_set_language(ln)
if (type=='baskets'):
msg = _("You are logged in as a guest user, so your baskets will disappear at the end of the current session.") + ' '
elif (type=='alerts'):
msg = _("You are logged in as a guest user, so your alerts will disappear at the end of the current session.") + ' '
msg += _("If you wish you can %(x_url_open)slogin or register here%(x_url_close)s.") % {'x_url_open': '',
'x_url_close': ''}
return """
%s
""" % msg
def tmpl_account_body(self, ln, user):
"""
Displays the body of the actions of the user
Parameters:
- 'ln' *string* - The language to display the interface in
- 'user' *string* - The username (nickname or email)
"""
# load the right message language
_ = gettext_set_language(ln)
out = _("You are logged in as %(x_user)s. You may want to a) %(x_url1_open)slogout%(x_url1_close)s; b) edit your %(x_url2_open)saccount settings%(x_url2_close)s.") %\
{'x_user': user,
'x_url1_open': '',
'x_url1_close': '',
'x_url2_open': '',
'x_url2_close': '',
}
return out + "
"
def tmpl_account_template(self, title, body, ln):
"""
Displays a block of the your account page
Parameters:
- 'ln' *string* - The language to display the interface in
- 'title' *string* - The title of the block
- 'body' *string* - The body of the block
"""
out =""
out +="""
%s
%s
""" % (title, body)
return out
def tmpl_account_page(self, ln, weburl, accBody, baskets, alerts, searches, messages, groups, administrative):
"""
Displays the your account page
Parameters:
- 'ln' *string* - The language to display the interface in
- 'weburl' *string* - The URL of CDS Invenio
- 'accBody' *string* - The body of the heading block
- 'baskets' *string* - The body of the baskets block
- 'alerts' *string* - The body of the alerts block
- 'searches' *string* - The body of the searches block
- 'messages' *string* - The body of the messages block
- 'groups' *string* - The body of the groups block
- 'administrative' *string* - The body of the administrative block
"""
# load the right message language
_ = gettext_set_language(ln)
out = ""
out += self.tmpl_account_template(_("Your Account"), accBody, ln)
out += self.tmpl_account_template(_("Your Messages"), messages, ln)
out += self.tmpl_account_template(_("Your Baskets"), baskets, ln)
out += self.tmpl_account_template(_("Your Alert Searches"), alerts, ln)
out += self.tmpl_account_template(_("Your Searches"), searches, ln)
groups_description = _("You can consult the list of %(x_url_open)syour groups%(x_url_close)s you are administering or are a member of.")
groups_description %= {'x_url_open': '',
'x_url_close': ''}
out += self.tmpl_account_template(_("Your Groups"), groups_description, ln)
submission_description = _("You can consult the list of %(x_url_open)syour submissions%(x_url_close)s and inquire about their status.")
submission_description %= {'x_url_open': '',
'x_url_close': ''}
out += self.tmpl_account_template(_("Your Submissions"), submission_description, ln)
approval_description = _("You can consult the list of %(x_url_open)syour approvals%(x_url_close)s with the documents you approved or refereed.")
approval_description %= {'x_url_open': '',
'x_url_close': ''}
out += self.tmpl_account_template(_("Your Approvals"), approval_description, ln)
out += self.tmpl_account_template(_("Your Administrative Activities"), administrative, ln)
return out
def tmpl_account_emailMessage(self, ln, msg):
"""
Displays a link to retrieve the lost password
Parameters:
- 'ln' *string* - The language to display the interface in
- 'msg' *string* - Explicative message on top of the form.
"""
# load the right message language
_ = gettext_set_language(ln)
out =""
out +="""
%(msg)s %(try_again)s
""" % {
'ln' : ln,
'msg' : msg,
'try_again' : _("Try again")
}
return out
def tmpl_account_lost_password_email_body(self, username, password, ln=cdslang):
"""
The body of the email that sends lost internal account
passwords to users.
"""
_ = gettext_set_language(ln)
out = """\
%(hello)s:
%(here_are_your_user_credentials_for)s %(cdsnameintl)s:
%(label_username)s: %(username)s
%(label_password)s: %(password)s
%(you_can_login_at)s:
<%(login_url)s>
%(best_regards)s
--
%(cdsnameintl)s <%(weburl)s>
%(need_intervention_please_contact)s <%(supportemail)s>
""" % {
'hello': _("Hello"),
'here_are_your_user_credentials_for': _("Here are your user credentials for"),
'cdsnameintl': cdsnameintl[ln],
'label_username': _("username"),
'username': username,
'label_password': _("password"),
'password': password,
'you_can_login_at': _("You can login at"),
'login_url': "%s/youraccount/login?ln=%s" % (sweburl, ln),
'best_regards': _("Best regards"),
'weburl': weburl,
'need_intervention_please_contact': _("Need human intervention? Contact"),
'supportemail': supportemail
}
return out
def tmpl_account_emailSent(self, ln, email):
"""
Displays a confirmation message for an email sent
Parameters:
- 'ln' *string* - The language to display the interface in
- 'email' *string* - The email to which the message has been sent
"""
# load the right message language
_ = gettext_set_language(ln)
out =""
out += _("Okay, password has been emailed to %s.") % email
return out
def tmpl_account_delete(self, ln):
"""
Displays a confirmation message about deleting the account
Parameters:
- 'ln' *string* - The language to display the interface in
"""
# load the right message language
_ = gettext_set_language(ln)
out = "
" + _("""Deleting your account""")
return out
def tmpl_account_logout(self, ln):
"""
Displays a confirmation message about logging out
Parameters:
- 'ln' *string* - The language to display the interface in
"""
# load the right message language
_ = gettext_set_language(ln)
out = _("You are no longer recognized.") + ' '
out += _("If you wish you can %(x_url_open)slogin here%(x_url_close)s.") % {'x_url_open': '',
'x_url_close': ''}
return out
def tmpl_login_form(self, ln, referer, internal, register_available, methods, selected_method, supportemail):
"""
Displays a login form
Parameters:
- 'ln' *string* - The language to display the interface in
- 'referer' *string* - The referer URL - will be redirected upon after login
- 'internal' *boolean* - If we are producing an internal authentication
- 'register_available' *boolean* - If users can register freely in the system
- 'methods' *array* - The available authentication methods
- 'selected_method' *string* - The default authentication method
- 'supportemail' *string* - The email of the support team
"""
# load the right message language
_ = gettext_set_language(ln)
out = "
%(please_login)s " % {
'please_login' : _("If you already have an account, please login using the form below.")
}
if register_available:
out += _("If you don't own an account yet, please %(x_url_open)sregister%(x_url_close)s an internal account.") %\
{'x_url_open': '',
'x_url_close': ''}
else:
out += _("It is not possible to create an account yourself. Contact %s if you want an account.") % ('%s' % (supportemail, supportemail))
out += """
"""
out += """
%(note)s: %(note_text)s""" % {
'note' : _("Note"),
'note_text': _("You can use your nickname or your email address to login.")}
return out
def tmpl_lost_your_password_teaser(self, ln=cdslang):
"""Displays a short sentence to attract user to the fact that
maybe he lost his password. Used by the registration page.
"""
_ = gettext_set_language(ln)
out = ""
out += """%(maybe_lost_pass)s""" % {
'ln' : ln,
'maybe_lost_pass': ("Maybe you have lost your password?")
}
return out
def tmpl_register_page(self, ln, referer, level, supportemail, cdsname):
"""
Displays a login form
Parameters:
- 'ln' *string* - The language to display the interface in
- 'referer' *string* - The referer URL - will be redirected upon after login
- 'level' *int* - Login level (0 - all access, 1 - accounts activated, 2+ - no self-registration)
- 'supportemail' *string* - The email of the support team
- 'cdsname' *string* - The name of the installation
"""
# load the right message language
_ = gettext_set_language(ln)
out = ""
if level <= 1:
out += _("Please enter your email address and desired nickname and password:")
if level == 1:
out += _("It will not be possible to use the account before it has been verified and activated.")
out += """
%(label)s
%(name_label)s
%(description_label)s
%(join_policy_label)s
%(join_policy)s
%(hidden_id)s
%(delete_text)s
"""
out %= {'action' : action,
'logo': weburl + '/img/webbasket_create.png',
'label': label,
'form_name' : form_name,
'name_label': _("Group name:"),
'delete_text': delete_text,
'description_label': _("Group description:"),
'join_policy_label': _("Group join policy:"),
'group_name': cgi.escape(group_name, 1),
'group_description': cgi.escape(group_description, 1),
'button_label': button_label,
'button_name':button_name,
'cancel_label':_("Cancel"),
'hidden_id':hidden_id,
'ln': ln,
'join_policy' :self.__create_join_policy_selection_menu("join_policy",
join_policy,
ln)
}
return indent_text(out, 2)
def tmpl_display_input_join_group(self,
group_list,
group_name,
group_from_search,
search,
warnings=[],
ln=cdslang):
"""
Display the groups the user can join.
He can use default select list or the search box
Parameters:
- 'ln' *string* - The language to display the interface in
- 'group_list' *list* - All the group the user can join
- 'group_name' *string* - Name of the group the user is looking for
- 'group_from search' *list* - List of the group the user can join matching group_name
- 'search' *int* - User is looking for group using group_name
- 'warnings' *list* - Display warning if two group are selected
"""
_ = gettext_set_language(ln)
out = self.tmpl_warning(warnings)
search_content = ""
if search:
search_content = """
"""
out %= {'action' : weburl + '/yourgroups/join',
'logo': weburl + '/img/webbasket_create.png',
'label': _("Join group"),
'group_name': cgi.escape(group_name, 1),
'label2':_("or find it") + ': ',
'list_label':_("Choose group:"),
'ln': ln,
'find_label': _("Find group"),
'cancel_label':_("Cancel"),
'group_list' :self.__create_select_menu("grpID",group_list, _("Please select:")),
'search_content' : search_content
}
return indent_text(out, 2)
def tmpl_display_manage_member(self,
grpID,
group_name,
members,
pending_members,
infos=[],
warnings=[],
ln=cdslang):
"""Display current members and waiting members of a group.
Parameters:
- 'ln' *string* - The language to display the interface in
- 'grpID *string* - ID of the group
- 'group_name' *string* - Name of the group
- 'members' *list* - List of the current members
- 'pending_members' *list* - List of the waiting members
- 'infos' *tuple of 2 lists* - Message to inform user about his last action
- 'warnings' *list* - Display warning if two group are selected
"""
_ = gettext_set_language(ln)
out = self.tmpl_warning(warnings)
out += self.tmpl_infobox(infos)
out += """
%(title)s
%(header1)s
%(member_text)s
%(header2)s
%(pending_text)s
%(header3)s
%(invite_text)s
"""
if members :
member_list = self.__create_select_menu("member_id", members, _("Please select:"))
member_text = """
""" % _("No members awaiting approval.")
header1 = self.tmpl_group_table_title(text=_("Current members"))
header2 = self.tmpl_group_table_title(text=_("Members awaiting approval"))
header3 = _("Invite new members")
link_open = ''
link_open %= (weburl, ln)
invite_text = _("If you want to invite new members to join your group, please use the %(x_url_open)sweb message%(x_url_close)s system.") % \
{'x_url_open': link_open,
'x_url_close': ''}
action = weburl + '/yourgroups/members?ln=' + ln
out %= {'title':_('Group: %s') % group_name,
'member_text' : member_text,
'pending_text' :pending_text,
'action':action,
'grpID':grpID,
'header1': header1,
'header2': header2,
'header3': header3,
'invite_text': invite_text,
'imgurl': weburl + '/img',
'cancel_label':_("Cancel"),
'ln':ln
}
return indent_text(out, 2)
def tmpl_display_input_leave_group(self,
groups,
warnings=[],
ln=cdslang):
"""Display groups the user can leave.
Parameters:
- 'ln' *string* - The language to display the interface in
- 'groups' *list* - List of groups the user is currently member of
- 'warnings' *list* - Display warning if no group is selected
"""
_ = gettext_set_language(ln)
out = self.tmpl_warning(warnings)
out += """
%(label)s
%(list_label)s
%(groups)s
%(submit)s
"""
if groups:
groups = self.__create_select_menu("grpID", groups, _("Please select:"))
list_label = _("Group list")
submit = """""" % _("Leave group")
else :
groups = _("You are not member of any group.")
list_label = ""
submit = ""
action = weburl + '/yourgroups/leave?ln=%s'
action %= (ln)
out %= {'groups' : groups,
'list_label' : list_label,
'action':action,
'logo': weburl + '/img/webbasket_create.png',
'label' : _("Leave group"),
'cancel_label':_("Cancel"),
'ln' :ln,
'submit' : submit
}
return indent_text(out, 2)
def tmpl_confirm_delete(self, grpID, ln=cdslang):
"""
display a confirm message when deleting a group
@param ln: language
@return html output
"""
_ = gettext_set_language(ln)
action = weburl + '/yourgroups/edit'
out = """
%(message)s
"""% {'message': _("Are you sure you want to delete this group?"),
'ln':ln,
'yes_label': _("Yes"),
'no_label': _("No"),
'grpID':grpID,
'action': action
}
return indent_text(out, 2)
def tmpl_confirm_leave(self, uid, grpID, ln=cdslang):
"""
display a confirm message
@param ln: language
@return html output
"""
_ = gettext_set_language(ln)
action = weburl + '/yourgroups/leave'
out = """
%(message)s
"""% {'message': _("Are you sure you want to leave this group?"),
'ln':ln,
'yes_label': _("Yes"),
'no_label': _("No"),
'grpID':grpID,
'action': action
}
return indent_text(out, 2)
def __create_join_policy_selection_menu(self, name, current_join_policy, ln=cdslang):
"""Private function. create a drop down menu for selection of join policy
@param current_join_policy: join policy as defined in CFG_WEBSESSION_GROUP_JOIN_POLICY
@param ln: language
"""
_ = gettext_set_language(ln)
elements = [(CFG_WEBSESSION_GROUP_JOIN_POLICY['VISIBLEOPEN'],
_("Visible and open for new members")),
(CFG_WEBSESSION_GROUP_JOIN_POLICY['VISIBLEMAIL'],
_("Visible but new members need approval"))
]
select_text = _("Please select:")
return self.__create_select_menu(name, elements, select_text, selected_key=current_join_policy)
def __create_select_menu(self, name, elements, select_text, multiple=0, selected_key=None):
""" private function, returns a popup menu
@param name: name of HTML control
@param elements: list of (key, value)
"""
if multiple :
out = """