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 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 return _("You can now change the settings of the selected user account; log out to get back to your account.")
def handle_form(self): _ = self._ form = self.request.form if 'cancel' in form: return if (wikiutil.checkTicket(self.request, self.request.form['ticket'][0]) and self.request.request_method == 'POST'): uid = form.get('selected_user', [''])[0] if not uid: return 'error', _("No user selected") theuser = user.User(self.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 self.request.session['setuid'] = uid self.request._setuid_real_user = self.request.user # now continue as the other user self.request.user = theuser return _("You can now change the settings of the selected user account; log out to get back to your account.") else: return None
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 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 return _( "You can now change the settings of the selected user account; log out to get back to your account." )
def _do_attachment_move(pagename, request): _ = request.getText if 'cancel' in request.form: return _('Move aborted!') if not wikiutil.checkTicket(request, request.form.get('ticket', '')): return _('Please use the interactive user interface to use action %(actionname)s!') % {'actionname': 'AttachFile.move' } if not request.user.may.delete(pagename): return _('You are not allowed to move attachments from this page.') if 'newpagename' in request.form: new_pagename = request.form.get('newpagename') else: upload_form(pagename, request, msg=_("Move aborted because new page name is empty.")) if 'newattachmentname' in request.form: new_attachment = request.form.get('newattachmentname') if new_attachment != wikiutil.taintfilename(new_attachment): upload_form(pagename, request, msg=_("Please use a valid filename for attachment '%(filename)s'.") % { 'filename': new_attachment}) return else: upload_form(pagename, request, msg=_("Move aborted because new attachment name is empty.")) attachment = request.form.get('oldattachmentname') if attachment != wikiutil.taintfilename(attachment): upload_form(pagename, request, msg=_("Please use a valid filename for attachment '%(filename)s'.") % { 'filename': attachment}) return move_file(request, pagename, new_pagename, attachment, new_attachment)
def execute(pagename, request): """ set values in user profile """ _ = request.getText cfg = request.cfg form = request.form if not request.user.isSuperUser(): request.theme.add_msg( _("Only superuser is allowed to use this action."), "error") elif (request.method == 'POST' and wikiutil.checkTicket(request, form.get('ticket', ''))): user_name = form.get('name', '') key = form.get('key', '') val = form.get('val', '') if key in cfg.user_checkbox_fields: val = int(val) uid = user.getUserId(request, user_name) theuser = user.User(request, uid) oldval = getattr(theuser, key) setattr(theuser, key, val) theuser.save() request.theme.add_msg( '%s.%s: %s -> %s' % tuple([wikiutil.escape(s) for s in [user_name, key, oldval, val]]), "info") Page(request, pagename).send_page()
def _do_install(pagename, request): _ = request.getText if not wikiutil.checkTicket(request, request.args.get('ticket', '')): return _('Please use the interactive user interface to use action %(actionname)s!') % {'actionname': 'AttachFile.install' } pagename, target, targetpath = _access_file(pagename, request) if not request.user.isSuperUser(): return _('You are not allowed to install files.') if not target: return package = packages.ZipPackage(request, targetpath) if package.isPackage(): if package.installPackage(): msg = _("Attachment '%(filename)s' installed.") % {'filename': target} else: msg = _("Installation of '%(filename)s' failed.") % {'filename': target} if package.msg: msg += " " + package.msg else: msg = _('The file %s is not a MoinMoin package file.') % target upload_form(pagename, request, msg=msg)
def _do_install(pagename, request): _ = request.getText if not wikiutil.checkTicket(request, request.args.get('ticket', '')): return _( 'Please use the interactive user interface to use action %(actionname)s!' ) % { 'actionname': 'AttachFile.install' } pagename, target, targetpath = _access_file(pagename, request) if not request.user.isSuperUser(): return _('You are not allowed to install files.') if not target: return package = packages.ZipPackage(request, targetpath) if package.isPackage(): if package.installPackage(): msg = _("Attachment '%(filename)s' installed.") % { 'filename': target } else: msg = _("Installation of '%(filename)s' failed.") % { 'filename': target } if package.msg: msg += " " + package.msg else: msg = _('The file %s is not a MoinMoin package file.') % target upload_form(pagename, request, msg=msg)
def execute(pagename, request): _ = request.getText # check for superuser if not request.user.isSuperUser(): request.theme.add_msg(_('You are not allowed to use this action.'), "error") return Page.Page(request, pagename).send_page() editor = request.values.get('editor') timestamp = time.time() - DAYS * 24 * 3600 ok = request.form.get('ok', 0) logging.debug("editor: %r ok: %r" % (editor, ok)) request.theme.send_title("Despam", pagename=pagename) # Start content (important for RTL support) request.write(request.formatter.startContent("content")) if (request.method == 'POST' and ok and wikiutil.checkTicket(request, request.form.get('ticket', ''))): revert_pages(request, editor, timestamp) elif editor: show_pages(request, pagename, editor, timestamp) else: request.write(show_editors(request, pagename, timestamp)) # End content and send footer request.write(request.formatter.endContent()) request.theme.send_footer(pagename) request.theme.send_closing_html()
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 execute(pagename, request): _ = request.getText actname = __name__.split('.')[-1] # Create a page editor that does not do edior backups, becuase # delete generate "deleted" version, of the page. page = PageEditor(request, pagename, do_editor_backup=0) # be extra paranoid in dangerous actions if actname in request.cfg.excluded_actions \ or not request.user.may.write(pagename) \ or not request.user.may.delete(pagename): return page.send_page(request, msg = _('You are not allowed to delete this page.')) # check whether page exists at all if not page.exists(): return page.send_page(request, msg = _('This page is already deleted or was never created!')) # check whether the user clicked the delete button if request.form.has_key('button') and request.form.has_key('ticket'): # check whether this is a valid deletion request (make outside # attacks harder by requiring two full HTTP transactions) if not wikiutil.checkTicket(request.form['ticket'][0]): return page.send_page(request, msg = _('Please use the interactive user interface to delete pages!')) # Delete the page page.deletePage(request.form.get('comment', [u''])[0]) return page.send_page(request, msg = _('Page "%s" was successfully deleted!') % (pagename,)) # send deletion form ticket = wikiutil.createTicket() querytext = _('Really delete this page?') button = _('Delete') comment_label = _("Optional reason for the deletion") # TODO: this form suck, redesign like RenamePage formhtml = ''' <form method="post" action=""> <strong>%(querytext)s</strong> <input type="hidden" name="action" value="%(actname)s"> <input type="hidden" name="ticket" value="%(ticket)s"> <input type="submit" name="button" value="%(button)s"> <p> %(comment_label)s<br> <input type="text" name="comment" size="60" maxlength="80"> </form>''' % { 'querytext': querytext, 'actname': actname, 'ticket': ticket, 'button': button, 'comment_label': comment_label, } return page.send_page(request, msg=formhtml)
def render(self): """ Render action This action returns a status message. """ _ = self.request.getText params = self.fix_params(self.parse_page()) if self.request.method != 'POST': # display the username / password dialog if we were just called by a GET request return self.show_password_form(params["user"], params["password"]) try: if "cancel" in self.request.values: raise ActionStatus(_("Operation was canceled."), "error") if not wikiutil.checkTicket(self.request, self.request.form.get('ticket', '')): raise ActionStatus( _('Please use the interactive user interface to use action %(actionname)s!' ) % {'actionname': 'SyncPages'}) name = self.request.form.get('name', '') password = self.request.form.get('password', '') if params["direction"] == UP: raise ActionStatus( _("The only supported directions are BOTH and DOWN."), "error") if not self.request.cfg.interwikiname: raise ActionStatus( _("Please set an interwikiname in your wikiconfig (see HelpOnConfiguration) to be able to use this action.", wiki=True), "error") if not params["remoteWiki"]: raise ActionStatus( _("Incorrect parameters. Please supply at least the ''remoteWiki'' parameter. Refer to HelpOnSynchronisation for help.", wiki=True), "error") local = MoinLocalWiki(self.request, params["localPrefix"], params["pageList"]) try: remote = MoinRemoteWiki(self.request, params["remoteWiki"], params["remotePrefix"], params["pageList"], name, password, verbose=debug) except (UnsupportedWikiException, NotAllowedException), (msg, ): raise ActionStatus(msg, "error") if not remote.valid: raise ActionStatus( _("The ''remoteWiki'' is unknown.", wiki=True), "error")
def testTickets(self): from MoinMoin.Page import Page # page name with double quotes self.request.page = Page(self.request, u'bla"bla') ticket1 = wikiutil.createTicket(self.request) assert wikiutil.checkTicket(self.request, ticket1) # page name with non-ASCII chars self.request.page = Page(self.request, u'\xc4rger') ticket2 = wikiutil.createTicket(self.request) assert wikiutil.checkTicket(self.request, ticket2) # same page with another action self.request.page = Page(self.request, u'\xc4rger') self.request.action = 'another' ticket3 = wikiutil.createTicket(self.request) assert wikiutil.checkTicket(self.request, ticket3) assert ticket1 != ticket2 assert ticket2 != ticket3
def rename(self): """ Rename pagename and return the new page """ _ = self.request.getText form = self.request.form # Require a valid ticket. Make outside attacks harder by # requiring two full HTTP transactions if not wikiutil.checkTicket(form['ticket'][0]): self.error = _('Please use the interactive user interface to rename pages!') return # Get new name from form and normalize. comment = form.get('comment', [u''])[0] newpagename = form.get('newpagename')[0] newpagename = self.request.normalizePagename(newpagename) # Name might be empty after normalization. To save translation # work for this extreme case, we just use "EmptyName". if not newpagename: newpagename = "EmptyName" # Valid new name newpage = PageEditor(self.request, newpagename) # Check whether a page with the new name already exists if newpage.exists(includeDeleted=1): return self.pageExistsError(newpagename) # Get old page text savetext = self.page.get_raw_body() oldpath = self.page.getPagePath(check_create=0) newpath = newpage.getPagePath(check_create=0) # Rename page # NOTE: might fail if another process created newpagename just # NOW, while you read this comment. Rename is atomic for files - # but for directories, rename will fail if the directory # exists. We should have global edit-lock to avoid this. # See http://docs.python.org/lib/os-file-dir.html try: os.rename(oldpath, newpath) self.newpage = newpage self.error = None # Save page text with a comment about the old name savetext = u"## page was renamed from %s\n%s" % (self.pagename, savetext) newpage.saveText(savetext, 0, comment=comment) except OSError, err: # Try to understand what happened. Maybe its better to check # the error code, but I just reused the available code above... if newpage.exists(includeDeleted=1): return self.pageExistsError(newpagename) else: self.error = _('Could not rename page because of file system' ' error: %s.') % unicode(err)
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 ticket_ok(self): """ Return True if we check for tickets and there is some valid ticket in the form data or if we don't check for tickets at all. Use this to make sure someone really used the web interface. """ if not self.use_ticket: return True # Require a valid ticket. Make outside attacks harder by # requiring two full HTTP transactions ticket = self.form.get('ticket', '') return wikiutil.checkTicket(self.request, ticket)
def save(self): request = self.request _ = request.getText if not wikiutil.checkTicket(request, request.args.get('ticket', '')): return _( 'Please use the interactive user interface to use action %(actionname)s!' ) % { 'actionname': 'anywikidraw.save' } pagename = self.pagename target = self.target if not request.user.may.write(pagename): return _('You are not allowed to save a drawing on this page.') if not target: return _("Empty target name given.") file_upload = request.files.get('filepath') if not file_upload: # This might happen when trying to upload file names # with non-ascii characters on Safari. return _( "No file content. Delete non ASCII characters from the file name and try again." ) filename = request.form['filename'] basepath, basename = os.path.split(filename) basename, ext = os.path.splitext(basename) ci = AttachFile.ContainerItem(request, pagename, target) filecontent = file_upload.stream content_length = None if ext == '.svg': # AnyWikiDraw POSTs this first AttachFile._addLogEntry(request, 'ATTDRW', pagename, target) ci.truncate() filecontent = filecontent.read( ) # read file completely into memory filecontent = filecontent.replace("\r", "") elif ext == '.map': # touch attachment directory to invalidate cache if new map is saved attach_dir = AttachFile.getAttachDir(request, pagename) os.utime(attach_dir, None) filecontent = filecontent.read( ) # read file completely into memory filecontent = filecontent.strip() else: #content_length = file_upload.content_length # XXX gives -1 for wsgiref :( If this is fixed, we could use the file obj, # without reading it into memory completely: filecontent = filecontent.read() if filecontent: ci.put('drawing' + ext, filecontent, content_length)
def ticket_ok(self): """ Return True if we check for tickets and there is some valid ticket in the form data or if we don't check for tickets at all. Use this to make sure someone really used the web interface. """ if not self.use_ticket: return True # Require a valid ticket. Make outside attacks harder by # requiring two full HTTP transactions ticket = self.form.get('ticket', [''])[0] return wikiutil.checkTicket(self.request, ticket)
def _do_upload(pagename, request): _ = request.getText if not wikiutil.checkTicket(request, request.form.get('ticket', '')): return _('Please use the interactive user interface to use action %(actionname)s!') % {'actionname': 'AttachFile.upload' } # Currently we only check TextCha for upload (this is what spammers ususally do), # but it could be extended to more/all attachment write access if not TextCha(request).check_answer_from_form(): return _('TextCha: Wrong answer! Go back and try again...') form = request.form file_upload = request.files.get('file') if not file_upload: # This might happen when trying to upload file names # with non-ascii characters on Safari. return _("No file content. Delete non ASCII characters from the file name and try again.") try: overwrite = int(form.get('overwrite', '0')) except: overwrite = 0 if not request.user.may.write(pagename): return _('You are not allowed to attach a file to this page.') if overwrite and not request.user.may.delete(pagename): return _('You are not allowed to overwrite a file attachment of this page.') target = form.get('target', u'').strip() if not target: target = file_upload.filename or u'' target = wikiutil.clean_input(target) if not target: return _("Filename of attachment not specified!") # add the attachment try: target, bytes = add_attachment(request, pagename, target, file_upload.stream, overwrite=overwrite) msg = _("Attachment '%(target)s' (remote name '%(filename)s')" " with %(bytes)d bytes saved.") % { 'target': target, 'filename': file_upload.filename, 'bytes': bytes} except AttachmentAlreadyExists: msg = _("Attachment '%(target)s' (remote name '%(filename)s') already exists.") % { 'target': target, 'filename': file_upload.filename} # return attachment list upload_form(pagename, request, msg)
def handle_form(self): request = self.request form = request.form if 'cancel' in form: return if request.method != 'POST': return if not wikiutil.checkTicket(request, form['ticket']): return if 'save' in form: # Save user profile return self._save_user_prefs()
def _do_del(pagename, request): _ = request.getText if not wikiutil.checkTicket(request, request.args.get('ticket', '')): return _('Please use the interactive user interface to use action %(actionname)s!') % {'actionname': 'AttachFile.del' } pagename, filename, fpath = _access_file(pagename, request) if not request.user.may.delete(pagename): return _('You are not allowed to delete attachments on this page.') if not filename: return # error msg already sent in _access_file remove_attachment(request, pagename, filename) upload_form(pagename, request, msg=_("Attachment '%(filename)s' deleted.") % {'filename': filename})
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.get('ticket', '')): return if form.has_key('save'): # Save user profile return self._save_notification_settings()
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.get("ticket", "")): return if form.has_key("save"): # Save user profile return self._save_notification_settings()
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 save(self): request = self.request _ = request.getText if not wikiutil.checkTicket(request, request.args.get('ticket', '')): return _('Please use the interactive user interface to use action %(actionname)s!') % {'actionname': 'anywikidraw.save' } pagename = self.pagename target = self.target if not request.user.may.write(pagename): return _('You are not allowed to save a drawing on this page.') if not target: return _("Empty target name given.") file_upload = request.files.get('filepath') if not file_upload: # This might happen when trying to upload file names # with non-ascii characters on Safari. return _("No file content. Delete non ASCII characters from the file name and try again.") filename = request.form['filename'] basepath, basename = os.path.split(filename) basename, ext = os.path.splitext(basename) ci = AttachFile.ContainerItem(request, pagename, target) filecontent = file_upload.stream content_length = None if ext == '.svg': # AnyWikiDraw POSTs this first AttachFile._addLogEntry(request, 'ATTDRW', pagename, target) ci.truncate() filecontent = filecontent.read() # read file completely into memory filecontent = filecontent.replace("\r", "") elif ext == '.map': # touch attachment directory to invalidate cache if new map is saved attach_dir = AttachFile.getAttachDir(request, pagename) os.utime(attach_dir, None) filecontent = filecontent.read() # read file completely into memory filecontent = filecontent.strip() else: #content_length = file_upload.content_length # XXX gives -1 for wsgiref :( If this is fixed, we could use the file obj, # without reading it into memory completely: filecontent = filecontent.read() if filecontent: ci.put('drawing' + ext, filecontent, content_length)
def handle_form(self): _ = self._ form = self.request.form if self.request.values.has_key("oid.return"): return self._handle_oidreturn() if form.has_key("cancel"): return if self.request.method != "POST": return if not wikiutil.checkTicket(self.request, form.get("ticket", "")): return if form.has_key("remove"): return self._handle_remove() if form.has_key("add"): return self._handle_add()
def handle_form(self): _ = self._ form = self.request.form if self.request.values.has_key('oid.return'): return self._handle_oidreturn() if form.has_key('cancel'): return if self.request.method != 'POST': return if not wikiutil.checkTicket(self.request, form.get('ticket', '')): return if form.has_key('remove'): return self._handle_remove() if form.has_key('add'): return self._handle_add()
def render(self): """ Render action This action returns a status message. """ _ = self.request.getText params = self.fix_params(self.parse_page()) if self.request.method != 'POST': # display the username / password dialog if we were just called by a GET request return self.show_password_form(params["user"], params["password"]) try: if "cancel" in self.request.values: raise ActionStatus(_("Operation was canceled."), "error") if not wikiutil.checkTicket(self.request, self.request.form.get('ticket', '')): raise ActionStatus(_('Please use the interactive user interface to use action %(actionname)s!') % {'actionname': 'SyncPages' }) name = self.request.form.get('name', '') password = self.request.form.get('password', '') if params["direction"] == UP: raise ActionStatus(_("The only supported directions are BOTH and DOWN."), "error") if not self.request.cfg.interwikiname: raise ActionStatus(_("Please set an interwikiname in your wikiconfig (see HelpOnConfiguration) to be able to use this action.", wiki=True), "error") if not params["remoteWiki"]: raise ActionStatus(_("Incorrect parameters. Please supply at least the ''remoteWiki'' parameter. Refer to HelpOnSynchronisation for help.", wiki=True), "error") local = MoinLocalWiki(self.request, params["localPrefix"], params["pageList"]) try: remote = MoinRemoteWiki(self.request, params["remoteWiki"], params["remotePrefix"], params["pageList"], name, password, verbose=debug) except (UnsupportedWikiException, NotAllowedException), (msg, ): raise ActionStatus(msg, "error") if not remote.valid: raise ActionStatus(_("The ''remoteWiki'' is unknown.", wiki=True), "error")
def _do_del(pagename, request): _ = request.getText if not wikiutil.checkTicket(request, request.args.get('ticket', '')): return _( 'Please use the interactive user interface to use action %(actionname)s!' ) % { 'actionname': 'AttachFile.del' } pagename, filename, fpath = _access_file(pagename, request) if not request.user.may.delete(pagename): return _('You are not allowed to delete attachments on this page.') if not filename: return # error msg already sent in _access_file remove_attachment(request, pagename, filename) upload_form(pagename, request, msg=_("Attachment '%(filename)s' deleted.") % {'filename': filename})
def _do_attachment_move(pagename, request): _ = request.getText if 'cancel' in request.form: return _('Move aborted!') if not wikiutil.checkTicket(request, request.form.get('ticket', '')): return _( 'Please use the interactive user interface to use action %(actionname)s!' ) % { 'actionname': 'AttachFile.move' } if not request.user.may.delete(pagename): return _('You are not allowed to move attachments from this page.') if 'newpagename' in request.form: new_pagename = request.form.get('newpagename') else: upload_form(pagename, request, msg=_("Move aborted because new page name is empty.")) if 'newattachmentname' in request.form: new_attachment = request.form.get('newattachmentname') if new_attachment != wikiutil.taintfilename(new_attachment): upload_form( pagename, request, msg= _("Please use a valid filename for attachment '%(filename)s'.") % {'filename': new_attachment}) return else: upload_form( pagename, request, msg=_("Move aborted because new attachment name is empty.")) attachment = request.form.get('oldattachmentname') move_file(request, pagename, new_pagename, attachment, new_attachment)
def execute(pagename, request): """ set values in user profile """ _ = request.getText cfg = request.cfg form = request.form if not request.user.isSuperUser(): request.theme.add_msg(_("Only superuser is allowed to use this action."), "error") elif (request.method == 'POST' and wikiutil.checkTicket(request, form.get('ticket', ''))): user_name = form.get('name', '') key = form.get('key', '') val = form.get('val', '') if key in cfg.user_checkbox_fields: val = int(val) uid = user.getUserId(request, user_name) theuser = user.User(request, uid) oldval = getattr(theuser, key) setattr(theuser, key, val) theuser.save() request.theme.add_msg('%s.%s: %s -> %s' % tuple([wikiutil.escape(s) for s in [user_name, key, oldval, val]]), "info") Page(request, pagename).send_page()
def handle_form(self): request = self.request form = request.form ss = self.cfg.session_service if form.has_key('cancel'): return if request.method != 'POST': return if not wikiutil.checkTicket(request, form['ticket']): return deleted = 0 for key in form.keys(): if not key.startswith("session."): continue _, sid = key.split(".", 1) ss.destroy_session(request, ss.get_session(request, sid)) deleted += 1 return 'info', "%s Sessions deleted" % deleted
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 password = form.get('password1', '') password2 = form.get('password2', '') # Check if password is given and matches with password repeat if password != password2: return 'error', _("Passwords don't match!") if not password: return 'error', _("Please specify a password!") pw_checker = request.cfg.password_checker if pw_checker: pw_error = pw_checker(request, request.user.name, password) if pw_error: return 'error', _("Password not acceptable: %s") % pw_error try: self.request.user.enc_password = user.encodePassword(request.cfg, password) self.request.user.save() return 'info', _("Your password has been changed.") except UnicodeError, err: # Should never happen return "Can't encode password: %s" % str(err)
def execute(pagename, request): """ edit a page """ _ = request.getText if 'button_preview' in request.form and 'button_spellcheck' in request.form: # multiple buttons pressed at once? must be some spammer/bot check_surge_protect(request, kick=True) # get rid of him return if not request.user.may.write(pagename): page = wikiutil.getLocalizedPage(request, 'PermissionDeniedPage') page.body = _('You are not allowed to edit this page.') page.page_name = pagename page.send_page(send_special=True) return valideditors = [ 'text', 'gui', ] editor = '' if request.user.valid: editor = request.user.editor_default if editor not in valideditors: editor = request.cfg.editor_default editorparam = request.values.get('editor', editor) if editorparam == "guipossible": lasteditor = editor elif editorparam == "textonly": editor = lasteditor = 'text' else: editor = lasteditor = editorparam if request.cfg.editor_force: editor = request.cfg.editor_default # if it is still nothing valid, we just use the text editor if editor not in valideditors: editor = 'text' rev = request.rev or 0 savetext = request.form.get('savetext') comment = request.form.get('comment', u'') category = request.form.get('category') rstrip = int(request.form.get('rstrip', '0')) trivial = int(request.form.get('trivial', '0')) ideastatus = int(request.form.get('ideastatus', '0')) if 'button_switch' in request.form: if editor == 'text': editor = 'gui' else: # 'gui' editor = 'text' # load right editor class if editor == 'gui': from MoinMoin.PageGraphicalEditor import PageGraphicalEditor pg = PageGraphicalEditor(request, pagename) else: # 'text' from MoinMoin.PageEditor import PageEditor pg = PageEditor(request, pagename) # is invoked without savetext start editing if savetext is None or 'button_load_draft' in request.form: pg.sendEditor() return # did user hit cancel button? cancelled = 'button_cancel' in request.form from MoinMoin.error import ConvertError try: if lasteditor == 'gui': # convert input from Graphical editor format = request.form.get('format', 'wiki') if format == 'wiki': converter_name = 'text_html_text_moin_wiki' else: converter_name = 'undefined' # XXX we don't have other converters yet convert = wikiutil.importPlugin(request.cfg, "converter", converter_name, 'convert') savetext = convert(request, pagename, savetext) # IMPORTANT: normalize text from the form. This should be done in # one place before we manipulate the text. savetext = pg.normalizeText(savetext, stripspaces=rstrip) except ConvertError: # we don't want to throw an exception if user cancelled anyway if not cancelled: raise if cancelled: pg.sendCancel(savetext or "", rev) pagedir = pg.getPagePath(check_create=0) import os if not os.listdir(pagedir): os.removedirs(pagedir) return comment = wikiutil.clean_input(comment) # Add category # TODO: this code does not work with extended links, and is doing # things behind your back, and in general not needed. Either we have # a full interface for categories (add, delete) or just add them by # markup. if category and category != _('<No addition>'): # opera 8.5 needs this # strip trailing whitespace savetext = savetext.rstrip() # Add category separator if last non-empty line contains # non-categories. lines = [line for line in savetext.splitlines() if line] if lines: #TODO: this code is broken, will not work for extended links #categories, e.g ["category hebrew"] categories = lines[-1].split() if categories: confirmed = wikiutil.filterCategoryPages(request, categories) if len(confirmed) < len(categories): # This was not a categories line, add separator savetext += u'\n----\n' # Add new category if savetext and savetext[-1] != u'\n': savetext += ' ' savetext += category + u'\n' # Should end with newline! if (request.cfg.edit_ticketing and not wikiutil.checkTicket(request, request.form.get('ticket', ''))): request.theme.add_msg( _('Please use the interactive user interface to use action %(actionname)s!' ) % {'actionname': 'edit'}, "error") pg.sendEditor(preview=savetext, comment=comment, staytop=1) # Preview, spellcheck or spellcheck add new words elif ('button_preview' in request.form or 'button_spellcheck' in request.form or 'button_newwords' in request.form): pg.sendEditor(preview=savetext, comment=comment) # Preview with mode switch elif 'button_switch' in request.form: pg.sendEditor(preview=savetext, comment=comment, staytop=1) # Save new text else: try: from MoinMoin.security.textcha import TextCha if not TextCha(request).check_answer_from_form(): raise pg.SaveError( _('TextCha: Wrong answer! Try again below...')) if request.cfg.comment_required and not comment: raise pg.SaveError( _('Supplying a comment is mandatory. Write a comment below and try again...' )) savemsg = pg.saveText(savetext, rev, trivial=trivial, comment=comment) except pg.EditConflict, e: msg = e.message # Handle conflict and send editor pg.set_raw_body(savetext, modified=1) pg.mergeEditConflict(rev) # We don't send preview when we do merge conflict pg.sendEditor(msg=msg, comment=comment) return except pg.SaveError, msg: # Show the error message request.theme.add_msg(unicode(msg), "error") # And show the editor again pg.sendEditor(preview=savetext, comment=comment, staytop=1) return
def execute(pagename, request): """ Main dispatcher for the 'AttachFile' action. """ _ = request.getText msg = None if action_name in request.cfg.actions_excluded: msg = _('File attachments are not allowed in this wiki!') elif request.form.has_key('filepath'): if request.user.may.write(pagename): save_drawing(pagename, request) request.http_headers() request.write("OK") else: msg = _('You are not allowed to save a drawing on this page.') elif not request.form.has_key('do'): upload_form(pagename, request) elif request.form['do'][0] == 'upload': if request.user.may.write(pagename): if request.form.has_key('file'): do_upload(pagename, request) else: # This might happen when trying to upload file names # with non-ascii characters on Safari. msg = _("No file content. Delete non ASCII characters from the file name and try again.") else: msg = _('You are not allowed to attach a file to this page.') elif request.form['do'][0] == 'del': if request.user.may.delete(pagename): del_file(pagename, request) else: msg = _('You are not allowed to delete attachments on this page.') elif request.form['do'][0] == 'move': if request.user.may.delete(pagename): send_moveform(pagename, request) else: msg = _('You are not allowed to move attachments from this page.') elif request.form['do'][0] == 'attachment_move': if request.form.has_key('cancel'): msg = _('Move aborted!') error_msg(pagename, request, msg) return if not wikiutil.checkTicket(request, request.form['ticket'][0]): msg = _('Please use the interactive user interface to move attachments!') error_msg(pagename, request, msg) return if request.user.may.delete(pagename): attachment_move(pagename, request) else: msg = _('You are not allowed to move attachments from this page.') elif request.form['do'][0] == 'get': if request.user.may.read(pagename): get_file(pagename, request) else: msg = _('You are not allowed to get attachments from this page.') elif request.form['do'][0] == 'unzip': if request.user.may.delete(pagename) and request.user.may.read(pagename) and request.user.may.write(pagename): unzip_file(pagename, request) else: msg = _('You are not allowed to unzip attachments of this page.') elif request.form['do'][0] == 'install': if request.user.isSuperUser(): install_package(pagename, request) else: msg = _('You are not allowed to install files.') elif request.form['do'][0] == 'view': if request.user.may.read(pagename): view_file(pagename, request) else: msg = _('You are not allowed to view attachments of this page.') else: msg = _('Unsupported upload action: %s') % (request.form['do'][0],) if msg: error_msg(pagename, request, msg)
def _do_unzip(pagename, request, overwrite=False): _ = request.getText if not wikiutil.checkTicket(request, request.args.get('ticket', '')): return _( 'Please use the interactive user interface to use action %(actionname)s!' ) % { 'actionname': 'AttachFile.unzip' } pagename, filename, fpath = _access_file(pagename, request) if not (request.user.may.delete(pagename) and request.user.may.read(pagename) and request.user.may.write(pagename)): return _('You are not allowed to unzip attachments of this page.') if not filename: return # error msg already sent in _access_file try: if not zipfile.is_zipfile(fpath): return _('The file %(filename)s is not a .zip file.') % { 'filename': filename } # determine how which attachment names we have and how much space each is occupying curr_fsizes = dict([(f, size(request, pagename, f)) for f in _get_files(request, pagename)]) # Checks for the existance of one common prefix path shared among # all files in the zip file. If this is the case, remove the common prefix. # We also prepare a dict of the new filenames->filesizes. zip_path_sep = '/' # we assume '/' is as zip standard suggests fname_index = None mapping = [] new_fsizes = {} zf = zipfile.ZipFile(fpath) for zi in zf.infolist(): name = zi.filename if not name.endswith(zip_path_sep): # a file (not a directory) if fname_index is None: fname_index = name.rfind(zip_path_sep) + 1 path = name[:fname_index] if (name.rfind(zip_path_sep) + 1 != fname_index # different prefix len or name[:fname_index] != path): # same len, but still different mapping = [] # zip is not acceptable break if zi.file_size >= request.cfg.unzip_single_file_size: # file too big mapping = [] # zip is not acceptable break finalname = name[fname_index:] # remove common path prefix finalname = finalname.decode( config.charset, 'replace') # replaces trash with \uFFFD char mapping.append((name, finalname)) new_fsizes[finalname] = zi.file_size # now we either have an empty mapping (if the zip is not acceptable), # an identity mapping (no subdirs in zip, just all flat), or # a mapping (origname, finalname) where origname is the zip member filename # (including some prefix path) and finalname is a simple filename. # calculate resulting total file size / count after unzipping: if overwrite: curr_fsizes.update(new_fsizes) total = curr_fsizes else: new_fsizes.update(curr_fsizes) total = new_fsizes total_count = len(total) total_size = sum(total.values()) if not mapping: msg = _( "Attachment '%(filename)s' not unzipped because some files in the zip " "are either not in the same directory or exceeded the single file size limit (%(maxsize_file)d kB)." ) % { 'filename': filename, 'maxsize_file': request.cfg.unzip_single_file_size / 1000, } elif total_size > request.cfg.unzip_attachments_space: msg = _( "Attachment '%(filename)s' not unzipped because it would have exceeded " "the per page attachment storage size limit (%(size)d kB)." ) % { 'filename': filename, 'size': request.cfg.unzip_attachments_space / 1000, } elif total_count > request.cfg.unzip_attachments_count: msg = _( "Attachment '%(filename)s' not unzipped because it would have exceeded " "the per page attachment count limit (%(count)d).") % { 'filename': filename, 'count': request.cfg.unzip_attachments_count, } else: not_overwritten = [] for origname, finalname in mapping: try: # Note: reads complete zip member file into memory. ZipFile does not offer block-wise reading: add_attachment(request, pagename, finalname, zf.read(origname), overwrite) except AttachmentAlreadyExists: not_overwritten.append(finalname) if not_overwritten: msg = _( "Attachment '%(filename)s' partially unzipped (did not overwrite: %(filelist)s)." ) % { 'filename': filename, 'filelist': ', '.join(not_overwritten), } else: msg = _("Attachment '%(filename)s' unzipped.") % { 'filename': filename } except RuntimeError, err: # We don't want to crash with a traceback here (an exception # here could be caused by an uploaded defective zip file - and # if we crash here, the user does not get a UI to remove the # defective zip file again). # RuntimeError is raised by zipfile stdlib module in case of # problems (like inconsistent slash and backslash usage in the # archive). logging.exception( "An exception within zip file attachment handling occurred:") msg = _("A severe error occurred:") + ' ' + str(err)
def do_edit(pagename, request): _ = request.getText form = request.form if form.has_key('button_preview') and form.has_key('button_spellcheck'): # multiple buttons pressed at once? must be some spammer/bot request.makeForbidden403() request.surge_protect(kick_him=True) # get rid of him request.log("LOL, some spammer pressed multiple buttons at once ...") return if not request.user.may.write(pagename): Page(request, pagename).send_page(request, msg = _('You are not allowed to edit this page.')) return valideditors = ['text', 'gui',] editor = '' if request.user.valid: editor = request.user.editor_default if editor not in valideditors: editor = request.cfg.editor_default editorparam = request.form.get('editor', [editor])[0] if editorparam == "guipossible": lasteditor = editor elif editorparam == "textonly": editor = lasteditor = 'text' else: editor = lasteditor = editorparam if request.cfg.editor_force: editor = request.cfg.editor_default # if it is still nothing valid, we just use the text editor if editor not in valideditors: editor = 'text' savetext = request.form.get('savetext', [None])[0] rev = int(request.form.get('rev', ['0'])[0]) comment = request.form.get('comment', [u''])[0] category = request.form.get('category', [None])[0] rstrip = int(request.form.get('rstrip', ['0'])[0]) trivial = int(request.form.get('trivial', ['0'])[0]) if request.form.has_key('button_switch'): if editor == 'text': editor = 'gui' else: # 'gui' editor = 'text' # load right editor class if editor == 'gui': from MoinMoin.PageGraphicalEditor import PageGraphicalEditor pg = PageGraphicalEditor(request, pagename) else: # 'text' from MoinMoin.PageEditor import PageEditor pg = PageEditor(request, pagename) # is invoked without savetext start editing if savetext is None: pg.sendEditor() return # did user hit cancel button? cancelled = request.form.has_key('button_cancel') if request.cfg.edit_ticketing: ticket = request.form.get('ticket', [''])[0] if not wikiutil.checkTicket(request, ticket): msg = _('Please use the interactive user interface to use action %(actionname)s!') % {'actionname': 'edit' } pg.send_page(request, msg=msg) return # convert input from Graphical editor from MoinMoin.converter.text_html_text_x_moin import convert, ConvertError try: if lasteditor == 'gui': savetext = convert(request, pagename, savetext) # IMPORTANT: normalize text from the form. This should be done in # one place before we manipulate the text. savetext = pg.normalizeText(savetext, stripspaces=rstrip) except ConvertError: # we don't want to throw an exception if user cancelled anyway if not cancelled: raise if cancelled: pg.sendCancel(savetext or "", rev) return comment = wikiutil.clean_comment(comment) # Add category # TODO: this code does not work with extended links, and is doing # things behind your back, and in general not needed. Either we have # a full interface for categories (add, delete) or just add them by # markup. if category and category != _('<No addition>', formatted=False): # opera 8.5 needs this # strip trailing whitespace savetext = savetext.rstrip() # Add category separator if last non-empty line contains # non-categories. lines = filter(None, savetext.splitlines()) if lines: #TODO: this code is broken, will not work for extended links #categories, e.g ["category hebrew"] categories = lines[-1].split() if categories: confirmed = wikiutil.filterCategoryPages(request, categories) if len(confirmed) < len(categories): # This was not a categories line, add separator savetext += u'\n----\n' # Add new category if savetext and savetext[-1] != u'\n': savetext += ' ' savetext += category + u'\n' # Should end with newline! # Preview, spellcheck or spellcheck add new words if (request.form.has_key('button_preview') or request.form.has_key('button_spellcheck') or request.form.has_key('button_newwords')): pg.sendEditor(preview=savetext, comment=comment) # Preview with mode switch elif request.form.has_key('button_switch'): pg.sendEditor(preview=savetext, comment=comment, staytop=1) # Save new text elif request.form.has_key('button_save'): import flume, flume.flmos as flmo try: savemsg = pg.saveText(savetext, rev, trivial=trivial, comment=comment) flmo.set_label(flume.LABEL_O) # Clear O label right afterwards to minimize privileged code except pg.EditConflict, msg: flmo.set_label(flume.LABEL_O) # Clear O label right afterwards to minimize privileged code # Handle conflict and send editor # TODO: conflict messages are duplicated from PageEditor, # refactor to one place only. conflict_msg = _('Someone else changed this page while you were editing!') pg.set_raw_body(savetext, modified=1) if pg.mergeEditConflict(rev): conflict_msg = _("""Someone else saved this page while you were editing! Please review the page and save then. Do not save this page as it is! Have a look at the diff of %(difflink)s to see what has been changed.""") % { 'difflink': pg.link_to(pg.request, querystr='action=diff&rev=%d' % rev) } # We don't send preview when we do merge conflict pg.sendEditor(msg=conflict_msg, comment=comment) return else: savemsg = conflict_msg except pg.SaveError, msg: # msg contain a unicode string savemsg = unicode(msg)
def _do_upload(pagename, request): _ = request.getText if not wikiutil.checkTicket(request, request.form.get('ticket', '')): return _( 'Please use the interactive user interface to use action %(actionname)s!' ) % { 'actionname': 'AttachFile.upload' } # Currently we only check TextCha for upload (this is what spammers ususally do), # but it could be extended to more/all attachment write access if not TextCha(request).check_answer_from_form(): return _('TextCha: Wrong answer! Go back and try again...') form = request.form file_upload = request.files.get('file') if not file_upload: # This might happen when trying to upload file names # with non-ascii characters on Safari. return _( "No file content. Delete non ASCII characters from the file name and try again." ) try: overwrite = int(form.get('overwrite', '0')) except: overwrite = 0 if not request.user.may.write(pagename): return _('You are not allowed to attach a file to this page.') if overwrite and not request.user.may.delete(pagename): return _( 'You are not allowed to overwrite a file attachment of this page.') target = form.get('target', u'').strip() if not target: target = file_upload.filename or u'' target = wikiutil.clean_input(target) if not target: return _("Filename of attachment not specified!") # add the attachment try: target, bytes = add_attachment(request, pagename, target, file_upload.stream, overwrite=overwrite) msg = _("Attachment '%(target)s' (remote name '%(filename)s')" " with %(bytes)d bytes saved.") % { 'target': target, 'filename': file_upload.filename, 'bytes': bytes } except AttachmentAlreadyExists: msg = _( "Attachment '%(target)s' (remote name '%(filename)s') already exists." ) % { 'target': target, 'filename': file_upload.filename } # return attachment list upload_form(pagename, request, msg)
def _do_unzip(pagename, request, overwrite=False): _ = request.getText if not wikiutil.checkTicket(request, request.args.get('ticket', '')): return _('Please use the interactive user interface to use action %(actionname)s!') % {'actionname': 'AttachFile.unzip' } pagename, filename, fpath = _access_file(pagename, request) if not (request.user.may.delete(pagename) and request.user.may.read(pagename) and request.user.may.write(pagename)): return _('You are not allowed to unzip attachments of this page.') if not filename: return # error msg already sent in _access_file try: if not zipfile.is_zipfile(fpath): return _('The file %(filename)s is not a .zip file.') % {'filename': filename} # determine how which attachment names we have and how much space each is occupying curr_fsizes = dict([(f, size(request, pagename, f)) for f in _get_files(request, pagename)]) # Checks for the existance of one common prefix path shared among # all files in the zip file. If this is the case, remove the common prefix. # We also prepare a dict of the new filenames->filesizes. zip_path_sep = '/' # we assume '/' is as zip standard suggests fname_index = None mapping = [] new_fsizes = {} zf = zipfile.ZipFile(fpath) for zi in zf.infolist(): name = zi.filename if not name.endswith(zip_path_sep): # a file (not a directory) if fname_index is None: fname_index = name.rfind(zip_path_sep) + 1 path = name[:fname_index] if (name.rfind(zip_path_sep) + 1 != fname_index # different prefix len or name[:fname_index] != path): # same len, but still different mapping = [] # zip is not acceptable break if zi.file_size >= request.cfg.unzip_single_file_size: # file too big mapping = [] # zip is not acceptable break finalname = name[fname_index:] # remove common path prefix finalname = finalname.decode(config.charset, 'replace') # replaces trash with \uFFFD char mapping.append((name, finalname)) new_fsizes[finalname] = zi.file_size # now we either have an empty mapping (if the zip is not acceptable), # an identity mapping (no subdirs in zip, just all flat), or # a mapping (origname, finalname) where origname is the zip member filename # (including some prefix path) and finalname is a simple filename. # calculate resulting total file size / count after unzipping: if overwrite: curr_fsizes.update(new_fsizes) total = curr_fsizes else: new_fsizes.update(curr_fsizes) total = new_fsizes total_count = len(total) total_size = sum(total.values()) if not mapping: msg = _("Attachment '%(filename)s' not unzipped because some files in the zip " "are either not in the same directory or exceeded the single file size limit (%(maxsize_file)d kB)." ) % {'filename': filename, 'maxsize_file': request.cfg.unzip_single_file_size / 1000, } elif total_size > request.cfg.unzip_attachments_space: msg = _("Attachment '%(filename)s' not unzipped because it would have exceeded " "the per page attachment storage size limit (%(size)d kB).") % { 'filename': filename, 'size': request.cfg.unzip_attachments_space / 1000, } elif total_count > request.cfg.unzip_attachments_count: msg = _("Attachment '%(filename)s' not unzipped because it would have exceeded " "the per page attachment count limit (%(count)d).") % { 'filename': filename, 'count': request.cfg.unzip_attachments_count, } else: not_overwritten = [] for origname, finalname in mapping: try: # Note: reads complete zip member file into memory. ZipFile does not offer block-wise reading: add_attachment(request, pagename, finalname, zf.read(origname), overwrite) except AttachmentAlreadyExists: not_overwritten.append(finalname) if not_overwritten: msg = _("Attachment '%(filename)s' partially unzipped (did not overwrite: %(filelist)s).") % { 'filename': filename, 'filelist': ', '.join(not_overwritten), } else: msg = _("Attachment '%(filename)s' unzipped.") % {'filename': filename} except (RuntimeError, zipfile.BadZipfile, zipfile.LargeZipFile), err: # We don't want to crash with a traceback here (an exception # here could be caused by an uploaded defective zip file - and # if we crash here, the user does not get a UI to remove the # defective zip file again). # RuntimeError is raised by zipfile stdlib module in case of # problems (like inconsistent slash and backslash usage in the # archive). # BadZipfile/LargeZipFile are raised when there are some # specific problems with the archive file. logging.exception("An exception within zip file attachment handling occurred:") msg = _("A severe error occurred:") + ' ' + str(err)
def execute(pagename, request): """ edit a page """ _ = request.getText if 'button_preview' in request.form and 'button_spellcheck' in request.form: # multiple buttons pressed at once? must be some spammer/bot check_surge_protect(request, kick=True) # get rid of him return if not request.user.may.write(pagename): page = wikiutil.getLocalizedPage(request, 'PermissionDeniedPage') page.body = _('You are not allowed to edit this page.') page.page_name = pagename page.send_page(send_special=True) return valideditors = ['text', 'gui', ] editor = '' if request.user.valid: editor = request.user.editor_default if editor not in valideditors: editor = request.cfg.editor_default editorparam = request.values.get('editor', editor) if editorparam == "guipossible": lasteditor = editor elif editorparam == "textonly": editor = lasteditor = 'text' else: editor = lasteditor = editorparam if request.cfg.editor_force: editor = request.cfg.editor_default # if it is still nothing valid, we just use the text editor if editor not in valideditors: editor = 'text' rev = request.rev or 0 savetext = request.form.get('savetext') comment = request.form.get('comment', u'') category = request.form.get('category') rstrip = int(request.form.get('rstrip', '0')) trivial = int(request.form.get('trivial', '0')) if 'button_switch' in request.form: if editor == 'text': editor = 'gui' else: # 'gui' editor = 'text' # load right editor class if editor == 'gui': from MoinMoin.PageGraphicalEditor import PageGraphicalEditor pg = PageGraphicalEditor(request, pagename) else: # 'text' from MoinMoin.PageEditor import PageEditor pg = PageEditor(request, pagename) # is invoked without savetext start editing if savetext is None or 'button_load_draft' in request.form: pg.sendEditor() return # did user hit cancel button? cancelled = 'button_cancel' in request.form from MoinMoin.error import ConvertError try: if lasteditor == 'gui': # convert input from Graphical editor format = request.form.get('format', 'wiki') if format == 'wiki': converter_name = 'text_html_text_moin_wiki' else: converter_name = 'undefined' # XXX we don't have other converters yet convert = wikiutil.importPlugin(request.cfg, "converter", converter_name, 'convert') savetext = convert(request, pagename, savetext) # IMPORTANT: normalize text from the form. This should be done in # one place before we manipulate the text. savetext = pg.normalizeText(savetext, stripspaces=rstrip) except ConvertError: # we don't want to throw an exception if user cancelled anyway if not cancelled: raise if cancelled: pg.sendCancel(savetext or "", rev) pagedir = pg.getPagePath(check_create=0) import os if not os.listdir(pagedir): os.removedirs(pagedir) return comment = wikiutil.clean_input(comment) # Add category # TODO: this code does not work with extended links, and is doing # things behind your back, and in general not needed. Either we have # a full interface for categories (add, delete) or just add them by # markup. if category and category != _('<No addition>'): # opera 8.5 needs this # strip trailing whitespace savetext = savetext.rstrip() # Add category separator if last non-empty line contains # non-categories. lines = [line for line in savetext.splitlines() if line] if lines: #TODO: this code is broken, will not work for extended links #categories, e.g ["category hebrew"] categories = lines[-1].split() if categories: confirmed = wikiutil.filterCategoryPages(request, categories) if len(confirmed) < len(categories): # This was not a categories line, add separator savetext += u'\n----\n' # Add new category if savetext and savetext[-1] != u'\n': savetext += ' ' savetext += category + u'\n' # Should end with newline! if (request.cfg.edit_ticketing and not wikiutil.checkTicket(request, request.form.get('ticket', ''))): request.theme.add_msg(_('Please use the interactive user interface to use action %(actionname)s!') % {'actionname': 'edit' }, "error") pg.sendEditor(preview=savetext, comment=comment, staytop=1) # Preview, spellcheck or spellcheck add new words elif ('button_preview' in request.form or 'button_spellcheck' in request.form or 'button_newwords' in request.form): pg.sendEditor(preview=savetext, comment=comment) # Preview with mode switch elif 'button_switch' in request.form: pg.sendEditor(preview=savetext, comment=comment, staytop=1) # Save new text else: try: from MoinMoin.security.textcha import TextCha if not TextCha(request).check_answer_from_form(): raise pg.SaveError(_('TextCha: Wrong answer! Try again below...')) if request.cfg.comment_required and not comment: raise pg.SaveError(_('Supplying a comment is mandatory. Write a comment below and try again...')) savemsg = pg.saveText(savetext, rev, trivial=trivial, comment=comment) except pg.EditConflict, e: msg = e.message # Handle conflict and send editor pg.set_raw_body(savetext, modified=1) pg.mergeEditConflict(rev) # We don't send preview when we do merge conflict pg.sendEditor(msg=msg, comment=comment) return except pg.SaveError, msg: # Show the error message request.theme.add_msg(unicode(msg), "error") # And show the editor again pg.sendEditor(preview=savetext, comment=comment, staytop=1) return