Attachment 'userform.rs.py'

Download

   1 # -*- coding: iso-8859-1 -*-
   2 """
   3     MoinMoin - User Account Maintenance
   4 
   5     Copyright (c) 2000, 2001, 2002 by Jürgen Hermann <jh@web.de>
   6     All rights reserved, see COPYING for details.
   7 
   8     $Id: userform.py,v 1.54 2003/11/09 21:00:51 thomaswaldmann Exp $
   9     ORS modifications:
  10         13.01.04 RS auto-create homepage for new user
  11 
  12 """
  13 
  14 # Imports
  15 import os, string, time, cgi, re, sha, Cookie
  16 from MoinMoin import config, user, util, webapi, wikiutil
  17 import MoinMoin.util.web
  18 import MoinMoin.util.mail
  19 import MoinMoin.util.datetime
  20 from MoinMoin.widget import html
  21 #RS auto-create homepage for new user
  22 from MoinMoin.Page import Page
  23 from MoinMoin.PageEditor import PageEditor
  24 #RS end
  25 _debug = 0
  26 
  27 
  28 #############################################################################
  29 ### Form POST Handling
  30 #############################################################################
  31 
  32 def savedata(pagename, request):
  33     """ Handle POST request of the user preferences form.
  34 
  35         Return error msg or None.
  36     """
  37     return UserSettingsHandler(request).handleData()
  38 
  39 
  40 class UserSettingsHandler:
  41 
  42     def __init__(self, request):
  43         """ Initialize user settings form.
  44         """
  45         self.request = request
  46         self._ = request.getText
  47 
  48 
  49     def handleData(self):
  50         _ = self._
  51         form = self.request.form
  52     
  53         if form.has_key('logout'):
  54             # clear the cookie in the browser and locally
  55             try:
  56                 cookie = Cookie.SimpleCookie(os.environ.get('HTTP_COOKIE', ''))
  57             except Cookie.CookieError:
  58                 # ignore invalid cookies
  59                 cookie = None
  60             else:
  61                 if cookie.has_key('MOIN_ID'):
  62                     uid = cookie['MOIN_ID'].value
  63                     webapi.setHttpHeader(self.request, 'Set-Cookie: MOIN_ID=%s; expires=Tuesday, 01-Jan-1999 12:00:00 GMT; Path=%s' % (
  64                         cookie['MOIN_ID'].value, webapi.getScriptname(),))
  65             os.environ['HTTP_COOKIE'] = ''
  66             self.request.auth_username = ''
  67             self.request.user = user.User(self.request)
  68             user.current = self.request.user
  69             return _("<b>Cookie deleted. You are now logged out.</b>")
  70     
  71         if form.has_key('login_sendmail'):
  72             try:
  73                 email = form['login_email'].value
  74             except KeyError:
  75                 return _("<b>Please provide a valid email address!</b>")
  76     
  77             text = ''
  78             users = user.getUserList()
  79             for uid in users:
  80                 theuser = user.User(self.request, uid)
  81                 if theuser.valid and theuser.email == email:
  82                     text = "%s\n\nID: %s\nName: %s\nPassword: %s\nLogin URL: %s?action=userform&uid=%s" % (
  83                         text, theuser.id, theuser.name, theuser.enc_password, webapi.getBaseURL(), theuser.id)
  84    
  85             if not text:
  86                 return _("<b>Found no account matching the given "
  87                     "email address '%(email)s'!</b>") % {'email': email}
  88     
  89             mailok, msg = util.mail.sendmail(self.request, [email], 
  90                 'Your wiki account data', text, mail_from=email)
  91             return "<b>%s</b>" % cgi.escape(msg)
  92     
  93         if form.has_key('login') or form.has_key('uid'):
  94             # check for "uid" value that we use in the relogin URL
  95             try:
  96                  uid = form['uid'].value
  97             except KeyError:
  98                  uid = None
  99 
 100             # try to get the user name
 101             try:
 102                 name = form['username'].value.replace('\t', ' ').strip()
 103             except KeyError:
 104                 name = ''
 105 
 106             # try to get the password
 107             password = form.getvalue('password','')
 108   
 109             # load the user data and check for validness
 110             theuser = user.User(self.request, uid, name=name, password=password)
 111             if not theuser.valid:
 112                 return _("<b>Unknown user name or password.</b>")
 113 
 114             # send the cookie
 115             theuser.sendCookie(self.request)
 116             self.request.user = theuser
 117             user.current = theuser
 118         else:
 119             # save user's profile, first get user instance
 120             theuser = user.User(self.request)
 121     
 122             # try to get the name, if name is empty or missing, return an error msg
 123             try:
 124                 theuser.name = form['username'].value.replace('\t', ' ').strip()
 125             except KeyError:
 126                 return _("<b>Please enter a user name!</b>")
 127     
 128             # Is this an existing user trying to change password, or a new user?
 129             newuser = 1
 130             if user.getUserId(theuser.name):
 131                 if theuser.name != user.current.name:
 132                     return _("<b>User name already exists!</b>")
 133                 else:
 134                     newuser = 0
 135 
 136             # try to get the (optional) password and pw repeat
 137             password = form.getvalue('password', '')
 138             password2 = form.getvalue('password2','')
 139 
 140             # Check if password and password repeat match
 141             if password != password2:
 142                 return _("<b>Passwords don't match!</b>")
 143             elif password and not password.startswith('{SHA}'):
 144                 theuser.enc_password = user.encodePassword(password)
 145 
 146             # try to get the (optional) email
 147             theuser.email = form.getvalue('email', '')
 148     
 149             # editor size
 150             theuser.edit_rows = util.web.getIntegerInput(self.request, 'edit_rows', theuser.edit_rows, 10, 60)
 151             theuser.edit_cols = util.web.getIntegerInput(self.request, 'edit_cols', theuser.edit_cols, 30, 100)
 152     
 153             # time zone
 154             theuser.tz_offset = util.web.getIntegerInput(self.request, 'tz_offset', theuser.tz_offset, -84600, 84600)
 155     
 156             # date format
 157             try:
 158                 theuser.datetime_fmt = UserSettings._date_formats.get(form['datetime_fmt'].value, '')
 159             except (KeyError, ValueError):
 160                 pass
 161     
 162             # CSS URL
 163             theuser.css_url = form.getvalue('css_url', '')
 164             if theuser.css_url == config.css_url:
 165                 theuser.css_url = ''
 166     
 167             # try to get the (optional) preferred language
 168             theuser.language = form.getvalue('language', '')
 169     
 170             # checkbox options
 171             for key, label in user.User._checkbox_fields:
 172                 value = form.getvalue(key, 0)
 173                 try:
 174                     value = int(value)
 175                 except ValueError:
 176                     pass
 177                 else:
 178                     setattr(theuser, key, value)
 179     
 180             # quicklinks for header
 181             quicklinks = form.getvalue('quicklinks', '')
 182             quicklinks = quicklinks.replace('\r', '')
 183             quicklinks = quicklinks.split('\n')
 184             quicklinks = map(string.strip, quicklinks)
 185             quicklinks = filter(None, quicklinks)
 186             quicklinks = map(wikiutil.quoteWikiname, quicklinks)
 187             theuser.quicklinks = ','.join(quicklinks)
 188             
 189             # subscription for page change notification
 190             theuser.subscribed_pages = form.getvalue('subscribed_pages', '')
 191             theuser.subscribed_pages = theuser.subscribed_pages.replace('\r', '')
 192             theuser.subscribed_pages = theuser.subscribed_pages.replace('\n', ',')
 193             
 194             # if we use ACLs, name and email are required to be unique
 195             # further, name is required to be a WikiName (CamelCase!)
 196             # see also MoinMoin/scripts/moin_usercheck.py
 197             if config.acl_enabled:
 198                 theuser.name = theuser.name.replace(' ','') # strip spaces, we don't allow them anyway
 199                 if not re.match("(?:[%(u)s][%(l)s]+){2,}" % {'u': config.upperletters, 'l': config.lowerletters}, theuser.name):
 200                     return _("<b>Please enter your name like that: FirstnameLastname</b>")
 201                 if not theuser.email or not re.match(".+@.+\..{2,}", theuser.email):
 202                     return _("<b>Please provide your email address - without that you could not get your login data via email just in case you lose it.</b>")
 203                 users = user.getUserList()
 204                 for uid in users:
 205                     if uid == theuser.id:
 206                         continue
 207                     thisuser = user.User(self.request, uid)
 208                     if thisuser.name == theuser.name:
 209                         return _("<b>This user name already belongs to somebody else.</b>")
 210                     if theuser.email and thisuser.email == theuser.email:
 211                         return _("<b>This email already belongs to somebody else.</b>")
 212             # save data and send cookie
 213             theuser.save()
 214             theuser.sendCookie(self.request)
 215             self.request.user = theuser
 216             user.current = theuser
 217     
 218             result = _("<b>User preferences saved!</b>")
 219 #RS auto-create homepage for new user
 220             if newuser:
 221                 if wikiutil.getHomePage(self.request,theuser.name)==None:
 222                     homepagename=theuser.name
 223                     thetemplate=Page("HomepageTemplate")
 224                     if thetemplate.exists():
 225                         tempbody=thetemplate.get_raw_body()
 226                         newhomepage = PageEditor(homepagename, self.request)
 227 ##                        newhomepage.sendEditor()
 228                         datestamp = '0'
 229                         newhomepage.saveText(tempbody, datestamp,
 230                                 stripspaces=0, notify=0, comment='Homepage created for new user')
 231                         result = _("<b>User preferences saved and homepage created for %s!</b>" % homepagename)
 232 
 233 #RS end
 234             if _debug:
 235                 result = result + util.dumpFormData(form)
 236             return result
 237 
 238 
 239 #############################################################################
 240 ### Form Generation
 241 #############################################################################
 242 
 243 class UserSettings:
 244     """ User login and settings management.
 245     """
 246 
 247     _date_formats = {
 248         'iso':  '%Y-%m-%d %H:%M:%S',
 249         'us':   '%m/%d/%Y %I:%M:%S %p',
 250         'euro': '%d.%m.%Y %H:%M:%S',
 251         'rfc':  '%a %b %d %H:%M:%S %Y',
 252     }
 253 
 254 
 255     def __init__(self, request):
 256         """ Initialize user settings form.
 257         """
 258         self.request = request
 259         self._ = request.getText
 260 
 261 
 262     def _tz_select(self):
 263         """ Create time zone selection.
 264         """
 265         tz = 0
 266         if self.request.user.valid:
 267             tz = int(self.request.user.tz_offset)
 268 
 269         options = []
 270         now = time.time()
 271         for halfhour in range(-47, 48):
 272             offset = halfhour * 1800
 273             t = now + offset
 274 
 275             options.append((
 276                 offset,
 277                 '%s [%s%s:%s]' % (
 278                     time.strftime(config.datetime_fmt, util.datetime.tmtuple(t)),
 279                     "+-"[offset < 0],
 280                     string.zfill("%d" % (abs(offset) / 3600), 2),
 281                     string.zfill("%d" % (abs(offset) % 3600 / 60), 2),
 282                 ),
 283             ))
 284  
 285         return util.web.makeSelection('tz_offset', options, tz)
 286 
 287 
 288     def _dtfmt_select(self):
 289         """ Create date format selection.
 290         """
 291         try:
 292             selected = [
 293                 k for k, v in self._date_formats.items()
 294                     if v == self.request.user.datetime_fmt][0]
 295         except IndexError:
 296             selected = ''
 297         options = [('', self._('Default'))] + self._date_formats.items()
 298 
 299         return util.web.makeSelection('datetime_fmt', options, selected)
 300 
 301 
 302     def _lang_select(self):
 303         """ Create language selection.
 304         """
 305         from MoinMoin.i18n import languages, NAME, ENCODING
 306 
 307         cur_lang = self.request.user.valid and self.request.user.language or ''
 308         langs = languages.items()
 309         langs.sort(lambda x,y,NAME=NAME: cmp(x[1][NAME], y[1][NAME]))
 310 
 311         options = [('', self._('<Browser setting>'))]
 312         for lang in langs:
 313             if config.charset.upper() == 'UTF-8' or \
 314                     lang[0] in ['', 'en'] or \
 315                     lang[1][ENCODING] == config.charset:
 316                 options.append((lang[0], lang[1][NAME]))
 317  
 318         return util.web.makeSelection('language', options, cur_lang)
 319 
 320 
 321     def make_form(self):
 322         """ Create the FORM, and the TABLE with the input fields
 323         """
 324         self._form = html.FORM(action=webapi.getScriptname()+webapi.getPathinfo())
 325         self._table = html.TABLE(border=0)
 326 
 327         self._form.append(html.INPUT(type="hidden", name="action", value="userform"))
 328         self._form.append(self._table)
 329 
 330 
 331     def make_row(self, label, cell, **kw):
 332         """ Create a row in the form table.
 333         """
 334         self._table.append(html.TR().extend([
 335             html.TD(**kw).extend([html.B().append(label), '\xA0']),
 336             html.TD().extend(cell),
 337         ]))
 338 
 339 
 340     def asHTML(self):
 341         """ Create the complete HTML form code.
 342         """
 343         self.make_form()
 344 
 345         # check user data
 346         if not self.request.user.css_url:
 347             self.request.user.css_url = config.css_url
 348 
 349         # different form elements depending on login state
 350         html_uid = ''
 351         if self.request.user.valid:
 352             html_uid = '<tr><td><b>ID</b>&nbsp;</td><td>%s</td></tr>' % (self.request.user.id,)
 353             buttons = [
 354                 ('save', self._(' Save ')),
 355                 ('logout', self._(' Logout ')),
 356             ]
 357 #            url = "%s?action=userform&uid=%s" % (webapi.getBaseURL(), self.request.user.id)
 358 #            html_relogin = self._('To login from a different machine, use this URL: ') + \
 359 #                '<a href="%s">%s</a><br>' % (url, url)
 360         else:
 361             buttons = [
 362                 ("save", self._(' Create Profile ')),
 363                 ('login', self._(' Login ')),
 364                 ]
 365 #           html_relogin = ""
 366 
 367             if config.mail_smarthost:
 368                 html_uid = """
 369                     <tr><td><b>%s</b>&nbsp;</td><td><input type="text" size="40" name="login_email"></td></tr>
 370                     <tr><td></td><td><input type="submit" name="login_sendmail" value="%s"></td></tr>
 371                 """ % (self._('Your email address'),
 372                        self._(' Mail me my account data '))
 373 
 374         self._table.append(html.Raw(html_uid))
 375 
 376         self.make_row(self._('Name'), [
 377             html.INPUT(
 378                 type="text", size=32, name="username", value=self.request.user.name
 379             ),
 380             ' \xA0 ', self._('(Use FirstnameLastname)'),
 381             ])
 382 
 383         self.make_row(self._('Password'), [
 384             html.INPUT(
 385                 type="password", size=32, name="password", value=self.request.user.enc_password
 386                 )
 387                 ])
 388 
 389         self.make_row(self._('Password repeat'), [
 390             html.INPUT(
 391                 type="password", size=32, name="password2", value=self.request.user.enc_password
 392                 ),
 393                 ' \xA0 ', self._('(Only when changing passwords)'),
 394                 ])
 395 
 396         self.make_row(self._('Email'), [html.INPUT(
 397             type="text", size=40, name="email", value=self.request.user.email
 398         )])
 399 
 400         self.make_row(self._('CSS URL'), [
 401             html.INPUT(
 402                 type="text", size=40, name="css_url", value=self.request.user.css_url
 403             ),
 404             ' \xA0 ', self._('("None" for disabling CSS)'),
 405         ])
 406 
 407         self.make_row(self._('Editor size'), [
 408             html.INPUT(type="text", size=3, maxlength=3,
 409                 name="edit_cols", value=self.request.user.edit_cols),
 410             ' \xA0x\xA0 ',
 411             html.INPUT(type="text", size=3, maxlength=3,
 412                 name="edit_rows", value=self.request.user.edit_rows),
 413         ])
 414 
 415         self.make_row(self._('Time zone'), [
 416             self._('Your time is'), ' ',
 417             self._tz_select(),
 418             html.BR(),
 419             self._('Server time is'), ' ',
 420             time.strftime(config.datetime_fmt, util.datetime.tmtuple()),
 421             ' (UTC)',
 422         ])
 423 
 424         self.make_row(self._('Date format'), [self._dtfmt_select()])
 425 
 426         self.make_row(self._('Preferred language'), [self._lang_select()])
 427 
 428         # boolean user options
 429         bool_options = []
 430         checkbox_fields = user.User._checkbox_fields
 431         checkbox_fields.sort(lambda a, b: cmp(a[1](), b[1]()))
 432         for key, label in checkbox_fields:
 433             bool_options.extend([
 434                 html.INPUT(type="checkbox", name=key, value=1,
 435                     checked=getattr(self.request.user, key, 0)),
 436                 '\xA0', label(), html.BR(),
 437             ])
 438         self.make_row(self._('General options'), bool_options)
 439 
 440         self.make_row(self._('Quick links'), valign="top", cell=[
 441             html.TEXTAREA(name="quicklinks", rows=6, cols=50)
 442                 .append('\n'.join(self.request.user.getQuickLinks())),
 443         ])
 444 
 445         # subscribed pages
 446         if config.mail_smarthost:
 447             notifylist = self.request.user.getSubscriptionList()
 448             notifylist.sort()
 449 
 450             warning = []
 451             if not self.request.user.email:
 452                 warning = [
 453                     html.BR(),
 454                     html.SMALL(Class="warning").append(
 455                         self._("This list does not work, unless you have"
 456                           " entered a valid email address!")
 457                     )]
 458             
 459             self.make_row(
 460                 html.Raw(self._('Subscribed wiki pages<br>(one regex per line)')),
 461                 valign="top",
 462                 cell=[
 463                     html.TEXTAREA(name="subscribed_pages", rows=6, cols=50)
 464                         .append('\n'.join(notifylist)),
 465                 ] + warning
 466             )
 467 
 468         # add buttons
 469         button_cell = []
 470         for name, label in buttons:
 471             button_cell.extend([
 472                 html.INPUT(type="submit", name=name, value=label),
 473                 ' \xA0 ',
 474             ])
 475         self.make_row('', button_cell)
 476 
 477         return str(self._form)
 478 # + html_relogin
 479 
 480 
 481 def getUserForm(request):
 482     """ Return HTML code for the user settings.
 483     """
 484     return UserSettings(request).asHTML()
 485 
 486 
 487 #############################################################################
 488 ### User account administration
 489 #############################################################################
 490 
 491 def do_user_browser(request):
 492     """ Browser for SystemAdmin macro.
 493     """
 494     from MoinMoin.util.dataset import TupleDataset, Column
 495     _ = request.getText
 496 
 497     data = TupleDataset()
 498     data.columns = [
 499         Column('id', label=('ID'), align='right'),
 500         Column('name', label=('Username')),
 501         Column('email', label=('Email')),
 502         Column('action', label=_('Action')),
 503     ]
 504 
 505     # iterate over users
 506     for uid in user.getUserList():
 507         account = user.User(request, uid)
 508         data.addRow((
 509             request.formatter.code(1) + uid + request.formatter.code(0),
 510             request.formatter.text(account.name),
 511             request.formatter.text(account.email),
 512             '',
 513         ))
 514 
 515     if data:
 516         from MoinMoin.widget.browser import DataBrowserWidget
 517 
 518         browser = DataBrowserWidget(request)
 519         browser.setData(data)
 520         return browser.toHTML()
 521 
 522     # no data
 523     return ''

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2004-01-16 15:17:51, 19.0 KB) [[attachment:userform.rs.py]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.