Import initial des fichiers de la version 1.5.3 de MoinMoin (mj Etch).
darcs-hash:20070601130042-68412-6e583291d0079b28e4c0cc18a7c8428051d37cb0.gz
This commit is contained in:
parent
7d86a17433
commit
329eea2862
4 changed files with 1730 additions and 1165 deletions
1541
wiki/request.py
1541
wiki/request.py
File diff suppressed because it is too large
Load diff
653
wiki/user.py
653
wiki/user.py
|
@ -6,7 +6,7 @@
|
|||
@license: GNU GPL, see COPYING for details.
|
||||
"""
|
||||
|
||||
import os, string, time, Cookie, sha, codecs
|
||||
import os, time, sha, codecs
|
||||
|
||||
try:
|
||||
import cPickle as pickle
|
||||
|
@ -14,16 +14,10 @@ except ImportError:
|
|||
import pickle
|
||||
|
||||
# Set pickle protocol, see http://docs.python.org/lib/node64.html
|
||||
try:
|
||||
# Requires 2.3
|
||||
PICKLE_PROTOCOL = pickle.HIGHEST_PROTOCOL
|
||||
except AttributeError:
|
||||
# Use protocol 1, binary format compatible with all python versions
|
||||
PICKLE_PROTOCOL = 1
|
||||
|
||||
PICKLE_PROTOCOL = pickle.HIGHEST_PROTOCOL
|
||||
|
||||
from MoinMoin import config, caching, wikiutil
|
||||
from MoinMoin.util import datetime
|
||||
from MoinMoin.util import filesys, timefuncs
|
||||
|
||||
|
||||
def getUserList(request):
|
||||
|
@ -36,9 +30,10 @@ def getUserList(request):
|
|||
import re, dircache
|
||||
user_re = re.compile(r'^\d+\.\d+(\.\d+)?$')
|
||||
files = dircache.listdir(request.cfg.user_dir)
|
||||
userlist = filter(user_re.match, files)
|
||||
userlist = [f for f in files if user_re.match(f)]
|
||||
return userlist
|
||||
|
||||
|
||||
def getUserId(request, searchName):
|
||||
"""
|
||||
Get the user ID for a specific user NAME.
|
||||
|
@ -74,6 +69,7 @@ def getUserId(request, searchName):
|
|||
id = _name2id.get(searchName, None)
|
||||
return id
|
||||
|
||||
|
||||
def getUserIdentification(request, username=None):
|
||||
"""
|
||||
Return user name or IP or '<unknown>' indicator.
|
||||
|
@ -96,7 +92,7 @@ def encodePassword(pwd, charset='utf-8'):
|
|||
|
||||
Compatible to Apache htpasswd SHA encoding.
|
||||
|
||||
When using different encoding then 'utf-8', the encoding might fail
|
||||
When using different encoding than 'utf-8', the encoding might fail
|
||||
and raise UnicodeError.
|
||||
|
||||
@param pwd: the cleartext password, (unicode)
|
||||
|
@ -116,6 +112,7 @@ def encodePassword(pwd, charset='utf-8'):
|
|||
pwd = '{SHA}' + base64.encodestring(pwd).rstrip()
|
||||
return pwd
|
||||
|
||||
|
||||
def normalizeName(name):
|
||||
""" Make normalized user name
|
||||
|
||||
|
@ -132,8 +129,11 @@ def normalizeName(name):
|
|||
@rtype: unicode
|
||||
@return: user name that can be used in acl lines
|
||||
"""
|
||||
# Strip non alpha numeric characters, keep white space
|
||||
name = ''.join([c for c in name if c.isalnum() or c.isspace()])
|
||||
name = name.replace('_', ' ') # we treat _ as a blank
|
||||
username_allowedchars = "'@." # ' for names like O'Brian or email addresses.
|
||||
# "," and ":" must not be allowed (ACL delimiters).
|
||||
# Strip non alpha numeric characters (except username_allowedchars), keep white space
|
||||
name = ''.join([c for c in name if c.isalnum() or c.isspace() or c in username_allowedchars])
|
||||
|
||||
# Normalize white space. Each name can contain multiple
|
||||
# words separated with only one space.
|
||||
|
@ -148,6 +148,7 @@ def isValidName(request, name):
|
|||
@param name: user name, unicode
|
||||
"""
|
||||
normalized = normalizeName(name)
|
||||
name = name.replace('_', ' ') # we treat _ as a blank
|
||||
return (name == normalized) and not wikiutil.isGroupPage(request, name)
|
||||
|
||||
|
||||
|
@ -190,42 +191,44 @@ def decodeList(line):
|
|||
class User:
|
||||
"""A MoinMoin User"""
|
||||
|
||||
_checkbox_fields = [
|
||||
('edit_on_doubleclick', lambda _: _('Open editor on double click')),
|
||||
('remember_last_visit', lambda _: _('Remember last page visited')),
|
||||
('show_fancy_links', lambda _: _('Show fancy links')),
|
||||
('show_nonexist_qm', lambda _: _('Show question mark for non-existing pagelinks')),
|
||||
('show_page_trail', lambda _: _('Show page trail')),
|
||||
('show_toolbar', lambda _: _('Show icon toolbar')),
|
||||
('show_topbottom', lambda _: _('Show top/bottom links in headings')),
|
||||
('show_fancy_diff', lambda _: _('Show fancy diffs')),
|
||||
('wikiname_add_spaces', lambda _: _('Add spaces to displayed wiki names')),
|
||||
('remember_me', lambda _: _('Remember login information')),
|
||||
('want_trivial', lambda _: _('Subscribe to trivial changes')),
|
||||
('disabled', lambda _: _('Disable this account forever')),
|
||||
]
|
||||
_transient_fields = ['id', 'valid', 'may', 'auth_username', 'trusted']
|
||||
|
||||
def __init__(self, request, id=None, name="", password=None, auth_username=""):
|
||||
"""
|
||||
Initialize user object
|
||||
def __init__(self, request, id=None, name="", password=None, auth_username="", **kw):
|
||||
""" Initialize User object
|
||||
|
||||
@param request: the request object
|
||||
@param id: (optional) user ID
|
||||
@param name: (optional) user name
|
||||
@param password: (optional) user password
|
||||
@param auth_username: (optional) already authenticated user name (e.g. apache basic auth)
|
||||
@param auth_username: (optional) already authenticated user name
|
||||
(e.g. when using http basic auth)
|
||||
@keyword auth_method: method that was used for authentication,
|
||||
default: 'internal'
|
||||
@keyword auth_attribs: tuple of user object attribute names that are
|
||||
determined by auth method and should not be
|
||||
changed by UserPreferences form, default: ().
|
||||
First tuple element was used for authentication.
|
||||
"""
|
||||
self._cfg = request.cfg
|
||||
self.valid = 0
|
||||
self.trusted = 0
|
||||
self.id = id
|
||||
if auth_username:
|
||||
self.auth_username = auth_username
|
||||
elif request:
|
||||
self.auth_username = request.auth_username
|
||||
else:
|
||||
self.auth_username = ""
|
||||
self.name = name
|
||||
self.auth_username = auth_username
|
||||
self.auth_method = kw.get('auth_method', 'internal')
|
||||
self.auth_attribs = kw.get('auth_attribs', ())
|
||||
|
||||
# create some vars automatically
|
||||
for tuple in self._cfg.user_form_fields:
|
||||
key = tuple[0]
|
||||
default = self._cfg.user_form_defaults.get(key, '')
|
||||
setattr(self, key, default)
|
||||
|
||||
if name:
|
||||
self.name = name
|
||||
elif auth_username: # this is needed for user_autocreate
|
||||
self.name = auth_username
|
||||
|
||||
# create checkbox fields (with default 0)
|
||||
for key, label in self._cfg.user_checkbox_fields:
|
||||
setattr(self, key, self._cfg.user_checkbox_defaults.get(key, 0))
|
||||
|
||||
self.enc_password = ""
|
||||
if password:
|
||||
|
@ -237,68 +240,40 @@ class User:
|
|||
except UnicodeError:
|
||||
pass # Should never happen
|
||||
|
||||
self.trusted = 0
|
||||
self.email = ""
|
||||
self.edit_rows = self._cfg.edit_rows
|
||||
#self.edit_cols = 80
|
||||
self.tz_offset = int(float(self._cfg.tz_offset) * 3600)
|
||||
self.last_saved = str(time.time())
|
||||
self.css_url = ""
|
||||
self.language = ""
|
||||
self.quicklinks = []
|
||||
self.date_fmt = ""
|
||||
self.datetime_fmt = ""
|
||||
self.quicklinks = []
|
||||
self.subscribed_pages = []
|
||||
self.theme_name = self._cfg.theme_default
|
||||
|
||||
# if an account is disabled, it may be used for looking up
|
||||
# id -> username for page info and recent changes, but it
|
||||
# is not usable for the user any more:
|
||||
# self.disabled = 0
|
||||
# is handled by checkbox now.
|
||||
self.editor_default = self._cfg.editor_default
|
||||
self.editor_ui = self._cfg.editor_ui
|
||||
self.last_saved = str(time.time())
|
||||
|
||||
# attrs not saved to profile
|
||||
self._request = request
|
||||
self._trail = []
|
||||
|
||||
# create checkbox fields (with default 0)
|
||||
for key, label in self._checkbox_fields:
|
||||
setattr(self, key, 0)
|
||||
self.wikiname_add_spaces = 1
|
||||
self.show_page_trail = 1
|
||||
self.show_fancy_links = 1
|
||||
#self.show_emoticons = 1
|
||||
self.show_toolbar = 1
|
||||
self.show_nonexist_qm = self._cfg.nonexist_qm
|
||||
self.show_fancy_diff = 1
|
||||
self.want_trivial = 0
|
||||
self.remember_me = 1
|
||||
|
||||
if not self.id and not self.auth_username:
|
||||
try:
|
||||
cookie = Cookie.SimpleCookie(request.saved_cookie)
|
||||
except Cookie.CookieError:
|
||||
# ignore invalid cookies, else user can't re login
|
||||
cookie = None
|
||||
if cookie and cookie.has_key('MOIN_ID'):
|
||||
self.id = cookie['MOIN_ID'].value
|
||||
|
||||
# we got an already authenticated username:
|
||||
check_pass = 0
|
||||
if not self.id and self.auth_username:
|
||||
self.id = getUserId(request, self.auth_username)
|
||||
|
||||
if not password is None:
|
||||
check_pass = 1
|
||||
if self.id:
|
||||
self.load_from_id()
|
||||
self.load_from_id(check_pass)
|
||||
if self.name == self.auth_username:
|
||||
self.trusted = 1
|
||||
elif self.name:
|
||||
self.load()
|
||||
self.id = getUserId(self._request, self.name)
|
||||
if self.id:
|
||||
self.load_from_id(1)
|
||||
else:
|
||||
self.id = self.make_id()
|
||||
else:
|
||||
#!!! this should probably be a hash of REMOTE_ADDR, HTTP_USER_AGENT
|
||||
# and some other things identifying remote users, then we could also
|
||||
# use it reliably in edit locking
|
||||
from random import randint
|
||||
self.id = "%s.%d" % (str(time.time()), randint(0,65535))
|
||||
self.id = self.make_id()
|
||||
|
||||
# "may" so we can say "if user.may.read(pagename):"
|
||||
if self._cfg.SecurityPolicy:
|
||||
|
@ -311,40 +286,53 @@ class User:
|
|||
if self.language and not languages.has_key(self.language):
|
||||
self.language = 'en'
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s.%s at 0x%x name:%r id:%s valid:%r>" % (
|
||||
self.__class__.__module__, self.__class__.__name__,
|
||||
id(self), self.name, self.id, self.valid)
|
||||
|
||||
def make_id(self):
|
||||
""" make a new unique user id """
|
||||
#!!! this should probably be a hash of REMOTE_ADDR, HTTP_USER_AGENT
|
||||
# and some other things identifying remote users, then we could also
|
||||
# use it reliably in edit locking
|
||||
from random import randint
|
||||
return "%s.%d" % (str(time.time()), randint(0,65535))
|
||||
|
||||
def create_or_update(self, changed=False):
|
||||
""" Create or update a user profile
|
||||
|
||||
@param changed: bool, set this to True if you updated the user profile values
|
||||
"""
|
||||
if self._cfg.user_autocreate:
|
||||
if not self.valid and not self.disabled or changed: # do we need to save/update?
|
||||
self.save() # yes, create/update user profile
|
||||
|
||||
def __filename(self):
|
||||
"""
|
||||
get filename of the user's file on disk
|
||||
""" Get filename of the user's file on disk
|
||||
|
||||
@rtype: string
|
||||
@return: full path and filename of user account file
|
||||
"""
|
||||
return os.path.join(self._cfg.user_dir, self.id or "...NONE...")
|
||||
|
||||
def __bookmark_filename(self):
|
||||
if self._cfg.interwikiname:
|
||||
return (self.__filename() + "." + self._cfg.interwikiname +
|
||||
".bookmark")
|
||||
else:
|
||||
return self.__filename() + ".bookmark"
|
||||
|
||||
def exists(self):
|
||||
"""
|
||||
Do we have a user account for this user?
|
||||
""" Do we have a user account for this user?
|
||||
|
||||
@rtype: bool
|
||||
@return: true, if we have a user account
|
||||
"""
|
||||
return os.path.exists(self.__filename())
|
||||
|
||||
|
||||
def load(self):
|
||||
"""
|
||||
Lookup user ID by user name and load user account.
|
||||
|
||||
Can load user data if the user name is known, but only if the password is set correctly.
|
||||
"""
|
||||
self.id = getUserId(self._request, self.name)
|
||||
if self.id:
|
||||
self.load_from_id(1)
|
||||
#print >>sys.stderr, "self.id: %s, self.name: %s" % (self.id, self.name)
|
||||
|
||||
def load_from_id(self, check_pass=0):
|
||||
"""
|
||||
Load user account data from disk.
|
||||
""" Load user account data from disk.
|
||||
|
||||
Can only load user data if the id number is already known.
|
||||
|
||||
|
@ -354,7 +342,8 @@ class User:
|
|||
@param check_pass: If 1, then self.enc_password must match the
|
||||
password in the user account file.
|
||||
"""
|
||||
if not self.exists(): return
|
||||
if not self.exists():
|
||||
return
|
||||
|
||||
data = codecs.open(self.__filename(), "r", config.charset).readlines()
|
||||
user_data = {'enc_password': ''}
|
||||
|
@ -364,7 +353,7 @@ class User:
|
|||
|
||||
try:
|
||||
key, val = line.strip().split('=', 1)
|
||||
if key not in self._transient_fields and key[0] != '_':
|
||||
if key not in self._cfg.user_transient_fields and key[0] != '_':
|
||||
# Decode list values
|
||||
if key in ['quicklinks', 'subscribed_pages']:
|
||||
val = decodeList(val)
|
||||
|
@ -387,6 +376,11 @@ class User:
|
|||
else:
|
||||
self.trusted = 1
|
||||
|
||||
# Remove ignored checkbox values from user data
|
||||
for key, label in self._cfg.user_checkbox_fields:
|
||||
if user_data.has_key(key) and key in self._cfg.user_checkbox_disable:
|
||||
del user_data[key]
|
||||
|
||||
# Copy user data into user object
|
||||
for key, val in user_data.items():
|
||||
vars(self)[key] = val
|
||||
|
@ -394,14 +388,14 @@ class User:
|
|||
self.tz_offset = int(self.tz_offset)
|
||||
|
||||
# Remove old unsupported attributes from user data file.
|
||||
remove_attributes = ['password', 'passwd', 'show_emoticons']
|
||||
remove_attributes = ['passwd', 'show_emoticons']
|
||||
for attr in remove_attributes:
|
||||
if hasattr(self, attr):
|
||||
delattr(self, attr)
|
||||
changed = 1
|
||||
|
||||
# make sure checkboxes are boolean
|
||||
for key, label in self._checkbox_fields:
|
||||
for key, label in self._cfg.user_checkbox_fields:
|
||||
try:
|
||||
setattr(self, key, int(getattr(self, key)))
|
||||
except ValueError:
|
||||
|
@ -467,7 +461,6 @@ class User:
|
|||
return False, False
|
||||
|
||||
# First get all available pre13 charsets on this system
|
||||
import codecs
|
||||
pre13 = ['iso-8859-1', 'iso-8859-2', 'euc-jp', 'gb2312', 'big5',]
|
||||
available = []
|
||||
for charset in pre13:
|
||||
|
@ -496,8 +489,7 @@ class User:
|
|||
return False, False
|
||||
|
||||
def save(self):
|
||||
"""
|
||||
Save user account data to user account file on disk.
|
||||
""" Save user account data to user account file on disk.
|
||||
|
||||
This saves all member variables, except "id" and "valid" and
|
||||
those starting with an underscore.
|
||||
|
@ -506,9 +498,7 @@ class User:
|
|||
return
|
||||
|
||||
user_dir = self._cfg.user_dir
|
||||
if not os.path.isdir(user_dir):
|
||||
os.mkdir(user_dir, 0777 & config.umask)
|
||||
os.chmod(user_dir, 0777 & config.umask)
|
||||
filesys.makeDirs(user_dir)
|
||||
|
||||
self.last_saved = str(time.time())
|
||||
|
||||
|
@ -522,7 +512,7 @@ class User:
|
|||
attrs = vars(self).items()
|
||||
attrs.sort()
|
||||
for key, value in attrs:
|
||||
if key not in self._transient_fields and key[0] != '_':
|
||||
if key not in self._cfg.user_transient_fields and key[0] != '_':
|
||||
# Encode list values
|
||||
if key in ['quicklinks', 'subscribed_pages']:
|
||||
value = encodeList(value)
|
||||
|
@ -538,20 +528,21 @@ class User:
|
|||
if not self.disabled:
|
||||
self.valid = 1
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Time and date formatting
|
||||
|
||||
def getTime(self, tm):
|
||||
"""
|
||||
Get time in user's timezone.
|
||||
""" Get time in user's timezone.
|
||||
|
||||
@param tm: time (UTC UNIX timestamp)
|
||||
@rtype: int
|
||||
@return: tm tuple adjusted for user's timezone
|
||||
"""
|
||||
return datetime.tmtuple(tm + self.tz_offset)
|
||||
return timefuncs.tmtuple(tm + self.tz_offset)
|
||||
|
||||
|
||||
def getFormattedDate(self, tm):
|
||||
"""
|
||||
Get formatted date adjusted for user's timezone.
|
||||
""" Get formatted date adjusted for user's timezone.
|
||||
|
||||
@param tm: time (UTC UNIX timestamp)
|
||||
@rtype: string
|
||||
|
@ -562,8 +553,7 @@ class User:
|
|||
|
||||
|
||||
def getFormattedDateTime(self, tm):
|
||||
"""
|
||||
Get formatted date and time adjusted for user's timezone.
|
||||
""" Get formatted date and time adjusted for user's timezone.
|
||||
|
||||
@param tm: time (UTC UNIX timestamp)
|
||||
@rtype: string
|
||||
|
@ -572,69 +562,58 @@ class User:
|
|||
datetime_fmt = self.datetime_fmt or self._cfg.datetime_fmt
|
||||
return time.strftime(datetime_fmt, self.getTime(tm))
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Bookmark
|
||||
|
||||
def setBookmark(self, tm=None):
|
||||
"""
|
||||
Set bookmark timestamp.
|
||||
def setBookmark(self, tm):
|
||||
""" Set bookmark timestamp.
|
||||
|
||||
@param tm: time (UTC UNIX timestamp), default: current time
|
||||
@param tm: timestamp
|
||||
"""
|
||||
if self.valid:
|
||||
if tm is None:
|
||||
tm = time.time()
|
||||
bmfile = open(self.__filename() + ".bookmark", "w")
|
||||
bm_fn = self.__bookmark_filename()
|
||||
bmfile = open(bm_fn, "w")
|
||||
bmfile.write(str(tm)+"\n")
|
||||
bmfile.close()
|
||||
try:
|
||||
os.chmod(self.__filename() + ".bookmark", 0666 & config.umask)
|
||||
os.chmod(bm_fn, 0666 & config.umask)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
# XXX Do we need that???
|
||||
#try:
|
||||
# os.utime(self.__filename() + ".bookmark", (tm, tm))
|
||||
#except OSError:
|
||||
# pass
|
||||
|
||||
|
||||
def getBookmark(self):
|
||||
"""
|
||||
Get bookmark timestamp.
|
||||
""" Get bookmark timestamp.
|
||||
|
||||
@rtype: int
|
||||
@return: bookmark time (UTC UNIX timestamp) or None
|
||||
@return: bookmark timestamp or None
|
||||
"""
|
||||
if self.valid and os.path.exists(self.__filename() + ".bookmark"):
|
||||
try:
|
||||
return int(open(self.__filename() + ".bookmark", 'r').readline())
|
||||
except (OSError, ValueError):
|
||||
return None
|
||||
return None
|
||||
bm = None
|
||||
bm_fn = self.__bookmark_filename()
|
||||
|
||||
if self.valid and os.path.exists(bm_fn):
|
||||
try:
|
||||
bm = long(open(bm_fn, 'r').readline()) # must be long for py 2.2
|
||||
except (OSError, ValueError):
|
||||
pass
|
||||
return bm
|
||||
|
||||
def delBookmark(self):
|
||||
"""
|
||||
Removes bookmark timestamp.
|
||||
""" Removes bookmark timestamp.
|
||||
|
||||
@rtype: int
|
||||
@return: 0 on success, 1 on failure
|
||||
"""
|
||||
bm_fn = self.__bookmark_filename()
|
||||
if self.valid:
|
||||
if os.path.exists(self.__filename() + ".bookmark"):
|
||||
if os.path.exists(bm_fn):
|
||||
try:
|
||||
os.unlink(self.__filename() + ".bookmark")
|
||||
os.unlink(bm_fn)
|
||||
except OSError:
|
||||
return 1
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def getQuickLinks(self):
|
||||
""" Get list of pages this user wants in the navibar
|
||||
|
||||
@rtype: list
|
||||
@return: quicklinks from user account
|
||||
"""
|
||||
return self.quicklinks
|
||||
# -----------------------------------------------------------------
|
||||
# Subscribe
|
||||
|
||||
def getSubscriptionList(self):
|
||||
""" Get list of pages this user has subscribed to
|
||||
|
@ -645,71 +624,210 @@ class User:
|
|||
return self.subscribed_pages
|
||||
|
||||
def isSubscribedTo(self, pagelist):
|
||||
"""
|
||||
Check if user subscription matches any page in pagelist.
|
||||
""" Check if user subscription matches any page in pagelist.
|
||||
|
||||
The subscription list may contain page names or interwiki page
|
||||
names. e.g 'Page Name' or 'WikiName:Page_Name'
|
||||
|
||||
TODO: check if its fast enough when calling with many users
|
||||
from page.getSubscribersList()
|
||||
|
||||
@param pagelist: list of pages to check for subscription
|
||||
@rtype: int
|
||||
@return: 1, if user has subscribed any page in pagelist
|
||||
0, if not
|
||||
@rtype: bool
|
||||
@return: if user is subscribed any page in pagelist
|
||||
"""
|
||||
if not self.valid:
|
||||
return False
|
||||
|
||||
import re
|
||||
# Create a new list with both names and interwiki names.
|
||||
pages = pagelist[:]
|
||||
if self._cfg.interwikiname:
|
||||
pages += [self._interWikiName(pagename) for pagename in pagelist]
|
||||
# Create text for regular expression search
|
||||
text = '\n'.join(pages)
|
||||
|
||||
matched = 0
|
||||
if self.valid:
|
||||
pagelist_lines = '\n'.join(pagelist)
|
||||
for pattern in self.getSubscriptionList():
|
||||
# check if pattern matches one of the pages in pagelist
|
||||
matched = pattern in pagelist
|
||||
if matched: break
|
||||
try:
|
||||
rexp = re.compile("^"+pattern+"$", re.M)
|
||||
except re.error:
|
||||
# skip bad regex
|
||||
continue
|
||||
matched = rexp.search(pagelist_lines)
|
||||
if matched: break
|
||||
if matched:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
for pattern in self.getSubscriptionList():
|
||||
# Try simple match first
|
||||
if pattern in pages:
|
||||
return True
|
||||
# Try regular expression search, skipping bad patterns
|
||||
try:
|
||||
pattern = re.compile(r'^%s$' % pattern, re.M)
|
||||
except re.error:
|
||||
continue
|
||||
if pattern.search(text):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def subscribePage(self, pagename, remove=False):
|
||||
""" Subscribe or unsubscribe to a wiki page.
|
||||
def subscribe(self, pagename):
|
||||
""" Subscribe to a wiki page.
|
||||
|
||||
Note that you need to save the user data to make this stick!
|
||||
To enable shared farm users, if the wiki has an interwiki name,
|
||||
page names are saved as interwiki names.
|
||||
|
||||
@param pagename: name of the page to subscribe
|
||||
@param remove: unsubscribe pagename if set
|
||||
@type remove: bool
|
||||
@type pagename: unicode
|
||||
@rtype: bool
|
||||
@return: true, if page was NEWLY subscribed.
|
||||
@return: if page was subscribed
|
||||
"""
|
||||
if remove:
|
||||
if pagename in self.subscribed_pages:
|
||||
self.subscribed_pages.remove(pagename)
|
||||
return 1
|
||||
else:
|
||||
if pagename not in self.subscribed_pages:
|
||||
self.subscribed_pages.append(pagename)
|
||||
return 1
|
||||
return 0
|
||||
if self._cfg.interwikiname:
|
||||
pagename = self._interWikiName(pagename)
|
||||
|
||||
if pagename not in self.subscribed_pages:
|
||||
self.subscribed_pages.append(pagename)
|
||||
self.save()
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def unsubscribe(self, pagename):
|
||||
""" Unsubscribe a wiki page.
|
||||
|
||||
Try to unsubscribe by removing non-interwiki name (leftover
|
||||
from old use files) and interwiki name from the subscription
|
||||
list.
|
||||
|
||||
Its possible that the user will be subscribed to a page by more
|
||||
then one pattern. It can be both pagename and interwiki name,
|
||||
or few patterns that all of them match the page. Therefore, we
|
||||
must check if the user is still subscribed to the page after we
|
||||
try to remove names from the list.
|
||||
|
||||
TODO: should we remove non-interwiki subscription? what if the
|
||||
user want to subscribe to the same page in multiple wikis?
|
||||
|
||||
@param pagename: name of the page to subscribe
|
||||
@type pagename: unicode
|
||||
@rtype: bool
|
||||
@return: if unsubscrieb was successful. If the user has a
|
||||
regular expression that match, it will always fail.
|
||||
"""
|
||||
changed = False
|
||||
if pagename in self.subscribed_pages:
|
||||
self.subscribed_pages.remove(pagename)
|
||||
changed = True
|
||||
|
||||
interWikiName = self._interWikiName(pagename)
|
||||
if interWikiName and interWikiName in self.subscribed_pages:
|
||||
self.subscribed_pages.remove(interWikiName)
|
||||
changed = True
|
||||
|
||||
if changed:
|
||||
self.save()
|
||||
return not self.isSubscribedTo([pagename])
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Quicklinks
|
||||
|
||||
def getQuickLinks(self):
|
||||
""" Get list of pages this user wants in the navibar
|
||||
|
||||
@rtype: list
|
||||
@return: quicklinks from user account
|
||||
"""
|
||||
return self.quicklinks
|
||||
|
||||
def isQuickLinkedTo(self, pagelist):
|
||||
""" Check if user quicklink matches any page in pagelist.
|
||||
|
||||
@param pagelist: list of pages to check for quicklinks
|
||||
@rtype: bool
|
||||
@return: if user has quicklinked any page in pagelist
|
||||
"""
|
||||
if not self.valid:
|
||||
return False
|
||||
|
||||
for pagename in pagelist:
|
||||
if pagename in self.quicklinks:
|
||||
return True
|
||||
interWikiName = self._interWikiName(pagename)
|
||||
if interWikiName and interWikiName in self.quicklinks:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def addQuicklink(self, pagename):
|
||||
""" Adds a page to the user quicklinks
|
||||
|
||||
If the wiki has an interwiki name, all links are saved as
|
||||
interwiki names. If not, as simple page name.
|
||||
|
||||
@param pagename: page name
|
||||
@type pagename: unicode
|
||||
@rtype: bool
|
||||
@return: if pagename was added
|
||||
"""
|
||||
changed = False
|
||||
interWikiName = self._interWikiName(pagename)
|
||||
if interWikiName:
|
||||
if pagename in self.quicklinks:
|
||||
self.quicklinks.remove(pagename)
|
||||
changed = True
|
||||
if interWikiName not in self.quicklinks:
|
||||
self.quicklinks.append(interWikiName)
|
||||
changed = True
|
||||
else:
|
||||
if pagename not in self.quicklinks:
|
||||
self.quicklinks.append(pagename)
|
||||
changed = True
|
||||
|
||||
if changed:
|
||||
self.save()
|
||||
return changed
|
||||
|
||||
def removeQuicklink(self, pagename):
|
||||
""" Remove a page from user quicklinks
|
||||
|
||||
Remove both interwiki and simple name from quicklinks.
|
||||
|
||||
@param pagename: page name
|
||||
@type pagename: unicode
|
||||
@rtype: bool
|
||||
@return: if pagename was removed
|
||||
"""
|
||||
changed = False
|
||||
interWikiName = self._interWikiName(pagename)
|
||||
if interWikiName and interWikiName in self.quicklinks:
|
||||
self.quicklinks.remove(interWikiName)
|
||||
changed = True
|
||||
if pagename in self.quicklinks:
|
||||
self.quicklinks.remove(pagename)
|
||||
changed = True
|
||||
|
||||
if changed:
|
||||
self.save()
|
||||
return changed
|
||||
|
||||
def _interWikiName(self, pagename):
|
||||
""" Return the inter wiki name of a page name
|
||||
|
||||
@param pagename: page name
|
||||
@type pagename: unicode
|
||||
"""
|
||||
if not self._cfg.interwikiname:
|
||||
return None
|
||||
|
||||
# Interwiki links must use _ e.g Wiki:Main_Page
|
||||
pagename = pagename.replace(" ", "_")
|
||||
return "%s:%s" % (self._cfg.interwikiname, pagename)
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Trail
|
||||
|
||||
def addTrail(self, pagename):
|
||||
"""
|
||||
Add page to trail.
|
||||
""" Add page to trail.
|
||||
|
||||
@param pagename: the page name to add to the trail
|
||||
"""
|
||||
# TODO: acquire lock here, so multiple processes don't clobber
|
||||
# each one trail.
|
||||
|
||||
if self.valid and (self.show_page_trail or self.remember_last_visit):
|
||||
# load trail if not known
|
||||
self.getTrail()
|
||||
|
||||
# don't append tail to trail ;)
|
||||
if self._trail and self._trail[-1] == pagename: return
|
||||
|
||||
# Add only existing pages that the user may read
|
||||
if self._request:
|
||||
from MoinMoin.Page import Page
|
||||
|
@ -718,25 +836,47 @@ class User:
|
|||
self._request.user.may.read(page.page_name)):
|
||||
return
|
||||
|
||||
# append new page, limiting the length
|
||||
self._trail = filter(lambda p, pn=pagename: p != pn, self._trail)
|
||||
# Save interwiki links internally
|
||||
if self._cfg.interwikiname:
|
||||
pagename = self._interWikiName(pagename)
|
||||
|
||||
# Don't append tail to trail ;)
|
||||
if self._trail and self._trail[-1] == pagename:
|
||||
return
|
||||
|
||||
# Append new page, limiting the length
|
||||
self._trail = [p for p in self._trail if p != pagename]
|
||||
self._trail = self._trail[-(self._cfg.trail_size-1):]
|
||||
self._trail.append(pagename)
|
||||
self.saveTrail()
|
||||
|
||||
# save new trail
|
||||
trailfile = codecs.open(self.__filename() + ".trail", "w", config.charset)
|
||||
for t in self._trail:
|
||||
trailfile.write('%s\n' % t)
|
||||
trailfile.close()
|
||||
# TODO: release lock here
|
||||
|
||||
def saveTrail(self):
|
||||
""" Save trail file
|
||||
|
||||
Save using one write call, which should be fine in most cases,
|
||||
but will fail in rare cases without real file locking.
|
||||
"""
|
||||
data = '\n'.join(self._trail) + '\n'
|
||||
path = self.__filename() + ".trail"
|
||||
try:
|
||||
file = codecs.open(path, "w", config.charset)
|
||||
try:
|
||||
os.chmod(self.__filename() + ".trail", 0666 & config.umask)
|
||||
except OSError:
|
||||
pass
|
||||
file.write(data)
|
||||
finally:
|
||||
file.close()
|
||||
|
||||
try:
|
||||
os.chmod(path, 0666 & config.umask)
|
||||
except OSError, err:
|
||||
self._request.log("Can't change mode of trail file: %s" %
|
||||
str(err))
|
||||
except (IOError, OSError), err:
|
||||
self._request.log("Can't save trail file: %s" % str(err))
|
||||
|
||||
def getTrail(self):
|
||||
"""
|
||||
Return list of recently visited pages.
|
||||
""" Return list of recently visited pages.
|
||||
|
||||
@rtype: list
|
||||
@return: pages in trail
|
||||
|
@ -745,12 +885,99 @@ class User:
|
|||
and not self._trail \
|
||||
and os.path.exists(self.__filename() + ".trail"):
|
||||
try:
|
||||
self._trail = codecs.open(self.__filename() + ".trail", 'r', config.charset).readlines()
|
||||
trail = codecs.open(self.__filename() + ".trail", 'r', config.charset).readlines()
|
||||
except (OSError, ValueError):
|
||||
self._trail = []
|
||||
else:
|
||||
self._trail = filter(None, map(string.strip, self._trail))
|
||||
self._trail = self._trail[-self._cfg.trail_size:]
|
||||
trail = []
|
||||
trail = [t.strip() for t in trail]
|
||||
trail = [t for t in trail if t]
|
||||
self._trail = trail[-self._cfg.trail_size:]
|
||||
|
||||
return self._trail
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Other
|
||||
|
||||
def isCurrentUser(self):
|
||||
return self._request.user.name == self.name
|
||||
|
||||
def isSuperUser(self):
|
||||
superusers = self._request.cfg.superuser
|
||||
assert isinstance(superusers, (list, tuple))
|
||||
return self.valid and self.name and self.name in superusers
|
||||
|
||||
def host(self):
|
||||
""" Return user host """
|
||||
_ = self._request.getText
|
||||
host = self.isCurrentUser() and self._cfg.show_hosts and self._request.remote_addr
|
||||
return host or _("<unknown>")
|
||||
|
||||
def signature(self):
|
||||
""" Return user signature using markup
|
||||
|
||||
Users sign with a link to their homepage, or with text if they
|
||||
don't have one. The text may be parsed as a link if it's using
|
||||
CamelCase. Visitors return their host address.
|
||||
|
||||
TODO: The signature use wiki format only, for example, it will
|
||||
not create a link when using rst format. It will also break if
|
||||
we change wiki syntax.
|
||||
"""
|
||||
if not self.name:
|
||||
return self.host()
|
||||
|
||||
wikiname, pagename = wikiutil.getInterwikiHomePage(self._request,
|
||||
self.name)
|
||||
if wikiname == 'Self':
|
||||
if not wikiutil.isStrictWikiname(self.name):
|
||||
markup = '["%s"]' % pagename
|
||||
else:
|
||||
markup = pagename
|
||||
else:
|
||||
markup = '%s:%s' % (wikiname, pagename.replace(" ","_"))
|
||||
return markup
|
||||
|
||||
def mailAccountData(self, cleartext_passwd=None):
|
||||
from MoinMoin.util import mail
|
||||
from MoinMoin.wikiutil import getSysPage
|
||||
_ = self._request.getText
|
||||
|
||||
if not self.enc_password: # generate pw if there is none yet
|
||||
from random import randint
|
||||
import base64
|
||||
|
||||
charset = 'utf-8'
|
||||
pwd = "%s%d" % (str(time.time()), randint(0, 65535))
|
||||
pwd = pwd.encode(charset)
|
||||
|
||||
pwd = sha.new(pwd).digest()
|
||||
pwd = '{SHA}%s' % base64.encodestring(pwd).rstrip()
|
||||
|
||||
self.enc_password = pwd
|
||||
self.save()
|
||||
|
||||
text = '\n' + _("""\
|
||||
Login Name: %s
|
||||
|
||||
Login Password: %s
|
||||
|
||||
Login URL: %s/%s
|
||||
""", formatted=False) % (
|
||||
self.name, self.enc_password, self._request.getBaseURL(), getSysPage(self._request, 'UserPreferences').page_name)
|
||||
|
||||
text = _("""\
|
||||
Somebody has requested to submit your account data to this email address.
|
||||
|
||||
If you lost your password, please use the data below and just enter the
|
||||
password AS SHOWN into the wiki's password form field (use copy and paste
|
||||
for that).
|
||||
|
||||
After successfully logging in, it is of course a good idea to set a new and known password.
|
||||
""", formatted=False) + text
|
||||
|
||||
|
||||
subject = _('[%(sitename)s] Your wiki account data',
|
||||
formatted=False) % {'sitename': self._cfg.sitename or "Wiki"}
|
||||
mailok, msg = mail.sendmail(self._request, [self.email], subject,
|
||||
text, mail_from=self._cfg.mail_from)
|
||||
return msg
|
||||
|
||||
|
|
563
wiki/userform.py
563
wiki/userform.py
|
@ -6,15 +6,13 @@
|
|||
@license: GNU GPL, see COPYING for details.
|
||||
"""
|
||||
|
||||
import string, time, re, Cookie
|
||||
from MoinMoin import config, user, util, wikiutil
|
||||
from MoinMoin.util import web, mail, datetime
|
||||
import string, time, re
|
||||
from MoinMoin import user, util, wikiutil
|
||||
from MoinMoin.util import web, mail, timefuncs
|
||||
from MoinMoin.widget import html
|
||||
from MoinMoin.PageEditor import PageEditor
|
||||
|
||||
_debug = 0
|
||||
|
||||
|
||||
#############################################################################
|
||||
### Form POST Handling
|
||||
#############################################################################
|
||||
|
@ -56,8 +54,9 @@ class UserSettingsHandler:
|
|||
if not item:
|
||||
continue
|
||||
# Normalize names - except [name_with_spaces label]
|
||||
if not (item.startswith('[') and item.endswith(']')):
|
||||
item = self.request.normalizePagename(item)
|
||||
# Commented out to allow URLs
|
||||
#if not (item.startswith('[') and item.endswith(']')):
|
||||
# item = self.request.normalizePagename(item)
|
||||
items.append(item)
|
||||
return items
|
||||
|
||||
|
@ -65,15 +64,11 @@ class UserSettingsHandler:
|
|||
_ = self._
|
||||
form = self.request.form
|
||||
|
||||
if form.has_key('logout'):
|
||||
# clear the cookie in the browser and locally. Does not
|
||||
# check if we have a valid user logged, just make sure we
|
||||
# don't have one after this call.
|
||||
self.request.deleteCookie()
|
||||
return _("Cookie deleted. You are now logged out.")
|
||||
if form.has_key('cancel'):
|
||||
return
|
||||
|
||||
if form.has_key('login_sendmail'):
|
||||
if not self.cfg.mail_smarthost:
|
||||
if form.has_key('account_sendmail'):
|
||||
if not self.cfg.mail_enabled:
|
||||
return _("""This wiki is not enabled for mail processing.
|
||||
Contact the owner of the wiki, who can enable email.""")
|
||||
try:
|
||||
|
@ -81,83 +76,32 @@ Contact the owner of the wiki, who can enable email.""")
|
|||
except KeyError:
|
||||
return _("Please provide a valid email address!")
|
||||
|
||||
text = ''
|
||||
users = user.getUserList(self.request)
|
||||
for uid in users:
|
||||
theuser = user.User(self.request, uid)
|
||||
if theuser.valid and theuser.email.lower() == email:
|
||||
text = "%s\n\nID: %s\nName: %s\nPassword: %s\nLogin URL: %s/?action=userform&uid=%s" % (
|
||||
text, theuser.id, theuser.name, theuser.enc_password, self.request.getBaseURL(), theuser.id)
|
||||
msg = theuser.mailAccountData()
|
||||
return wikiutil.escape(msg)
|
||||
|
||||
if not text:
|
||||
return _("Found no account matching the given email address '%(email)s'!") % {'email': wikiutil.escape(email)}
|
||||
return _("Found no account matching the given email address '%(email)s'!") % {'email': wikiutil.escape(email)}
|
||||
|
||||
mailok, msg = util.mail.sendmail(self.request, [email],
|
||||
'Your wiki account data', text, mail_from=self.cfg.mail_from)
|
||||
return wikiutil.escape(msg)
|
||||
|
||||
if form.has_key('login'):
|
||||
# Trying to login with a user name and a password
|
||||
|
||||
# Require valid user name
|
||||
name = form.get('username', [''])[0]
|
||||
if not user.isValidName(self.request, name):
|
||||
return _("""Invalid user name {{{'%s'}}}.
|
||||
Name may contain any Unicode alpha numeric character, with optional one
|
||||
space between words. Group page name is not allowed.""") % wikiutil.escape(name)
|
||||
|
||||
# Check that user exists
|
||||
if not user.getUserId(self.request, name):
|
||||
return _('Unknown user name: {{{"%s"}}}. Please enter'
|
||||
' user name and password.') % name
|
||||
|
||||
# Require password
|
||||
password = form.get('password',[None])[0]
|
||||
if not password:
|
||||
return _("Missing password. Please enter user name and"
|
||||
" password.")
|
||||
|
||||
# Load the user data and check for validness
|
||||
theuser = user.User(self.request, name=name, password=password)
|
||||
if not theuser.valid:
|
||||
return _("Sorry, wrong password.")
|
||||
|
||||
# Save the user and send a cookie
|
||||
self.request.user = theuser
|
||||
self.request.setCookie()
|
||||
|
||||
elif form.has_key('uid'):
|
||||
# Trying to login with the login URL, soon to be removed!
|
||||
try:
|
||||
uid = form['uid'][0]
|
||||
except KeyError:
|
||||
return _("Bad relogin URL.")
|
||||
|
||||
# Load the user data and check for validness
|
||||
theuser = user.User(self.request, uid)
|
||||
if not theuser.valid:
|
||||
return _("Unknown user.")
|
||||
|
||||
# Save the user and send a cookie
|
||||
self.request.user = theuser
|
||||
self.request.setCookie()
|
||||
|
||||
else:
|
||||
# Save user profile
|
||||
theuser = user.User(self.request)
|
||||
if (form.has_key('create') or
|
||||
form.has_key('create_only') or
|
||||
form.has_key('create_and_mail')):
|
||||
if self.request.request_method != 'POST':
|
||||
return _("Use UserPreferences to change your settings or create an account.")
|
||||
# Create user profile
|
||||
if form.has_key('create'):
|
||||
theuser = self.request.get_user_from_form()
|
||||
else:
|
||||
theuser = user.User(self.request, auth_method="request:152")
|
||||
|
||||
# Require non-empty name
|
||||
try:
|
||||
theuser.name = form['username'][0]
|
||||
theuser.name = form['name'][0]
|
||||
except KeyError:
|
||||
return _("Empty user name. Please enter a user name.")
|
||||
|
||||
#### HACK CRANS : oblige les utilistaeurs a créer un WikiNom valide
|
||||
if not wikiutil.isStrictWikiname(theuser.name):
|
||||
return (u"""Nom d'utilisateur invalide {{{'%s'}}}.
|
||||
Le login doit être de la forme WikiNom, WikiPseudo, PrenomNom... (voir ci dessous pour plus d'informations).""" % wikiutil.escape(theuser.name))
|
||||
#### FIN HACK
|
||||
|
||||
# Don't allow users with invalid names
|
||||
if not user.isValidName(self.request, theuser.name):
|
||||
return _("""Invalid user name {{{'%s'}}}.
|
||||
|
@ -173,16 +117,6 @@ space between words. Group page name is not allowed.""") % wikiutil.escape(theus
|
|||
else:
|
||||
newuser = 0
|
||||
|
||||
#### HACK SAUVAGE
|
||||
|
||||
if newuser and not self.cfg.ip_autorised_create_account(self.request.remote_addr):
|
||||
return _(u"""Création de compte impossible.
|
||||
Pour des raisons de sécurité, la fonction de création d'un compte n'est
|
||||
possible que depuis la zone CRANS.
|
||||
Si vous possédez un compte sur zamok, vous pouvez y exécuter
|
||||
creer_compte_wiki.""")
|
||||
#### FIN DU HACK
|
||||
|
||||
# try to get the password and pw repeat
|
||||
password = form.get('password', [''])[0]
|
||||
password2 = form.get('password2',[''])[0]
|
||||
|
@ -200,30 +134,126 @@ creer_compte_wiki.""")
|
|||
# Should never happen
|
||||
return "Can't encode password: %s" % str(err)
|
||||
|
||||
# try to get the (optional) email
|
||||
# try to get the (required) email
|
||||
email = form.get('email', [''])[0]
|
||||
theuser.email = email.strip()
|
||||
|
||||
# Require email if acl is enabled
|
||||
if not theuser.email and self.cfg.acl_enabled:
|
||||
return _("Please provide your email address. If you loose your"
|
||||
if not theuser.email:
|
||||
return _("Please provide your email address. If you lose your"
|
||||
" login information, you can get it by email.")
|
||||
|
||||
# Email required to be unique
|
||||
# See also MoinMoin/scripts/moin_usercheck.py
|
||||
if theuser.email:
|
||||
# Email should be unique - see also MoinMoin/script/accounts/moin_usercheck.py
|
||||
if theuser.email and self.request.cfg.user_email_unique:
|
||||
users = user.getUserList(self.request)
|
||||
for uid in users:
|
||||
if uid == theuser.id:
|
||||
continue
|
||||
thisuser = user.User(self.request, uid)
|
||||
if thisuser.email == theuser.email and not thisuser.disabled:
|
||||
return _("This email already belongs to somebody else.")
|
||||
|
||||
# save data
|
||||
theuser.save()
|
||||
if form.has_key('create_and_mail'):
|
||||
theuser.mailAccountData()
|
||||
|
||||
result = _("User account created! You can use this account to login now...")
|
||||
if _debug:
|
||||
result = result + util.dumpFormData(form)
|
||||
return result
|
||||
|
||||
|
||||
# Select user profile (su user) - only works with cookie auth active.
|
||||
if form.has_key('select_user'):
|
||||
if (wikiutil.checkTicket(self.request.form['ticket'][0]) and
|
||||
self.request.request_method == 'POST' and
|
||||
self.request.user.isSuperUser()):
|
||||
su_user = form.get('selected_user', [''])[0]
|
||||
uid = user.getUserId(self.request, su_user)
|
||||
theuser = user.User(self.request, uid)
|
||||
theuser.disabled = None
|
||||
theuser.save()
|
||||
from MoinMoin import auth
|
||||
auth.setCookie(self.request, theuser)
|
||||
self.request.user = theuser
|
||||
return _("Use UserPreferences to change settings of the selected user account")
|
||||
else:
|
||||
return _("Use UserPreferences to change your settings or create an account.")
|
||||
|
||||
if form.has_key('save'): # Save user profile
|
||||
if self.request.request_method != 'POST':
|
||||
return _("Use UserPreferences to change your settings or create an account.")
|
||||
theuser = self.request.get_user_from_form()
|
||||
|
||||
if not 'name' in theuser.auth_attribs:
|
||||
# Require non-empty name
|
||||
theuser.name = form.get('name', [theuser.name])[0]
|
||||
if not theuser.name:
|
||||
return _("Empty user name. Please enter a user name.")
|
||||
|
||||
# Don't allow users with invalid names
|
||||
if not user.isValidName(self.request, theuser.name):
|
||||
return _("""Invalid user name {{{'%s'}}}.
|
||||
Name may contain any Unicode alpha numeric character, with optional one
|
||||
space between words. Group page name is not allowed.""") % wikiutil.escape(theuser.name)
|
||||
|
||||
# Is this an existing user trying to change information or a new user?
|
||||
# Name required to be unique. Check if name belong to another user.
|
||||
newuser = 1
|
||||
if user.getUserId(self.request, theuser.name):
|
||||
if theuser.name != self.request.user.name:
|
||||
return _("This user name already belongs to somebody else.")
|
||||
else:
|
||||
newuser = 0
|
||||
|
||||
if not 'password' in theuser.auth_attribs:
|
||||
# try to get the password and pw repeat
|
||||
password = form.get('password', [''])[0]
|
||||
password2 = form.get('password2',[''])[0]
|
||||
|
||||
# Check if password is given and matches with password repeat
|
||||
if password != password2:
|
||||
return _("Passwords don't match!")
|
||||
if not password and newuser:
|
||||
return _("Please specify a password!")
|
||||
# Encode password
|
||||
if password and not password.startswith('{SHA}'):
|
||||
try:
|
||||
theuser.enc_password = user.encodePassword(password)
|
||||
except UnicodeError, err:
|
||||
# Should never happen
|
||||
return "Can't encode password: %s" % str(err)
|
||||
|
||||
if not 'email' in theuser.auth_attribs:
|
||||
# try to get the email
|
||||
email = form.get('email', [theuser.email])[0]
|
||||
theuser.email = email.strip()
|
||||
|
||||
# Require email
|
||||
if not theuser.email:
|
||||
return _("Please provide your email address. If you lose your"
|
||||
" login information, you can get it by email.")
|
||||
|
||||
# Email should be unique - see also MoinMoin/script/accounts/moin_usercheck.py
|
||||
if theuser.email and self.request.cfg.user_email_unique:
|
||||
users = user.getUserList(self.request)
|
||||
for uid in users:
|
||||
if uid == theuser.id:
|
||||
continue
|
||||
thisuser = user.User(self.request, uid, auth_method='userform:283')
|
||||
if thisuser.email == theuser.email:
|
||||
return _("This email already belongs to somebody else.")
|
||||
|
||||
if not 'aliasname' in theuser.auth_attribs:
|
||||
# aliasname
|
||||
theuser.aliasname = form.get('aliasname', [''])[0]
|
||||
|
||||
# editor size
|
||||
theuser.edit_rows = util.web.getIntegerInput(self.request, 'edit_rows', theuser.edit_rows, 10, 60)
|
||||
|
||||
# try to get the editor
|
||||
theuser.editor_default = form.get('editor_default', [self.cfg.editor_default])[0]
|
||||
theuser.editor_ui = form.get('editor_ui', [self.cfg.editor_ui])[0]
|
||||
|
||||
# time zone
|
||||
theuser.tz_offset = util.web.getIntegerInput(self.request, 'tz_offset', theuser.tz_offset, -84600, 84600)
|
||||
|
||||
|
@ -232,7 +262,8 @@ creer_compte_wiki.""")
|
|||
dt_d_combined = UserSettings._date_formats.get(form['datetime_fmt'][0], '')
|
||||
theuser.datetime_fmt, theuser.date_fmt = dt_d_combined.split(' & ')
|
||||
except (KeyError, ValueError):
|
||||
pass
|
||||
theuser.datetime_fmt = '' # default
|
||||
theuser.date_fmt = '' # default
|
||||
|
||||
# try to get the (optional) theme
|
||||
theme_name = form.get('theme_name', [self.cfg.theme_default])[0]
|
||||
|
@ -248,22 +279,41 @@ creer_compte_wiki.""")
|
|||
theme_name = wikiutil.escape(theme_name)
|
||||
return _("The theme '%(theme_name)s' could not be loaded!") % locals()
|
||||
|
||||
# User CSS URL
|
||||
theuser.css_url = form.get('css_url', [''])[0]
|
||||
|
||||
# try to get the (optional) preferred language
|
||||
theuser.language = form.get('language', [''])[0]
|
||||
|
||||
# I want to handle all inputs from user_form_fields, but
|
||||
# don't want to handle the cases that have already been coded
|
||||
# above.
|
||||
# This is a horribly fragile kludge that's begging to break.
|
||||
# Something that might work better would be to define a
|
||||
# handler for each form field, instead of stuffing them all in
|
||||
# one long and inextensible method. That would allow for
|
||||
# plugins to provide methods to validate their fields as well.
|
||||
already_handled = ['name', 'password', 'password2', 'email',
|
||||
'aliasname', 'edit_rows', 'editor_default',
|
||||
'editor_ui', 'tz_offset', 'datetime_fmt',
|
||||
'theme_name', 'language']
|
||||
for field in self.cfg.user_form_fields:
|
||||
key = field[0]
|
||||
if ((key in self.cfg.user_form_disable)
|
||||
or (key in already_handled)):
|
||||
continue
|
||||
default = self.cfg.user_form_defaults[key]
|
||||
value = form.get(key, [default])[0]
|
||||
setattr(theuser, key, value)
|
||||
|
||||
# checkbox options
|
||||
if not newuser:
|
||||
for key, label in user.User._checkbox_fields:
|
||||
value = form.get(key, ["0"])[0]
|
||||
try:
|
||||
value = int(value)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
setattr(theuser, key, value)
|
||||
for key, label in self.cfg.user_checkbox_fields:
|
||||
if key not in self.cfg.user_checkbox_disable and key not in self.cfg.user_checkbox_remove:
|
||||
value = form.get(key, ["0"])[0]
|
||||
try:
|
||||
value = int(value)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
setattr(theuser, key, value)
|
||||
|
||||
# quicklinks for navibar
|
||||
theuser.quicklinks = self.decodePageList('quicklinks')
|
||||
|
@ -271,18 +321,9 @@ creer_compte_wiki.""")
|
|||
# subscription for page change notification
|
||||
theuser.subscribed_pages = self.decodePageList('subscribed_pages')
|
||||
|
||||
# save data and send cookie
|
||||
# save data
|
||||
theuser.save()
|
||||
self.request.user = theuser
|
||||
self.request.setCookie()
|
||||
|
||||
#### HACK : création de la page WikiNom
|
||||
try:
|
||||
p = PageEditor(self.request, theuser.name)
|
||||
p.saveText( 'Décrire ici %s' % theuser.name, 0)
|
||||
except:
|
||||
pass
|
||||
#### FIN DU HACK
|
||||
|
||||
result = _("User preferences saved!")
|
||||
if _debug:
|
||||
|
@ -326,7 +367,7 @@ class UserSettings:
|
|||
options.append((
|
||||
str(offset),
|
||||
'%s [%s%s:%s]' % (
|
||||
time.strftime(self.cfg.datetime_fmt, util.datetime.tmtuple(t)),
|
||||
time.strftime(self.cfg.datetime_fmt, timefuncs.tmtuple(t)),
|
||||
"+-"[offset < 0],
|
||||
string.zfill("%d" % (abs(offset) / 3600), 2),
|
||||
string.zfill("%d" % (abs(offset) % 3600 / 60), 2),
|
||||
|
@ -366,15 +407,44 @@ class UserSettings:
|
|||
|
||||
return util.web.makeSelection('language', options, cur_lang)
|
||||
|
||||
def _user_select(self):
|
||||
options = []
|
||||
users = user.getUserList(self.request)
|
||||
for uid in users:
|
||||
name = user.User(self.request, id=uid).name # + '_' + uid # for debugging
|
||||
options.append((name, name))
|
||||
options.sort()
|
||||
|
||||
size = min(5, len(options))
|
||||
current_user = self.request.user.name
|
||||
return util.web.makeSelection('selected_user', options, current_user, size=size)
|
||||
|
||||
def _theme_select(self):
|
||||
""" Create theme selection. """
|
||||
cur_theme = self.request.user.valid and self.request.user.theme_name or self.cfg.theme_default
|
||||
options = []
|
||||
options = [("<default>", "<%s>" % self._("Default"))]
|
||||
for theme in wikiutil.getPlugins('theme', self.request.cfg):
|
||||
options.append((theme, theme))
|
||||
|
||||
return util.web.makeSelection('theme_name', options, cur_theme)
|
||||
|
||||
def _editor_default_select(self):
|
||||
""" Create editor selection. """
|
||||
editor_default = self.request.user.valid and self.request.user.editor_default or self.cfg.editor_default
|
||||
options = [("<default>", "<%s>" % self._("Default"))]
|
||||
for editor in ['text','gui',]:
|
||||
options.append((editor, editor))
|
||||
return util.web.makeSelection('editor_default', options, editor_default)
|
||||
|
||||
def _editor_ui_select(self):
|
||||
""" Create editor selection. """
|
||||
editor_ui = self.request.user.valid and self.request.user.editor_ui or self.cfg.editor_ui
|
||||
options = [("<default>", "<%s>" % self._("Default")),
|
||||
("theonepreferred", self._("the one preferred")),
|
||||
("freechoice", self._("free choice")),
|
||||
]
|
||||
return util.web.makeSelection('editor_ui', options, editor_ui)
|
||||
|
||||
def make_form(self):
|
||||
""" Create the FORM, and the TABLE with the input fields
|
||||
"""
|
||||
|
@ -402,98 +472,83 @@ class UserSettings:
|
|||
]))
|
||||
|
||||
|
||||
def asHTML(self):
|
||||
def asHTML(self, create_only=False):
|
||||
""" Create the complete HTML form code. """
|
||||
_ = self._
|
||||
self.make_form()
|
||||
|
||||
if self.request.user.valid:
|
||||
# User preferences interface
|
||||
buttons = [
|
||||
('save', _('Save')),
|
||||
('logout', _('Logout')),
|
||||
]
|
||||
else:
|
||||
# Login / register interface
|
||||
buttons = [
|
||||
# IMPORTANT: login should be first to be the default
|
||||
# button when a user click enter.
|
||||
('login', _('Login')),
|
||||
("save", _('Create Profile')),
|
||||
]
|
||||
if self.cfg.mail_smarthost:
|
||||
buttons.append(("login_sendmail", _('Mail me my account data')))
|
||||
if self.request.user.isSuperUser():
|
||||
ticket = wikiutil.createTicket()
|
||||
self.make_row(_('Select User'), [self._user_select()])
|
||||
self._form.append(html.INPUT(type="hidden", name="ticket", value="%s" % ticket))
|
||||
buttons = [("select_user", _('Select User'))]
|
||||
button_cell = []
|
||||
for name, label in buttons:
|
||||
button_cell.extend([
|
||||
html.INPUT(type="submit", name=name, value=label),
|
||||
' ',
|
||||
])
|
||||
self.make_row('', button_cell)
|
||||
|
||||
self.make_row(_('Name'), [
|
||||
html.INPUT(
|
||||
type="text", size="36", name="username", value=self.request.user.name
|
||||
),
|
||||
' ', _('(Use FirstnameLastname)', formatted=False),
|
||||
])
|
||||
if self.request.user.valid and not create_only:
|
||||
buttons = [('save', _('Save')), ('cancel', _('Cancel')), ]
|
||||
uf_remove = self.cfg.user_form_remove
|
||||
uf_disable = self.cfg.user_form_disable
|
||||
for attr in self.request.user.auth_attribs:
|
||||
if attr == 'password':
|
||||
uf_remove.append(attr)
|
||||
uf_remove.append('password2')
|
||||
else:
|
||||
uf_disable.append(attr)
|
||||
for key, label, type, length, textafter in self.cfg.user_form_fields:
|
||||
default = self.cfg.user_form_defaults[key]
|
||||
if not key in uf_remove:
|
||||
if key in uf_disable:
|
||||
self.make_row(_(label),
|
||||
[ html.INPUT(type=type, size=length, name=key, disabled="disabled",
|
||||
value=getattr(self.request.user, key)), ' ', _(textafter), ])
|
||||
else:
|
||||
self.make_row(_(label),
|
||||
[ html.INPUT(type=type, size=length, name=key, value=getattr(self.request.user, key)), ' ', _(textafter), ])
|
||||
|
||||
self.make_row(_('Password'), [
|
||||
html.INPUT(
|
||||
type="password", size="36", name="password",
|
||||
),
|
||||
' ',
|
||||
])
|
||||
|
||||
self.make_row(_('Password repeat'), [
|
||||
html.INPUT(
|
||||
type="password", size="36", name="password2",
|
||||
),
|
||||
' ', _('(Only when changing passwords)'),
|
||||
])
|
||||
|
||||
self.make_row(_('Email'), [
|
||||
html.INPUT(
|
||||
type="text", size="36", name="email", value=self.request.user.email
|
||||
),
|
||||
' ',
|
||||
])
|
||||
|
||||
# Show options only if already logged in
|
||||
if self.request.user.valid:
|
||||
|
||||
if not self.cfg.theme_force:
|
||||
if not self.cfg.theme_force and not "theme_name" in self.cfg.user_form_remove:
|
||||
self.make_row(_('Preferred theme'), [self._theme_select()])
|
||||
|
||||
self.make_row(_('User CSS URL'), [
|
||||
html.INPUT(
|
||||
type="text", size="40", name="css_url", value=self.request.user.css_url
|
||||
),
|
||||
' ', _('(Leave it empty for disabling user CSS)'),
|
||||
])
|
||||
if not self.cfg.editor_force:
|
||||
if not "editor_default" in self.cfg.user_form_remove:
|
||||
self.make_row(_('Editor Preference'), [self._editor_default_select()])
|
||||
if not "editor_ui" in self.cfg.user_form_remove:
|
||||
self.make_row(_('Editor shown on UI'), [self._editor_ui_select()])
|
||||
|
||||
self.make_row(_('Editor size'), [
|
||||
html.INPUT(type="text", size="3", maxlength="3",
|
||||
name="edit_rows", value=str(self.request.user.edit_rows)),
|
||||
])
|
||||
if not "tz_offset" in self.cfg.user_form_remove:
|
||||
self.make_row(_('Time zone'), [
|
||||
_('Your time is'), ' ',
|
||||
self._tz_select(),
|
||||
html.BR(),
|
||||
_('Server time is'), ' ',
|
||||
time.strftime(self.cfg.datetime_fmt, timefuncs.tmtuple()),
|
||||
' (UTC)',
|
||||
])
|
||||
|
||||
self.make_row(_('Time zone'), [
|
||||
_('Your time is'), ' ',
|
||||
self._tz_select(),
|
||||
html.BR(),
|
||||
_('Server time is'), ' ',
|
||||
time.strftime(self.cfg.datetime_fmt, util.datetime.tmtuple()),
|
||||
' (UTC)',
|
||||
])
|
||||
if not "datetime_fmt" in self.cfg.user_form_remove:
|
||||
self.make_row(_('Date format'), [self._dtfmt_select()])
|
||||
|
||||
self.make_row(_('Date format'), [self._dtfmt_select()])
|
||||
|
||||
self.make_row(_('Preferred language'), [self._lang_select()])
|
||||
if not "language" in self.cfg.user_form_remove:
|
||||
self.make_row(_('Preferred language'), [self._lang_select()])
|
||||
|
||||
# boolean user options
|
||||
bool_options = []
|
||||
checkbox_fields = user.User._checkbox_fields
|
||||
checkbox_fields = self.cfg.user_checkbox_fields
|
||||
_ = self.request.getText
|
||||
checkbox_fields.sort(lambda a, b: cmp(a[1](_), b[1](_)))
|
||||
for key, label in checkbox_fields:
|
||||
bool_options.extend([
|
||||
html.INPUT(type="checkbox", name=key, value="1",
|
||||
checked=getattr(self.request.user, key, 0)),
|
||||
' ', label(_), html.BR(),
|
||||
])
|
||||
if not key in self.cfg.user_checkbox_remove:
|
||||
bool_options.extend([
|
||||
html.INPUT(type="checkbox", name=key, value="1",
|
||||
checked=getattr(self.request.user, key, 0),
|
||||
disabled=key in self.cfg.user_checkbox_disable and True or None),
|
||||
' ', label(_), html.BR(),
|
||||
])
|
||||
self.make_row(_('General options'), bool_options, valign="top")
|
||||
|
||||
self.make_row(_('Quick links'), [
|
||||
|
@ -502,7 +557,7 @@ class UserSettings:
|
|||
], valign="top")
|
||||
|
||||
# subscribed pages
|
||||
if self.cfg.mail_smarthost:
|
||||
if self.cfg.mail_enabled:
|
||||
# Get list of subscribe pages, DO NOT sort! it should
|
||||
# stay in the order the user entered it in his input
|
||||
# box.
|
||||
|
@ -524,24 +579,114 @@ class UserSettings:
|
|||
] + warning,
|
||||
valign="top"
|
||||
)
|
||||
else: # not logged in
|
||||
# Login / register interface
|
||||
buttons = [
|
||||
# IMPORTANT: login should be first to be the default
|
||||
# button when a user hits ENTER.
|
||||
#('login', _('Login')), # we now have a Login macro
|
||||
('create', _('Create Profile')),
|
||||
('cancel', _('Cancel')),
|
||||
]
|
||||
for key, label, type, length, textafter in self.cfg.user_form_fields:
|
||||
if key in ('name', 'password', 'password2', 'email'):
|
||||
self.make_row(_(label),
|
||||
[ html.INPUT(type=type, size=length, name=key,
|
||||
value=''),
|
||||
' ', _(textafter), ])
|
||||
|
||||
if self.cfg.mail_enabled:
|
||||
buttons.append(("account_sendmail", _('Mail me my account data')))
|
||||
|
||||
if create_only:
|
||||
buttons = [("create_only", _('Create Profile'))]
|
||||
if self.cfg.mail_enabled:
|
||||
buttons.append(("create_and_mail", "%s + %s" %
|
||||
(_('Create Profile'), _('Email'))))
|
||||
|
||||
# Add buttons
|
||||
button_cell = []
|
||||
for name, label in buttons:
|
||||
button_cell.extend([
|
||||
html.INPUT(type="submit", name=name, value=label),
|
||||
' ',
|
||||
])
|
||||
if not name in self.cfg.user_form_remove:
|
||||
button_cell.extend([
|
||||
html.INPUT(type="submit", name=name, value=label),
|
||||
' ',
|
||||
])
|
||||
self.make_row('', button_cell)
|
||||
|
||||
return unicode(self._form)
|
||||
|
||||
|
||||
def getUserForm(request):
|
||||
def getUserForm(request, create_only=False):
|
||||
""" Return HTML code for the user settings. """
|
||||
return UserSettings(request).asHTML()
|
||||
return UserSettings(request).asHTML(create_only=create_only)
|
||||
|
||||
|
||||
class Login:
|
||||
""" User login. """
|
||||
|
||||
def __init__(self, request):
|
||||
""" Initialize user settings form.
|
||||
"""
|
||||
self.request = request
|
||||
self._ = request.getText
|
||||
self.cfg = request.cfg
|
||||
|
||||
def make_row(self, label, cell, **kw):
|
||||
""" Create a row in the form table.
|
||||
"""
|
||||
self._table.append(html.TR().extend([
|
||||
html.TD(**kw).extend([html.B().append(label), ' ']),
|
||||
html.TD().extend(cell),
|
||||
]))
|
||||
|
||||
|
||||
def asHTML(self):
|
||||
""" Create the complete HTML form code. """
|
||||
_ = self._
|
||||
request = self.request
|
||||
sn = request.getScriptname()
|
||||
pi = request.getPathinfo()
|
||||
action = u"%s%s" % (sn, pi)
|
||||
userprefslink = wikiutil.getSysPage(request, "UserPreferences").link_to(request)
|
||||
hint = _("To create an account or recover a lost password, see the %(userprefslink)s page.") % {
|
||||
'userprefslink': userprefslink}
|
||||
self._form = html.FORM(action=action)
|
||||
self._table = html.TABLE(border="0")
|
||||
|
||||
# Use the user interface language and direction
|
||||
lang_attr = request.theme.ui_lang_attr()
|
||||
self._form.append(html.Raw('<div class="userprefs"%s>' % lang_attr))
|
||||
|
||||
self._form.append(html.INPUT(type="hidden", name="action", value="login"))
|
||||
self._form.append(self._table)
|
||||
self._form.append(html.P().append(hint))
|
||||
self._form.append(html.Raw("</div>"))
|
||||
|
||||
self.make_row(_('Name'), [
|
||||
html.INPUT(
|
||||
type="text", size="32", name="name",
|
||||
),
|
||||
])
|
||||
|
||||
self.make_row(_('Password'), [
|
||||
html.INPUT(
|
||||
type="password", size="32", name="password",
|
||||
),
|
||||
])
|
||||
|
||||
self.make_row('', [
|
||||
html.INPUT(
|
||||
type="submit", name='login', value=_('Login')
|
||||
),
|
||||
])
|
||||
|
||||
return unicode(self._form)
|
||||
|
||||
def getLogin(request):
|
||||
""" Return HTML code for the login. """
|
||||
return Login(request).asHTML()
|
||||
|
||||
#############################################################################
|
||||
### User account administration
|
||||
#############################################################################
|
||||
|
@ -557,7 +702,7 @@ def do_user_browser(request):
|
|||
#Column('id', label=('ID'), align='right'),
|
||||
Column('name', label=('Username')),
|
||||
Column('email', label=('Email')),
|
||||
#Column('action', label=_('Action')),
|
||||
Column('action', label=_('Action')),
|
||||
]
|
||||
|
||||
# Iterate over users
|
||||
|
@ -573,10 +718,14 @@ def do_user_browser(request):
|
|||
data.addRow((
|
||||
#request.formatter.code(1) + uid + request.formatter.code(0),
|
||||
request.formatter.rawHTML(namelink),
|
||||
(request.formatter.url(1, 'mailto:' + account.email, 'external', pretty_url=1, unescaped=1) +
|
||||
(request.formatter.url(1, 'mailto:' + account.email, css='mailto', do_escape=0) +
|
||||
request.formatter.text(account.email) +
|
||||
request.formatter.url(0)),
|
||||
#'',
|
||||
request.page.link_to(request, text=_('Mail me my account data'),
|
||||
querystr= {"action":"userform",
|
||||
"email": account.email,
|
||||
"account_sendmail": "1",
|
||||
"sysadm": "users",})
|
||||
))
|
||||
|
||||
if data:
|
||||
|
|
|
@ -8,13 +8,7 @@
|
|||
"""
|
||||
|
||||
import re
|
||||
from MoinMoin import user, search
|
||||
|
||||
#### HACK SAUVAGE 1/4
|
||||
import sys
|
||||
sys.path.append('/usr/scripts/gestion/')
|
||||
from iptools import is_crans
|
||||
#### FIN DU HACK 1/4
|
||||
from MoinMoin import user
|
||||
|
||||
class AccessControlList:
|
||||
''' Access Control List
|
||||
|
@ -93,10 +87,6 @@ class AccessControlList:
|
|||
|
||||
Configuration options
|
||||
|
||||
cfg.acl_enabled
|
||||
If true will enable ACL support.
|
||||
Default: 0
|
||||
|
||||
cfg.acl_rights_default
|
||||
It is is ONLY used when no other ACLs are given.
|
||||
Default: "Known:read,write,delete All:read,write",
|
||||
|
@ -117,10 +107,7 @@ class AccessControlList:
|
|||
Default: ["read", "write", "delete", "admin"]
|
||||
'''
|
||||
|
||||
#special_users = ["All", "Known", "Trusted"]
|
||||
#### HACK SAUVAGE 2/4
|
||||
special_users = ["All", "Known", "Trusted", "Conf"]
|
||||
#### FIN DU HACK 2/4
|
||||
special_users = ["All", "Known", "Trusted"] # order is important
|
||||
|
||||
def __init__(self, request, lines=[]):
|
||||
"""Initialize an ACL, starting from <nothing>.
|
||||
|
@ -159,7 +146,6 @@ class AccessControlList:
|
|||
@param aclstring: acl string from page or cfg
|
||||
@param remember: should add the line to self.acl_lines
|
||||
"""
|
||||
# FIXME: should compile this once and cache (in cfg?)
|
||||
group_re = re.compile(cfg.page_group_regex)
|
||||
|
||||
# Remember lines
|
||||
|
@ -195,17 +181,6 @@ class AccessControlList:
|
|||
"""May <name> <dowhat>?
|
||||
Returns boolean answer.
|
||||
"""
|
||||
if not request.cfg.acl_enabled:
|
||||
# everybody may read and write:
|
||||
if dowhat in ["read", "write",]:
|
||||
return 1
|
||||
# only known users may do some more dangerous things:
|
||||
if request.user.valid:
|
||||
if dowhat in ["delete", "revert",]:
|
||||
return 1
|
||||
# in any other case, we better disallow it:
|
||||
return 0
|
||||
|
||||
is_group_member = request.dicts.has_member
|
||||
|
||||
allowed = None
|
||||
|
@ -213,8 +188,16 @@ class AccessControlList:
|
|||
if entry in self.special_users:
|
||||
handler = getattr(self, "_special_"+entry, None)
|
||||
allowed = handler(request, name, dowhat, rightsdict)
|
||||
elif self._is_group.get(entry) and is_group_member(entry, name):
|
||||
allowed = rightsdict.get(dowhat)
|
||||
elif self._is_group.get(entry):
|
||||
if is_group_member(entry, name):
|
||||
allowed = rightsdict.get(dowhat)
|
||||
else:
|
||||
for special in self.special_users:
|
||||
if is_group_member(entry, special):
|
||||
handler = getattr(self, "_special_"+ special, None)
|
||||
allowed = handler(request, name,
|
||||
dowhat, rightsdict)
|
||||
break # order of self.special_users is important
|
||||
elif entry == name:
|
||||
allowed = rightsdict.get(dowhat)
|
||||
if allowed is not None:
|
||||
|
@ -226,8 +209,6 @@ class AccessControlList:
|
|||
return ''.join(["%s%s%s" % (b,l,e) for l in self.acl_lines])
|
||||
|
||||
def _special_All(self, request, name, dowhat, rightsdict):
|
||||
if dowhat == "read" and self.is_page_public(request):
|
||||
return True
|
||||
return rightsdict.get(dowhat)
|
||||
|
||||
def _special_Known(self, request, name, dowhat, rightsdict):
|
||||
|
@ -239,11 +220,6 @@ class AccessControlList:
|
|||
return rightsdict.get(dowhat)
|
||||
return None
|
||||
|
||||
#### HACK SAUVAGE 3/4
|
||||
def _special_Conf(self, request, name, dowhat, rightsdict):
|
||||
return request.cfg.acl_request(self, request, name, dowhat, rightsdict)
|
||||
#### FIN Du HACK 3/4
|
||||
|
||||
def _special_Trusted(self, request, name, dowhat, rightsdict):
|
||||
""" check if user <name> is known AND even has logged in using a password.
|
||||
does not work for subsription emails that should be sent to <user>,
|
||||
|
@ -258,22 +234,6 @@ class AccessControlList:
|
|||
def __ne__(self, other):
|
||||
return self.acl_lines != other.acl_lines
|
||||
|
||||
#### HACK SAUVAGE 4/4
|
||||
def is_page_public(self,request):
|
||||
## On recherche si la page est publique
|
||||
if not request.page:
|
||||
return False
|
||||
this_page = request.page.page_name
|
||||
query = search.QueryParser().parse_query(u'CatégoriePagePublique')
|
||||
page = search.Page(request, this_page)
|
||||
result = query.search(page)
|
||||
if result:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
#### FIN DU HACK 4/4
|
||||
|
||||
|
||||
|
||||
class ACLStringIterator:
|
||||
""" Iterator for acl string
|
||||
|
@ -291,7 +251,7 @@ class ACLStringIterator:
|
|||
""" Initialize acl iterator
|
||||
|
||||
@param rights: the acl rights to consider when parsing
|
||||
@param aclstirng: string to parse
|
||||
@param aclstring: string to parse
|
||||
"""
|
||||
self.rights = rights
|
||||
self.rest = aclstring.strip()
|
||||
|
@ -331,7 +291,6 @@ class ACLStringIterator:
|
|||
else:
|
||||
# Get entries
|
||||
try:
|
||||
# XXX TODO disallow : and , in usernames
|
||||
entries, self.rest = self.rest.split(':', 1)
|
||||
except ValueError:
|
||||
self.finished = 1
|
||||
|
@ -360,9 +319,6 @@ def parseACL(request, body):
|
|||
|
||||
Use ACL object may(request, dowhat) to get acl rights.
|
||||
"""
|
||||
if not request.cfg.acl_enabled:
|
||||
return AccessControlList(request)
|
||||
|
||||
acl_lines = []
|
||||
while body and body[0] == '#':
|
||||
# extract first line
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue