def _handle_name_continuation(self, request): _ = request.getText logging.debug('openid %s' % request.session) logging.debug('openid %s' % request.form.get('openid_identifier')) if not 'openid.id' in request.session: return CancelLogin(_('No OpenID found in session.')) newname = request.form.get('username', '') if not newname: return MultistageFormLogin(self._get_account_name) if not user.isValidName(request, newname): return MultistageFormLogin(self._get_account_name_inval_user) uid = None if newname: uid = user.getUserId(request, newname) if not uid: # we can create a new user with this name :) u = user.User(request, auth_method=self.name, auth_username=request.session['openid.id'], auth_attribs=self.auth_attribs) u.name = newname u = self._handle_user_data(request, u) return ContinueLogin(u) # requested username already exists. if they know the password, # they can associate that account with the openid. assoc = lambda req, form: self._associate_account(req, form, newname) return MultistageFormLogin(assoc)
def _handle_user_data(self, request, u): create = not u if create: # pass in a created but unsaved user object u = user.User(request, auth_method=self.name, auth_username=request.session['openid.id'], auth_attribs=self.auth_attribs) # invalid name u.name = '' u = self._create_user(request.session['openid.info'], u, request.cfg) if u: self._update_user(request.session['openid.info'], u, request.cfg) # just in case the wiki admin screwed up if (not user.isValidName(request, u.name) or (create and user.getUserId(request, u.name))): return None if not hasattr(u, 'openids'): u.openids = [] if not request.session['openid.id'] in u.openids: u.openids.append(request.session['openid.id']) u.save() del request.session['openid.id'] del request.session['openid.info'] return u
def _handle_name_continuation(self, request): _ = request.getText if not 'openid.id' in request.session: return CancelLogin(_('No OpenID found in session.')) newname = request.form.get('username', '') if not newname: return MultistageFormLogin(self._get_account_name) if not user.isValidName(request, newname): return MultistageFormLogin(self._get_account_name_inval_user) uid = None if newname: uid = user.getUserId(request, newname) if not uid: # we can create a new user with this name :) u = user.User(request, auth_method=self.name, auth_username=request.session['openid.id'], auth_attribs=self.auth_attribs) u.name = newname u = self._handle_user_data(request, u) return ContinueLogin(u) # requested username already exists. if they know the password, # they can associate that account with the openid. assoc = lambda req, form: self._associate_account(req, form, newname) return MultistageFormLogin(assoc)
def _handle_user_data(self, request, u): create = not u if create: # pass in a created but unsaved user object u = user.User(request, auth_method=self.name, auth_username=request.session["openid.id"]) # invalid name u.name = "" u = self._create_user(request.session["openid.info"], u) if u: self._update_user(request.session["openid.info"], u) # just in case the wiki admin screwed up if not user.isValidName(request, u.name) or (create and user.getUserId(request, u.name)): return None if not hasattr(u, "openids"): u.openids = [] if not request.session["openid.id"] in u.openids: u.openids.append(request.session["openid.id"]) u.save() del request.session["openid.id"] del request.session["openid.info"] return u
def _invite(request, page_url, email, new_template, old_template, **custom_vars): mail_from = request.user.email if "@" not in mail_from: mail_from += "@" + request.cfg.invite_sender_default_domain variables = dict(custom_vars) variables.update( PAGEURL=page_url, ADMINEMAIL=request.cfg.mail_from, INVITERUSER=request.user.name, INVITEREMAIL=mail_from, SERVERURL=request.host_url, ) old_user = user.get_by_email_address(request, email) if old_user: variables.update(INVITEDUSER=old_user.name, INVITEDEMAIL=old_user.email) if not old_template: old_template = getattr(request.cfg, OLD_TEMPLATE_VARIABLE, OLD_TEMPLATE_DEFAULT) template = load_template(request, old_template) send_message(request, prepare_message(template, variables)) return old_user force_lower = getattr(request.cfg, "username_force_lowercase", False) if force_lower: email = email.lower() if not user.isValidName(request, email): exception_msg = "'{0}' is not a valid username.".format(email) if force_lower: exception_msg += " (email address was converted to lowercase)" raise InviteException(exception_msg) password = generate_password() new_user = user.User(request, None, email, password) new_user.email = email new_user.aliasname = "" new_user.password = password variables.update(INVITEDUSER=new_user.name, INVITEDEMAIL=new_user.email, INVITEDPASSWORD=password) if not new_template: new_template = getattr(request.cfg, NEW_TEMPLATE_VARIABLE, NEW_TEMPLATE_DEFAULT) template = load_template(request, new_template) send_message(request, prepare_message(template, variables), lambda x: x.lower() == email.lower()) variables.update(INVITEDPASSWORD="******") send_message(request, prepare_message(template, variables), lambda x: x.lower() != email.lower()) new_user.save() logging.info( "New user %s added to wiki %s (invited by %s)" % (new_user.name, request.cfg.interwikiname, request.user.name) ) return new_user
def _create_user(request): collab_mode = getattr(request.cfg, 'collab_mode', False) _ = request.getText form = request.form if request.method != 'POST': return if not wikiutil.checkTicket(request, form.get('ticket', '')): return if not TextCha(request).check_answer_from_form(): return _('TextCha: Wrong answer! Go back and try again...') # Create user profile theuser = user.User(request, auth_method="new-user") # Require non-empty name try: if collab_mode: name = wikiutil.clean_input(form.get('email', [''])) theuser.name = name.strip() else: theuser.name = form['name'] except KeyError: return _("Empty user name. Please enter a user name.") # Don't allow creating users with invalid names if not user.isValidName(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.""", wiki=True) % wikiutil.escape(theuser.name) # Name required to be unique. Check if name belong to another user. if user.getUserId(request, theuser.name): return _("This user name already belongs to somebody else.") # try to get the password and pw repeat password = form.get('password1', '') password2 = form.get('password2', '') # Check if password is given and matches with password repeat if password != password2: return _("Passwords don't match!") if not password: return _("Please specify a password!") pw_checker = request.cfg.password_checker if pw_checker: pw_error = pw_checker(request, theuser.name, password) if pw_error: return _("Password not acceptable: %s") % wikiutil.escape(pw_error) # Encode password try: theuser.enc_password = user.encodePassword(request.cfg, password) except UnicodeError, err: # Should never happen return "Can't encode password: %s" % wikiutil.escape(str(err))
def testGroupNames(self): """ user: isValidName: reject group names """ test = u'AdminGroup' assert self.group.search(test) result = user.isValidName(request, test) expected = False self.assertEqual(result, expected, 'Expected "%(expected)s" but got "%(result)s"' % locals())
def testWhitespace(self): """ user: isValidName: reject leading, trailing or multiple whitespace """ cases = ( u' User Name', u'User Name ', u'User Name', ) for test in cases: assert not user.isValidName(self.request, test)
def _create_user(request): _ = request.getText form = request.form if request.method != 'POST': return if not wikiutil.checkTicket(request, form.get('ticket', '')): return if not TextCha(request).check_answer_from_form(): return _('TextCha: Wrong answer! Go back and try again...') # Create user profile theuser = user.User(request, auth_method="new-user") # Require non-empty name try: theuser.name = form['name'] except KeyError: return _("Empty user name. Please enter a user name.") # Don't allow creating users with invalid names if not user.isValidName(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.""", wiki=True) % wikiutil.escape(theuser.name) # Name required to be unique. Check if name belong to another user. if user.getUserId(request, theuser.name): return _("This user name already belongs to somebody else.") # try to get the password and pw repeat password = form.get('password1', '') password2 = form.get('password2', '') # Check if password is given and matches with password repeat if password != password2: return _("Passwords don't match!") if not password: return _("Please specify a password!") pw_checker = request.cfg.password_checker if pw_checker: pw_error = pw_checker(request, theuser.name, password) if pw_error: return _("Password not acceptable: %s") % wikiutil.escape(pw_error) # 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" % wikiutil.escape(str(err))
def testValid(self): """ user: isValidName: accept names in any language, with spaces """ cases = ( u'Jürgen Hermann', # German u'ניר סופר', # Hebrew u'CamelCase', # Good old camel case u'가각간갇갈 갉갊감 갬갯걀갼' # Hangul (gibberish) ) for test in cases: assert user.isValidName(self.request, test)
def testNonAlnumCharacters(self): """ user: isValidName: reject unicode non alpha numeric characters : and , used in acl rules, we might add more characters to the syntax. """ invalid = u'! # $ % ^ & * ( ) = + , : ; " | ~ / \\ \u0000 \u202a'.split() base = u'User%sName' for c in invalid: name = base % c assert not user.isValidName(self.request, name)
def testNonAlnumCharacters(self): """ user: isValidName: reject unicode non alpha numeric characters : and , used in acl rules, we might add more characters to the syntax. """ invalid = u'! # $ % ^ & * ( ) = + , : ; " | ~ / \\ \u0000 \u202a'.split( ) base = u'User%sName' for c in invalid: name = base % c assert not user.isValidName(self.request, name)
def testWhitespace(self): """ user: isValidName: reject leading, trailing or multiple whitespace """ cases = ( u' User Name', u'User Name ', u'User Name', ) expected = False for test in cases: result = user.isValidName(request, test) self.assertEqual(result, expected, 'Expected "%(expected)s" but got "%(result)s"' % locals())
def testNonAlnumCharacters(self): """ user: isValidName: reject unicode non alpha numeric characters : and , used in acl rules, we might add more characters to the syntax. """ invalid = u'! @ # $ % ^ & * ( ) - = + , : ; " | ~ / \\ \u0000 \u202a'.split() base = u'User%sName' expected = False for c in invalid: name = base % c result = user.isValidName(request, name) self.assertEqual(result, expected, 'Expected "%(expected)s" but got "%(result)s"' % locals())
def testValid(self): """ user: isValidName: accept names in any language, with spaces """ cases = ( u'Jürgen Hermann', # German u'ניר סופר', # Hebrew u'CamelCase', # Good old camel case u'가각간갇갈 갉갊감 갬갯걀갼' # Hangul (gibberish) ) expected = True for test in cases: result = user.isValidName(request, test) self.assertEqual(result, expected, 'Expected "%(expected)s" but got "%(result)s"' % locals())
def handle_form(self): _ = self._ request = self.request form = request.form if form.has_key('cancel'): return if request.method != 'POST': return if not wikiutil.checkTicket(request, form['ticket']): return user_name = form.get('user_name', '') if user_name: uid = user.getUserId(request, user_name) if uid: theuser = user.User(request, uid, auth_method='setuid') else: # Don't allow creating users with invalid names if not user.isValidName(request, user_name): return 'error', _("""Invalid user name {{{'%s'}}}. Name may contain any Unicode alpha numeric character, with optional one space between words. Group page name is not allowed.""", wiki=True) % wikiutil.escape(user_name) theuser = user.User(request, auth_method='setuid') theuser.name = user_name else: uid = form.get('selected_user', '') if not uid: return 'error', _("No user selected") theuser = user.User(request, uid, auth_method='setuid') if not theuser or not theuser.exists(): return 'error', _("No user selected") # set valid to True so superusers can even switch # to disable accounts theuser.valid = True request._setuid_real_user = request.user # now continue as the other user request.user = theuser if not uid: # create new user theuser.save() return _( "You can now change the settings of the selected user account; log out to get back to your account." )
def _handle_name_continuation(self, request): if not "openid.id" in request.session: return CancelLogin(None) _ = request.getText newname = request.form.get("username", [""])[0] if not newname: return MultistageFormLogin(self._get_account_name) if not user.isValidName(request, newname): return MultistageFormLogin(self._get_account_name_inval_user) uid = None if newname: uid = user.getUserId(request, newname) if not uid: # we can create a new user with this name :) u = user.User(request, auth_method=self.name, auth_username=request.session["openid.id"]) u.name = newname u = self._handle_user_data(request, u) return ContinueLogin(u) # requested username already exists. if they know the password, # they can associate that account with the openid. assoc = lambda req, form: self._associate_account(req, form, newname) return MultistageFormLogin(assoc)
def testGroupNames(self): """ user: isValidName: reject group names """ test = u'AdminGroup' assert not user.isValidName(self.request, test)
def _invite(request, page_url, email, new_template, old_template, **custom_vars): mail_from = request.user.email if "@" not in mail_from: mail_from += "@" + request.cfg.invite_sender_default_domain variables = dict(custom_vars) variables.update(PAGEURL=page_url, ADMINEMAIL=request.cfg.mail_from, INVITERUSER=request.user.name, INVITEREMAIL=mail_from, SERVERURL=request.host_url) old_user = user.get_by_email_address(request, email) if old_user: variables.update(INVITEDUSER=old_user.name, INVITEDEMAIL=old_user.email) if not old_template: old_template = getattr(request.cfg, OLD_TEMPLATE_VARIABLE, OLD_TEMPLATE_DEFAULT) template = load_template(request, old_template) send_message(request, prepare_message(template, variables)) return old_user force_lower = getattr(request.cfg, "username_force_lowercase", False) if force_lower: email = email.lower() if not user.isValidName(request, email): exception_msg = "'{0}' is not a valid username.".format(email) if force_lower: exception_msg += ' (email address was converted to lowercase)' raise InviteException(exception_msg) password = generate_password() new_user = user.User(request, None, email, password) new_user.email = email new_user.aliasname = "" new_user.password = password variables.update(INVITEDUSER=new_user.name, INVITEDEMAIL=new_user.email, INVITEDPASSWORD=password) if not new_template: new_template = getattr(request.cfg, NEW_TEMPLATE_VARIABLE, NEW_TEMPLATE_DEFAULT) template = load_template(request, new_template) send_message(request, prepare_message(template, variables), lambda x: x.lower() == email.lower()) variables.update(INVITEDPASSWORD="******") send_message(request, prepare_message(template, variables), lambda x: x.lower() != email.lower()) new_user.save() logging.info("New user %s added to wiki %s (invited by %s)" % (new_user.name, request.cfg.interwikiname, request.user.name)) return new_user
def handleData(self): _ = 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('login_sendmail'): if not self.cfg.mail_smarthost: return _("""This wiki is not enabled for mail processing. Contact the owner of the wiki, who can enable email.""") try: email = form['email'][0].lower() 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) if not text: 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) # Require non-empty name try: theuser.name = form['username'][0] except KeyError: 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 # 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) # try to get the (optional) 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" " login information, you can get it by email.") # Email required to be unique # See also MoinMoin/scripts/moin_usercheck.py if theuser.email: 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: return _("This email already belongs to somebody else.") # editor size theuser.edit_rows = util.web.getIntegerInput(self.request, 'edit_rows', theuser.edit_rows, 10, 60) # time zone theuser.tz_offset = util.web.getIntegerInput(self.request, 'tz_offset', theuser.tz_offset, -84600, 84600) # datetime format try: 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 # try to get the (optional) theme theme_name = form.get('theme_name', [self.cfg.theme_default])[0] if theme_name != theuser.theme_name: # if the theme has changed, load the new theme # so the user has a direct feedback # WARNING: this should be refactored (i.e. theme load # after userform handling), cause currently the # already loaded theme is just replaced (works cause # nothing has been emitted yet) theuser.theme_name = theme_name if self.request.loadTheme(theuser.theme_name) > 0: 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] # 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) # quicklinks for navibar theuser.quicklinks = self.decodePageList('quicklinks') # subscription for page change notification theuser.subscribed_pages = self.decodePageList('subscribed_pages') # save data and send cookie theuser.save() self.request.user = theuser self.request.setCookie() result = _("User preferences saved!") if _debug: result = result + util.dumpFormData(form) return result
def _save_user_prefs(self): _ = self._ form = self.request.form request = self.request if request.request_method != 'POST': return if not 'name' in request.user.auth_attribs: # Require non-empty name new_name = form.get('name', [request.user.name])[0] # Don't allow changing the name to an invalid one if not user.isValidName(request, new_name): return 'error', _("""Invalid user name {{{'%s'}}}. Name may contain any Unicode alpha numeric character, with optional one space between words. Group page name is not allowed.""", wiki=True) % wikiutil.escape(new_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. existing_id = user.getUserId(request, new_name) if existing_id is not None and existing_id != request.user.id: return 'error', _("This user name already belongs to somebody else.") if not new_name: return 'error', _("Empty user name. Please enter a user name.") # done sanity checking the name, set it request.user.name = new_name if not 'email' in request.user.auth_attribs: # try to get the email new_email = wikiutil.clean_input(form.get('email', [request.user.email])[0]) new_email = new_email.strip() # Require email if not new_email and 'email' not in request.cfg.user_form_remove: return 'error', _("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 new_email and request.cfg.user_email_unique: other = user.get_by_email_address(request, new_email) if other is not None and other.id != request.user.id: return 'error', _("This email already belongs to somebody else.") # done checking the email, set it request.user.email = new_email if not 'jid' in request.user.auth_attribs: # try to get the jid new_jid = wikiutil.clean_input(form.get('jid', [''])[0]).strip() jid_changed = request.user.jid != new_jid previous_jid = request.user.jid if new_jid and request.cfg.user_jid_unique: other = user.get_by_jabber_id(request, new_jid) if other is not None and other.id != request.user.id: return 'error', _("This jabber id already belongs to somebody else.") if jid_changed: set_event = events.JabberIDSetEvent(request, new_jid) unset_event = events.JabberIDUnsetEvent(request, previous_jid) events.send_event(unset_event) events.send_event(set_event) # done checking the JID, set it request.user.jid = new_jid if not 'aliasname' in request.user.auth_attribs: # aliasname request.user.aliasname = wikiutil.clean_input(form.get('aliasname', [''])[0]) # editor size request.user.edit_rows = util.web.getIntegerInput(request, 'edit_rows', request.user.edit_rows, 10, 60) # try to get the editor request.user.editor_default = form.get('editor_default', [self.cfg.editor_default])[0] request.user.editor_ui = form.get('editor_ui', [self.cfg.editor_ui])[0] # time zone request.user.tz_offset = util.web.getIntegerInput(request, 'tz_offset', request.user.tz_offset, -84600, 84600) # datetime format try: dt_d_combined = Settings._date_formats.get(form['datetime_fmt'][0], '') request.user.datetime_fmt, request.user.date_fmt = dt_d_combined.split(' & ') except (KeyError, ValueError): request.user.datetime_fmt = '' # default request.user.date_fmt = '' # default # try to get the (optional) theme theme_name = form.get('theme_name', [self.cfg.theme_default])[0] if theme_name != request.user.theme_name: # if the theme has changed, load the new theme # so the user has a direct feedback # WARNING: this should be refactored (i.e. theme load # after userform handling), cause currently the # already loaded theme is just replaced (works cause # nothing has been emitted yet) request.user.theme_name = theme_name if request.loadTheme(theme_name) > 0: theme_name = wikiutil.escape(theme_name) return 'error', _("The theme '%(theme_name)s' could not be loaded!") % locals() # try to get the (optional) preferred language request.user.language = form.get('language', [''])[0] if request.user.language == u'': # For language-statistics from MoinMoin import i18n request.user.real_language = i18n.get_browser_language(request) else: request.user.real_language = '' # 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', 'email', 'aliasname', 'edit_rows', 'editor_default', 'editor_ui', 'tz_offset', 'datetime_fmt', 'theme_name', 'language', 'real_language', 'jid'] 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(request.user, key, value) # checkbox options 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(request.user, key, value) # quicklinks for navibar request.user.quicklinks = self._decode_pagelist('quicklinks') # save data request.user.save() if request.user.disabled: # set valid to false so the current request won't # show the user as logged-in any more request.user.valid = False result = _("User preferences saved!") if _debug: result = result + util.dumpFormData(form) return result
def _save_user_prefs(self): _ = self._ form = self.request.form request = self.request if not 'name' in request.user.auth_attribs: # Require non-empty name new_name = wikiutil.clean_input(form.get('name', request.user.name)).strip() # Don't allow changing the name to an invalid one if not user.isValidName(request, new_name): return 'error', _("""Invalid user name {{{'%s'}}}. Name may contain any Unicode alpha numeric character, with optional one space between words. Group page name is not allowed.""", wiki=True) % wikiutil.escape(new_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. existing_id = user.getUserId(request, new_name) if existing_id is not None and existing_id != request.user.id: return 'error', _("This user name already belongs to somebody else.") if not new_name: return 'error', _("Empty user name. Please enter a user name.") # done sanity checking the name, set it request.user.name = new_name if not 'email' in request.user.auth_attribs: # try to get the email new_email = wikiutil.clean_input(form.get('email', request.user.email)).strip() # Require email if not new_email and 'email' not in request.cfg.user_form_remove: return 'error', _("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 new_email and request.cfg.user_email_unique: other = user.get_by_email_address(request, new_email) if other is not None and other.id != request.user.id: return 'error', _("This email already belongs to somebody else.") # done checking the email, set it request.user.email = new_email if not 'jid' in request.user.auth_attribs: # try to get the jid new_jid = wikiutil.clean_input(form.get('jid', '')).strip() jid_changed = request.user.jid != new_jid previous_jid = request.user.jid if new_jid and request.cfg.user_jid_unique: other = user.get_by_jabber_id(request, new_jid) if other is not None and other.id != request.user.id: return 'error', _("This jabber id already belongs to somebody else.") if jid_changed: set_event = events.JabberIDSetEvent(request, new_jid) unset_event = events.JabberIDUnsetEvent(request, previous_jid) events.send_event(unset_event) events.send_event(set_event) # done checking the JID, set it request.user.jid = new_jid if not 'aliasname' in request.user.auth_attribs: # aliasname request.user.aliasname = wikiutil.clean_input(form.get('aliasname', '')).strip() # editor size request.user.edit_rows = util.web.getIntegerInput(request, 'edit_rows', request.user.edit_rows, 0, 999) # try to get the editor request.user.editor_default = wikiutil.clean_input(form.get('editor_default', self.cfg.editor_default)) request.user.editor_ui = wikiutil.clean_input(form.get('editor_ui', self.cfg.editor_ui)) # time zone request.user.tz_offset = util.web.getIntegerInput(request, 'tz_offset', request.user.tz_offset, -84600, 84600) # datetime format try: dt_d_combined = Settings._date_formats.get(form['datetime_fmt'], '') request.user.datetime_fmt, request.user.date_fmt = dt_d_combined.split(' & ') except (KeyError, ValueError): request.user.datetime_fmt = '' # default request.user.date_fmt = '' # default # try to get the (optional) theme theme_name = wikiutil.clean_input(form.get('theme_name', self.cfg.theme_default)) if theme_name != request.user.theme_name: # if the theme has changed, load the new theme # so the user has a direct feedback # WARNING: this should be refactored (i.e. theme load # after userform handling), cause currently the # already loaded theme is just replaced (works cause # nothing has been emitted yet) request.user.theme_name = theme_name if load_theme_fallback(request, theme_name) > 0: theme_name = wikiutil.escape(theme_name) return 'error', _("The theme '%(theme_name)s' could not be loaded!") % locals() # try to get the (optional) preferred language request.user.language = wikiutil.clean_input(form.get('language', '')) if request.user.language == u'': # For language-statistics from MoinMoin import i18n request.user.real_language = i18n.get_browser_language(request) else: request.user.real_language = '' # 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', 'email', 'aliasname', 'edit_rows', 'editor_default', 'editor_ui', 'tz_offset', 'datetime_fmt', 'theme_name', 'language', 'real_language', 'jid'] 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) value = wikiutil.clean_input(value) setattr(request.user, key, value) # checkbox options 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") try: value = int(value) except ValueError: # value we got is crap, do not setattr this value, just pass pass else: setattr(request.user, key, value) # quicklinks for navibar request.user.quicklinks = self._decode_pagelist('quicklinks') # save data request.user.save() if request.user.disabled: # set valid to false so the current request won't # show the user as logged-in any more request.user.valid = False result = _("User preferences saved!") return result