def handleData(self): _ = self._ form = self.request.form security_pagename = "%s/%s" % (config.wiki_settings_page, config.wiki_settings_page_security_defaults) if self.request.user.name in wikiacl.Group("Admin", self.request): grouplist = user.getGroupList(self.request) # intialize default rights default_rights = {} for groupname in grouplist: if groupname == 'Admin': default_rights['Admin'] = [True, True, True, True] else: default_rights[groupname] = [False, False, False, False] for key in form: if key.endswith('_may_read'): action = 'read' elif key.endswith('_may_edit'): action = 'edit' elif key.endswith('_may_delete'): action = 'delete' elif key.endswith('_may_admin'): action = 'admin' else: continue groupname = unquoteWikiname(key[:key.find('_may_%s' % action)]) # is valid group? if groupname in grouplist: default_rights[groupname][ACL_RIGHTS_TABLE[action]] = True for groupname in default_rights: default_rights[groupname] = tuple(default_rights[groupname]) self.request.config.acl_rights_default = default_rights # sets the config -- becomes active as soon as this line is # executed! self.request.config.set_config(self.request.config.wiki_name, self.request.config.get_dict(), self.request) return _("Security settings updated!")
def handleData(self): _ = self._ form = self.request.form groups_pagename = "%s/%s" % (config.wiki_settings_page, config.wiki_settings_page_security_defaults) if self.request.user.name in wikiacl.Group("Admin", self.request): if (self.request.form.has_key('delete') and self.request.form['delete']): # delete user group delete_group = unquoteWikiname(self.request.form['delete'][0]) del self.request.config.acl_rights_default[delete_group] # process altered configuration # TODO: abstract this into Groups-y class. self.request.config.set_config(self.request.config.wiki_name, self.request.config.get_dict(), self.request) return 'User group "%s" deleted.' % ( self.request.form['delete'][0]) else: grouplist_all = user.getGroupList(self.request) grouplist = copy(grouplist_all) # remove immutable groups grouplist.remove("All") grouplist.remove("Known") new_group_name = None new_group_dict = None for key in form: if key.startswith('group_'): groupname = unquoteWikiname(key[len('group_'):]) if len(groupname) > 100: return _("Group names must be less than 100 " "characters.") if groupname not in grouplist: continue # throw out invalid group names # keep track of empty textarea responses grouplist.remove(groupname) memberlist = [member.strip() for member in form[key][0].split('\n')] newmemberlist = [] for member in memberlist: if len(member) > 100: return _("User names must be less than 100 " "characters.") if member: newmemberlist.append(member) memberlist = newmemberlist # initialize the group dictionary group_dict = {} for membername in memberlist: group_dict[membername.lower()] = None group = wikiacl.Group(groupname, self.request, fresh=True) group.update(group_dict) group.save() elif key == 'ips_banned': ips_banned = {} for ip in form['ips_banned'][0].split('\n'): ip = ip.strip() if not web.isIpAddress(ip): return _('Invalid IP address "%s" entered.' % ( ip)) ips_banned[ip] = None group = wikiacl.Group("Banned", self.request, fresh=True) group.update_ips(ips_banned) group.save() elif key == 'new_group_name': new_group_name = form['new_group_name'][0].strip() if len(new_group_name) > 100: return _("Group names must be less than 100 " "characters.") elif new_group_name in grouplist_all: return _("Group %s already exists." % ( new_group_name)) elif key == 'new_group_users': new_group_users = [member.strip() for member in form['new_group_users'][0].split('\n')] new_group_users_copy = [] for member in new_group_users: if len(member) > 100: return _("User names must be less than 100 " "characters.") if member: new_group_users_copy.append(member) new_group_users = new_group_users_copy # initialize the group dictionary new_group_dict = {} for membername in new_group_users: new_group_dict[membername.lower()] = None for emptygroupname in grouplist: group = wikiacl.Group(emptygroupname, self.request) group.update({}) group.save() if new_group_name: new_group = wikiacl.Group(new_group_name, self.request) if new_group_dict: new_group.update(new_group_dict) new_group.save() return _("User groups updated!")
def execute(pagename, request): _ = request.getText page = Page(pagename, request) actname = __name__.split('.')[-1] if not request.user.may.admin(page): msg = _("You don't have admin permissions on this page, " "so you cannot change security settings.") return page.send_page(msg) if request.form.has_key('button'): # process save groups = [] groups_dict = {} for key in request.form: if key.endswith('_groupname'): groups.append(unquoteWikiname(key[:-10])) else: if key.endswith('_may_read'): dowhat = 'read' groupname = unquoteWikiname(key[:-9]) elif key.endswith('_may_edit'): dowhat = 'edit' groupname = unquoteWikiname(key[:-9]) elif key.endswith('_may_delete'): dowhat = 'delete' groupname = unquoteWikiname(key[:-11]) elif key.endswith('_may_admin'): dowhat = 'admin' groupname = unquoteWikiname(key[:-10]) else: continue if not groups_dict.has_key(groupname): groups_dict[groupname] = [False, False, False, False] groups_dict[groupname][ACL_RIGHTS_TABLE[dowhat]] = True # set groups we weren't sent any checkboxes for to # all false (nothing checked) groups_no_checks = filter(lambda(groupname): ( groupname not in groups_dict), groups) for groupname in groups_no_checks: groups_dict[groupname] = [False, False, False, False] wikiacl.setACL(pagename, groups_dict, request) return page.send_page( msg = _("Security settings sucessfully changed!")) formhtml = ['<h3>Security settings for "%s":</h3>' % pagename] button = _("Save") url = page.url() d = {'url': url, 'actname': actname, 'button': button} formhtml.append('<form method="POST" action="%(url)s">\n' '<input type="hidden" name="action" value="%(actname)s">\n' % d) custom_groups = user.getGroupList(request, exclude_special_groups=True) grouplist = ['All', 'Known'] + custom_groups for groupname in grouplist: # "All" and "Known" are a bit condense if groupname == 'All': written_groupname = 'Everybody' elif groupname == 'Known': written_groupname = 'Logged in people' else: written_groupname = groupname group = wikiacl.Group(groupname, request, fresh=True) # we want to show the 'change security' option only if # it makes some sense show_admin = groupname in custom_groups formhtml.append('<h6>%s</h6>' % written_groupname) formhtml.append('<input type="hidden" name="%s_groupname" ' 'value="1">' % quoteWikiname(groupname)) if group.may(page, 'read'): formhtml.append('<input type="checkbox" checked ' 'name="%s_may_read" value="1">' % quoteWikiname(groupname)) else: formhtml.append('<input type="checkbox" name="%s_may_read" ' 'value="1">' % quoteWikiname(groupname)) formhtml.append(' read ') if group.may(page, 'edit'): formhtml.append('<input type="checkbox" checked ' 'name="%s_may_edit" value="1">' % quoteWikiname(groupname)) else: formhtml.append('<input type="checkbox" name="%s_may_edit" ' 'value="1">' % quoteWikiname(groupname)) formhtml.append(' edit ') if group.may(page, 'delete'): formhtml.append('<input type="checkbox" checked ' 'name="%s_may_delete" value="1">' % quoteWikiname(groupname)) else: formhtml.append('<input type="checkbox" name="%s_may_delete" ' 'value="1">' % quoteWikiname(groupname)) formhtml.append(' delete ') if show_admin: if group.may(page, 'admin'): formhtml.append('<input type="checkbox" checked ' 'name="%s_may_admin" value="1">' % quoteWikiname(groupname)) else: formhtml.append('<input type="checkbox" name="%s_may_admin" ' 'value="1">' % quoteWikiname(groupname)) formhtml.append(' change security ') formhtml.append( '<p><input type="submit" name="button" value="%(button)s">\n' '</p>\n' '</form>' % d) page.send_page(msg=''.join(formhtml))
def run(self): from Sycamore import wikiacl had_error = False _ = self.getText #self.open_logs() if self.isForbidden(): self.status = "403 FORBIDDEN" self.http_headers([('Content-Type', 'text/plain')]) self.write('You are not allowed to access this!\n') return self.finish() if not self.wiki_exists: self.write('<html><head>' '<meta name="robots" content="noindex,follow"></head><body>') wiki_name = self.config.name if type(config.wiki_farm_no_exist_msg) == tuple: msg, items_string = config.wiki_farm_no_exist_msg items = eval(items_string) no_exist_msg = msg % items else: no_exist_msg = config.wiki_farm_no_exist_msg self.write(no_exist_msg) self.write('</body></html>') return self.finish() elif (self.config.is_disabled and not self.user.name in wikiacl.Group("Admin", self)): self.write('<html><head>' '<meta name="robots" content="noindex,follow"></head><body>') self.write('<p>The wiki %s has been disabled and will be ' 'permanently deleted in 30 days.</p>' % self.config.wiki_name) self.write('</body></html>') return self.finish() # parse request data try: from Sycamore.Page import Page self.args = self.setup_args() self.form = self.args path_info = self.getPathinfo() #from pprint import pformat #sys.stderr.write(pformat(self.__dict__)) action = self.form.get('action',[None])[0] pagename = None oldlink = None if len(path_info) and path_info[0] == '/': pagename = wikiutil.unquoteWikiname(path_info[1:]) oldlink = wikiutil.unquoteFilename(path_info[1:]) pagename = self.recodePageName(pagename) oldlink = self.recodePageName(oldlink) self.pagename = pagename # if oldlink has control characters when we do an mc_quote -- eep! # we want to, then, throw it out because it wasn't going to work if (not oldlink or not wikiutil.suitable_mc_key(oldlink.encode(config.charset))): oldlink = '' pagename_propercased = '' oldlink_propercased = '' if pagename: pagename_exists_name = Page(pagename, self).exists() if pagename_exists_name: pagename_propercased = pagename_exists_name if oldlink: oldlink_exists_name = Page(oldlink, self).exists() if oldlink_exists_name: oldlink_propercased = oldlink_exists_name if pagename_propercased: self.pagename_propercased = pagename_propercased else: self.pagename = pagename if self.pagename.endswith('/'): pagename = self.pagename[:-1] while pagename.endswith('/'): pagename = pagename[:-1] url = Page(pagename, self).url(relative=False) self.http_redirect(url, status="301 MOVED PERMANENTLY") except Page.ExcessiveLength, msg: Page(self.config.page_front_page, self).send_page(msg=msg) return self.finish()
if action: handler = wikiaction.getHandler(action) if handler: handler(pagename or wikiutil.getSysPage(self, self.config.page_front_page).page_name, self) else: self.http_headers() self.write("<p>" + _("Unknown action")) else: if self.form.has_key('goto'): query = self.form['goto'][0].strip() elif pagename: query = pagename else: query = wikiutil.unquoteWikiname(self.query_string) or \ wikiutil.getSysPage(self, self.config.page_front_page).proper_name() try: Page(query, self).send_page(count_hit=1) except Page.ExcessiveLength, msg: Page(self.config.page_front_page, self).send_page(msg=msg) return self.finish() # generate page footer # (actions that do not want this footer use raise # util.SycamoreNoFooter to break out of the default execution path # see the "except SycamoreNoFooter" below)
def sendEditor(self, **kw): """ Send the editor form page. @keyword preview: if given, show this text in preview mode @keyword staytop: don't go to #preview @keyword comment: comment field (when preview is true) @keyword had_conflict: we had an edit conflict on a save. """ import re try: from Sycamore.action import SpellCheck except ImportError: SpellCheck = None form = self.request.form _ = self._ self.request.http_headers([("Content-Type", "text/html; charset=%s" % config.charset)] + self.request.nocache) msg = None preview = kw.get('preview', None) emit_anchor = not kw.get('staytop', 0) proper_name = self.proper_name() from Sycamore.formatter.text_html import Formatter self.request.formatter = Formatter(self.request, store_pagelinks=1, preview=preview) base_uri = "%s/%s?action=edit" % (self.request.getScriptname(), wikiutil.quoteWikiname( self.proper_name())) backto = form.get('backto', [None])[0] if backto: base_uri += '&' + util.web.makeQueryString(backto=backto) # check edit permissions if not self.request.user.may.edit(self): msg = _('You are not allowed to edit this page.') elif self.prev_date: # Trying to edit an old version, this is not possible via # the web interface, but catch it just in case... msg = _('Cannot edit old revisions!') # Is the IP address a Tor exit note? if config.block_tor_edits: tor = torcheck.torcheck() if tor.query(self.request.remote_addr): msg = _('You are not allowed to edit this page, %s.' % self.request.remote_addr) # Test against a number of DNSBLs if config.block_dnsbl_edits: # Test: is this an IP address? re1='((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))(?![\\d])' rg = re.compile(re1,re.IGNORECASE|re.DOTALL) m = rg.search(self.request.remote_addr) if m: # this is an IP address # reverse IP address octets dq = self.request.remote_addr.split('.') dq.reverse() for dnsbl in config.block_dnsbl_edits: querystring = '.'.join(dq) querystring += '.' + dnsbl + '.' try: result = socket.gethostbyname(querystring) except socket.gaierror: # probably nxdomain result = '0.0.0.0' if result.startswith('127.0.0'): # utoh msg = _('You are not allowed to edit this page: %s listed on %s' % (self.request.remote_addr, dnsbl)) # Did one of the prechecks fail? if msg and not kw.get('had_conflict', None): self.send_page(msg=msg) return # check for preview submit if preview is None: title = _('Edit "%(pagename)s"') else: title = _('Preview of "%(pagename)s"') self.set_raw_body(preview.replace("\r", ""), 1) page_needle = self.page_name if config.allow_subpages and page_needle.count('/'): page_needle = '/' + page_needle.split('/')[-1] wikiutil.send_title(self.request, self.proper_name(), pagename=self.proper_name(), has_link=True, strict_title='Editing "%s"' % self.proper_name(), body_onload = "sizeForIE('savetext', 100, 'editorComment', 99);" ) # start content div self.request.write('<div id="content" class="content">\n') # get request parameters text_rows = None if form.has_key('rows'): text_rows = int(form['rows'][0]) if self.request.user.valid: # possibly update user's pref if text_rows != self.request.user.edit_rows: self.request.user.edit_rows = text_rows self.request.user.save() else: text_rows = config.edit_rows if self.request.user.valid: text_rows = int(self.request.user.edit_rows) if form.has_key('cols'): text_cols = int(form['cols'][0]) if self.request.user.valid: # possibly update user's pref if text_rows != self.request.user.edit_rows: self.request.user.edit_rows = text_rows self.request.user.save() else: text_cols = 80 if self.request.user.valid: text_cols = int(self.request.user.edit_cols) # check datestamp (version) of the page our edit is based on if preview is not None: # propagate original datestamp mtime = float(form['datestamp'][0]) # did someone else change the page while we were editing? conflict_msg = None if not self.exists(): # page does not exist, are we creating it? if mtime: conflict_msg = _('<p>Someone else <b>deleted</b> this ' 'page while you were editing!') elif mtime != self.mtime(): conflict_msg = _('<p>Someone else changed this page while ' 'you were editing.') # merge conflicting versions allow_conflicts = 1 from Sycamore.util import diff3 savetext = self.get_raw_body() oldpg = Page(self.page_name, self.request, prev_date=mtime) original_text = oldpg.get_raw_body() saved_text = Page(self.page_name, self.request).get_raw_body() verynewtext, had_conflict = diff3.text_merge( original_text, saved_text, savetext, marker1='----- /!\ Edit conflict! Your version: -----\n', marker2='----- /!\ Edit conflict! Other version: -----\n', marker3='----- /!\ End of edit conflict -----\n') if had_conflict and self.request.user.valid and ( self.request.user.id == self.last_edit_info()[1]): # user pressed back button or did something weird conflict_msg =None elif had_conflict: conflict_msg = _(conflict_msg + 'There was an <b>edit conflict between ' 'your changes!</b></p>' '<p>Please review the conflicts and ' 'merge the changes.</p>') mtime = self.mtime() self.set_raw_body(verynewtext, 1) else: conflict_msg = _(conflict_msg + 'Your changes were sucessfully merged!') mtime = self.mtime() self.set_raw_body(verynewtext) if conflict_msg: self.request.write('<div id="message"><div>%s' '</div></div>'% conflict_msg) emit_anchor = 0 # make this msg visible! elif self.exists(): # datestamp of existing page mtime = self.mtime() else: # page creation mtime = 0 # output message message = kw.get('msg', '') if message: self.request.write('<div id="message">%s</div>' % (message)) # get the text body for the editor field if form.has_key('template'): # "template" parameter contains the name of the template page template_page = wikiutil.unquoteWikiname(form['template'][0]) raw_body = Page(template_page, self.request).get_raw_body() else: raw_body = self.get_raw_body() # send text above text area # button toolbar self.request.write('<div id="editArea">') self.request.write("<script type=\"text/javascript\">" "var buttonRoot = '%s';</script>" % ( os.path.join(config.url_prefix, self.request.theme.name, 'img', 'buttons'))) if self.request.user.name: if config.user_page_prefix: self.request.write("<script type=\"text/javascript\">" "var userPageLink = '[\"%s%s\"]';</script>" % ( config.user_page_prefix, self.request.user.propercased_name)) else: self.request.write("<script type=\"text/javascript\">" "var userPageLink = '[\"%s\"]';</script>" % ( config.user_page_prefix, self.request.user.propercased_name)) else: self.request.write("<script type=\"text/javascript\">" "var userPageLink = '%s';</script>" % ( self.request.remote_addr)) if config.wiki_farm: self.request.write("<script type=\"text/javascript\" " "src=\"http://%s%s%s/edit.js\"></script>\n" % ( config.wiki_base_domain, config.web_dir, config.url_prefix)) else: self.request.write("<script type=\"text/javascript\" " "src=\"%s%s/edit.js\"></script>\n" % ( config.web_dir, config.url_prefix)) # send form self.request.write('<form name="editform" id="editform" ' 'method="post" action="%s/%s#preview">' % ( self.request.getScriptname(), wikiutil.quoteWikiname(proper_name))) self.request.write(str(html.INPUT(type="hidden", name="action", value="savepage"))) if backto: self.request.write(str(html.INPUT(type="hidden", name="backto", value=backto))) # generate default content if not raw_body: if self.isTalkPage(): raw_body = _('This page is for discussing the ' 'contents of ["%s"].') % self.proper_name()[:-5] else: raw_body = _('Describe %s here.') % (self.proper_name(),) # replace CRLF with LF raw_body = self._normalize_text(raw_body) # send datestamp (version) of the page our edit is based on self.request.write('<input type="hidden" name="datestamp" ' 'value="%s">' % repr(mtime)) # Print the editor textarea and the save button self.request.write('<textarea id="savetext" name="savetext" ' 'rows="%d" cols="%d" style="width:100%%;">%s' '</textarea>' % (text_rows, text_cols, wikiutil.escape(raw_body))) # make sure we keep the template notice on a resize of the editor template_param = '' if form.has_key('template'): template_param = '&template=' + form['template'][0] # draw edit size links self.request.write(_('<div class="pageEditInfo" id="editorSize">' 'editor size:')) self.request.write('<a href="#" onclick="return sizeEditor(\'bigger\',' '\'%s&preview=1&cols=60%s\')">%s' '</a>' % (base_uri, template_param, '+')) self.request.write(',<a href="#" onclick="return sizeEditor(\'smaller\',' '\'%s&preview=1&cols=60%s\')">%s' '</a>' % (base_uri, template_param, '-')) self.request.write('</div>') self.request.write('</p>') # close textarea self.request.write('<div id="editComment" id="editorResizeButtons"> ' '%s<br><input type="text" class="formfields" ' 'name="comment" id="editorComment" value="%s" ' 'size="%d" maxlength="80" style="width:99%%;">' '</div>' % (_("<font size=\"+1\">Please comment " "about this change:</font>"), wikiutil.escape(kw.get('comment', ''), 1), text_cols)) spam_catch_button = ( '<span style="position: absolute; top: 0px; left: 0px;' 'height: 0px; width: 0px; overflow: hidden;">' 'dont enter into this box:' '<input type="text" name="text_dont"/>' '</span>' '<span style="position: absolute; top: 0px; left: 0px;' 'height: 0px; width: 0px; overflow: hidden;">' '<input class="formbutton" type="submit" name="button_dont" ' 'value="Dont press me">\n' '</span>') self.request.write(spam_catch_button) # button bar button_spellcheck = (SpellCheck and '<input type="submit" class="formbutton" name="button_spellcheck"' ' value="%s">' % _('Check Spelling')) or '' save_button_text = _('Save Changes') cancel_button_text = _('Cancel') self.request.write("</div>") if self.request.user.may.admin(self): security_button = ('<input type="button" class="formbutton" ' 'onClick="location.href=' '\'%s/%s?action=Security\'" ' 'value="Security">') % ( self.request.getScriptname(), wikiutil.quoteWikiname(proper_name)) else: security_button = '' if self.request.user.may.delete(self): delete_button = ('<input type="button" class="formbutton" ' 'onClick="location.href=' '\'%s/%s?action=DeletePage\'" value="Delete">') % ( self.request.getScriptname(), wikiutil.quoteWikiname(proper_name)) rename_button = ('<input type="button" class="formbutton" ' 'onClick="location.href=\'%s/%s?action=Rename\'"' ' value="Rename">') % ( self.request.getScriptname(), wikiutil.quoteWikiname(proper_name)) else: delete_button = '' rename_button = '' self.request.write('<div id="editButtonRow">' '<span>' '<input type="submit" class="formbutton" ' 'name="button_preview" value="%s"> ' '<input type="submit" class="formbutton" ' 'name="button_save" value="%s"> ' '<input type="submit" class="formbutton" ' 'name="button_cancel" value="%s"> ' '</span>' '<span class="editActions">' '<input type="button" class="formbutton" ' 'onClick="window.open(\'%s/%s?action=Files\', ' '\'files\', \'width=800,height=600,' 'scrollbars=1\')" value="Upload Files"> ' '%s ' '%s ' '%s ' '%s</span>' '</div>' % ( _('Preview'), save_button_text, cancel_button_text, self.request.getScriptname(), wikiutil.quoteWikiname(proper_name), button_spellcheck, delete_button, rename_button, security_button)) if self.request.config.edit_agreement_text: self.request.write(self.request.config.edit_agreement_text) badwords_re = None if preview is not None: if SpellCheck and ( form.has_key('button_spellcheck') or form.has_key('button_newwords')): badwords, badwords_re, msg = SpellCheck.checkSpelling(self, self.request, own_form=0) self.request.write("<p>%s</p>" % msg) self.request.write("</form>") if config.wiki_farm: from Sycamore import farm help_link = farm.link_to_page(farm.getBaseWikiName(), "Help with Editing", self.request.formatter, force_farm=True) else: help_link = Page("Help with Editing", self.request).link_to() # QuickHelp originally by Georg Mischler <*****@*****.**> self.request.write('<h2>Editing quick-help</h2>\n' '<dl><div style="float: right; margin: 10px; border: 1px solid; ' 'padding: 3pt;">See <b>%s</b> for more information.</div>' % ( help_link) + _("<dt>Emphasis:</dt>\n" "<dd>''<em>italics</em>''; '''<strong>bold</strong>''';" "'''''<strong><em>bold italics</em></strong>''''';" "''<em>mixed '''<strong>bold</strong>''' and " "italics</em>''; ---- horizontal rule.</dd>" "<dt>Headings:</dt>" "<dd>= Title 1 =; == Title 2 ==; === Title 3 ===;" "==== Title 4 ====; ===== Title 5 =====.</dd>" "<dt>Lists:</dt>" "<dd>space and one of * bullets; 1., a., A., i., I. " "numbered items;" " 1.#n start numbering at n; space alone indents.</dd>" "<dt>Links:</dt>" "<dd>[\"brackets and double quotes\"]; [\"the exact " "page name\" label];" " url; [url]; [url label].</dd>" "<dt>Tables:</dt>" "<dd>|| cell text |||| cell text spanning two columns ||;" " no trailing white space allowed after tables or titles." "</dd></dl>")) if preview is not None: if not emit_anchor: preview_name = "previewHide" else: preview_name = "preview" self.request.write('<div id="%s" class="preview">' % preview_name) self.send_page(content_only=1, hilite_re=badwords_re, preview=preview) self.request.write('</div>') self.request.write('</div>\n') # end content div wikiutil.send_after_content(self.request) self.request.theme.emit_custom_html(config.page_footer1) self.request.theme.emit_custom_html(config.page_footer2) self.request.write('</body></html>')
def sendEditor(self, **kw): """ Send the editor form page. @keyword preview: if given, show this text in preview mode @keyword staytop: don't go to #preview @keyword comment: comment field (when preview is true) @keyword had_conflict: we had an edit conflict on a save. """ import re try: from Sycamore.action import SpellCheck except ImportError: SpellCheck = None form = self.request.form _ = self._ self.request.http_headers([("Content-Type", "text/html; charset=%s" % config.charset)] + self.request.nocache) msg = None preview = kw.get('preview', None) emit_anchor = not kw.get('staytop', 0) proper_name = self.proper_name() from Sycamore.formatter.text_html import Formatter self.request.formatter = Formatter(self.request, store_pagelinks=1, preview=preview) base_uri = "%s/%s?action=edit" % (self.request.getScriptname(), wikiutil.quoteWikiname( self.proper_name())) backto = form.get('backto', [None])[0] if backto: base_uri += '&' + util.web.makeQueryString(backto=backto) # check edit permissions if not self.request.user.may.edit(self): msg = _('You are not allowed to edit this page.') elif self.prev_date: # Trying to edit an old version, this is not possible via # the web interface, but catch it just in case... msg = _('Cannot edit old revisions!') # Did one of the prechecks fail? if msg and not kw.get('had_conflict', None): self.send_page(msg=msg) return # check for preview submit if preview is None: title = _('Edit "%(pagename)s"') else: title = _('Preview of "%(pagename)s"') self.set_raw_body(preview.replace("\r", ""), 1) page_needle = self.page_name if config.allow_subpages and page_needle.count('/'): page_needle = '/' + page_needle.split('/')[-1] wikiutil.send_title( self.request, self.proper_name(), pagename=self.proper_name(), has_link=True, strict_title='Editing "%s"' % self.proper_name(), body_onload="sizeForIE('savetext', 100, 'editorComment', 99);") # start content div self.request.write('<div id="content" class="content">\n') # get request parameters text_rows = None if form.has_key('rows'): text_rows = int(form['rows'][0]) if self.request.user.valid: # possibly update user's pref if text_rows != self.request.user.edit_rows: self.request.user.edit_rows = text_rows self.request.user.save() else: text_rows = config.edit_rows if self.request.user.valid: text_rows = int(self.request.user.edit_rows) if form.has_key('cols'): text_cols = int(form['cols'][0]) if self.request.user.valid: # possibly update user's pref if text_rows != self.request.user.edit_rows: self.request.user.edit_rows = text_rows self.request.user.save() else: text_cols = 80 if self.request.user.valid: text_cols = int(self.request.user.edit_cols) # check datestamp (version) of the page our edit is based on if preview is not None: # propagate original datestamp mtime = float(form['datestamp'][0]) # did someone else change the page while we were editing? conflict_msg = None if not self.exists(): # page does not exist, are we creating it? if mtime: conflict_msg = _('<p>Someone else <b>deleted</b> this ' 'page while you were editing!') elif mtime != self.mtime(): conflict_msg = _('<p>Someone else changed this page while ' 'you were editing.') # merge conflicting versions allow_conflicts = 1 from Sycamore.util import diff3 savetext = self.get_raw_body() oldpg = Page(self.page_name, self.request, prev_date=mtime) original_text = oldpg.get_raw_body() saved_text = Page(self.page_name, self.request).get_raw_body() verynewtext, had_conflict = diff3.text_merge( original_text, saved_text, savetext, marker1='----- /!\ Edit conflict! Your version: -----\n', marker2='----- /!\ Edit conflict! Other version: -----\n', marker3='----- /!\ End of edit conflict -----\n') if had_conflict and self.request.user.valid and ( self.request.user.id == self.last_edit_info()[1]): # user pressed back button or did something weird conflict_msg = None elif had_conflict: conflict_msg = _(conflict_msg + 'There was an <b>edit conflict between ' 'your changes!</b></p>' '<p>Please review the conflicts and ' 'merge the changes.</p>') mtime = self.mtime() self.set_raw_body(verynewtext, 1) else: conflict_msg = _(conflict_msg + 'Your changes were sucessfully merged!') mtime = self.mtime() self.set_raw_body(verynewtext) if conflict_msg: self.request.write('<div id="message"><div>%s' '</div></div>' % conflict_msg) emit_anchor = 0 # make this msg visible! elif self.exists(): # datestamp of existing page mtime = self.mtime() else: # page creation mtime = 0 # output message message = kw.get('msg', '') if message: self.request.write('<div id="message">%s</div>' % (message)) # get the text body for the editor field if form.has_key('template'): # "template" parameter contains the name of the template page template_page = wikiutil.unquoteWikiname(form['template'][0]) raw_body = Page(template_page, self.request).get_raw_body() else: raw_body = self.get_raw_body() # send text above text area # button toolbar self.request.write('<div id="editArea">') self.request.write( "<script type=\"text/javascript\">" "var buttonRoot = '%s';</script>" % (os.path.join( config.url_prefix, self.request.theme.name, 'img', 'buttons'))) if self.request.user.name: if config.user_page_prefix: self.request.write( "<script type=\"text/javascript\">" "var userPageLink = '[\"%s%s\"]';</script>" % (config.user_page_prefix, self.request.user.propercased_name)) else: self.request.write("<script type=\"text/javascript\">" "var userPageLink = '[\"%s\"]';</script>" % (config.user_page_prefix, self.request.user.propercased_name)) else: self.request.write("<script type=\"text/javascript\">" "var userPageLink = '%s';</script>" % (self.request.remote_addr)) if config.wiki_farm: self.request.write( "<script type=\"text/javascript\" " "src=\"http://%s%s%s/edit.js\"></script>\n" % (config.wiki_base_domain, config.web_dir, config.url_prefix)) else: self.request.write("<script type=\"text/javascript\" " "src=\"%s%s/edit.js\"></script>\n" % (config.web_dir, config.url_prefix)) # send form self.request.write('<form name="editform" id="editform" ' 'method="post" action="%s/%s#preview">' % (self.request.getScriptname(), wikiutil.quoteWikiname(proper_name))) self.request.write( str(html.INPUT(type="hidden", name="action", value="savepage"))) if backto: self.request.write( str(html.INPUT(type="hidden", name="backto", value=backto))) # generate default content if not raw_body: if self.isTalkPage(): raw_body = _('This page is for discussing the ' 'contents of ["%s"].') % self.proper_name()[:-5] else: raw_body = _('Describe %s here.') % (self.proper_name(), ) # replace CRLF with LF raw_body = self._normalize_text(raw_body) # send datestamp (version) of the page our edit is based on self.request.write('<input type="hidden" name="datestamp" ' 'value="%s">' % repr(mtime)) # Print the editor textarea and the save button self.request.write('<textarea id="savetext" name="savetext" ' 'rows="%d" cols="%d" style="width:100%%;">%s' '</textarea>' % (text_rows, text_cols, wikiutil.escape(raw_body))) # make sure we keep the template notice on a resize of the editor template_param = '' if form.has_key('template'): template_param = '&template=' + form['template'][0] # draw edit size links self.request.write( _('<div class="pageEditInfo" id="editorSize">' 'editor size:')) self.request.write('<a href="#" onclick="return sizeEditor(\'bigger\',' '\'%s&preview=1&cols=60%s\')">%s' '</a>' % (base_uri, template_param, '+')) self.request.write( ',<a href="#" onclick="return sizeEditor(\'smaller\',' '\'%s&preview=1&cols=60%s\')">%s' '</a>' % (base_uri, template_param, '-')) self.request.write('</div>') self.request.write('</p>') # close textarea self.request.write( '<div id="editComment" id="editorResizeButtons"> ' '%s<br><input type="text" class="formfields" ' 'name="comment" id="editorComment" value="%s" ' 'size="%d" maxlength="80" style="width:99%%;">' '</div>' % (_("<font size=\"+1\">Please comment " "about this change:</font>"), wikiutil.escape(kw.get('comment', ''), 1), text_cols)) spam_catch_button = ( '<span style="position: absolute; top: 0px; left: 0px;' 'height: 0px; width: 0px; overflow: hidden;">' 'dont enter into this box:' '<input type="text" name="text_dont"/>' '</span>' '<span style="position: absolute; top: 0px; left: 0px;' 'height: 0px; width: 0px; overflow: hidden;">' '<input class="formbutton" type="submit" name="button_dont" ' 'value="Dont press me">\n' '</span>') self.request.write(spam_catch_button) # button bar button_spellcheck = ( SpellCheck and '<input type="submit" class="formbutton" name="button_spellcheck"' ' value="%s">' % _('Check Spelling')) or '' save_button_text = _('Save Changes') cancel_button_text = _('Cancel') self.request.write("</div>") if self.request.user.may.admin(self): security_button = ('<input type="button" class="formbutton" ' 'onClick="location.href=' '\'%s/%s?action=Security\'" ' 'value="Security">') % ( self.request.getScriptname(), wikiutil.quoteWikiname(proper_name)) else: security_button = '' if self.request.user.may.delete(self): delete_button = ('<input type="button" class="formbutton" ' 'onClick="location.href=' '\'%s/%s?action=DeletePage\'" value="Delete">' ) % (self.request.getScriptname(), wikiutil.quoteWikiname(proper_name)) rename_button = ('<input type="button" class="formbutton" ' 'onClick="location.href=\'%s/%s?action=Rename\'"' ' value="Rename">') % (self.request.getScriptname( ), wikiutil.quoteWikiname(proper_name)) else: delete_button = '' rename_button = '' self.request.write( '<div id="editButtonRow">' '<span>' '<input type="submit" class="formbutton" ' 'name="button_preview" value="%s"> ' '<input type="submit" class="formbutton" ' 'name="button_save" value="%s"> ' '<input type="submit" class="formbutton" ' 'name="button_cancel" value="%s"> ' '</span>' '<span class="editActions">' '<input type="button" class="formbutton" ' 'onClick="window.open(\'%s/%s?action=Files\', ' '\'files\', \'width=800,height=600,' 'scrollbars=1\')" value="Upload Files"> ' '%s ' '%s ' '%s ' '%s</span>' '</div>' % (_('Preview'), save_button_text, cancel_button_text, self.request.getScriptname(), wikiutil.quoteWikiname(proper_name), button_spellcheck, delete_button, rename_button, security_button)) if self.request.config.edit_agreement_text: self.request.write(self.request.config.edit_agreement_text) badwords_re = None if preview is not None: if SpellCheck and (form.has_key('button_spellcheck') or form.has_key('button_newwords')): badwords, badwords_re, msg = SpellCheck.checkSpelling( self, self.request, own_form=0) self.request.write("<p>%s</p>" % msg) self.request.write("</form>") if config.wiki_farm: from Sycamore import farm help_link = farm.link_to_page(farm.getBaseWikiName(), "Help with Editing", self.request.formatter, force_farm=True) else: help_link = Page("Help with Editing", self.request).link_to() # QuickHelp originally by Georg Mischler <*****@*****.**> self.request.write( '<h2>Editing quick-help</h2>\n' '<dl><div style="float: right; margin: 10px; border: 1px solid; ' 'padding: 3pt;">See <b>%s</b> for more information.</div>' % (help_link) + _("<dt>Emphasis:</dt>\n" "<dd>''<em>italics</em>''; '''<strong>bold</strong>''';" "'''''<strong><em>bold italics</em></strong>''''';" "''<em>mixed '''<strong>bold</strong>''' and " "italics</em>''; ---- horizontal rule.</dd>" "<dt>Headings:</dt>" "<dd>= Title 1 =; == Title 2 ==; === Title 3 ===;" "==== Title 4 ====; ===== Title 5 =====.</dd>" "<dt>Lists:</dt>" "<dd>space and one of * bullets; 1., a., A., i., I. " "numbered items;" " 1.#n start numbering at n; space alone indents.</dd>" "<dt>Links:</dt>" "<dd>[\"brackets and double quotes\"]; [\"the exact " "page name\" label];" " url; [url]; [url label].</dd>" "<dt>Tables:</dt>" "<dd>|| cell text |||| cell text spanning two columns ||;" " no trailing white space allowed after tables or titles." "</dd></dl>")) if preview is not None: if not emit_anchor: preview_name = "previewHide" else: preview_name = "preview" self.request.write('<div id="%s" class="preview">' % preview_name) self.send_page(content_only=1, hilite_re=badwords_re, preview=preview) self.request.write('</div>') self.request.write('</div>\n') # end content div wikiutil.send_after_content(self.request) self.request.theme.emit_custom_html(config.page_footer1) self.request.theme.emit_custom_html(config.page_footer2) self.request.write('</body></html>')
def execute(pagename, request): _ = request.getText page = Page(pagename, request) actname = __name__.split('.')[-1] if not request.user.may.admin(page): msg = _("You don't have admin permissions on this page, " "so you cannot change security settings.") return page.send_page(msg) if request.form.has_key('button'): # process save groups = [] groups_dict = {} for key in request.form: if key.endswith('_groupname'): groups.append(unquoteWikiname(key[:-10])) else: if key.endswith('_may_read'): dowhat = 'read' groupname = unquoteWikiname(key[:-9]) elif key.endswith('_may_edit'): dowhat = 'edit' groupname = unquoteWikiname(key[:-9]) elif key.endswith('_may_delete'): dowhat = 'delete' groupname = unquoteWikiname(key[:-11]) elif key.endswith('_may_admin'): dowhat = 'admin' groupname = unquoteWikiname(key[:-10]) else: continue if not groups_dict.has_key(groupname): groups_dict[groupname] = [False, False, False, False] groups_dict[groupname][ACL_RIGHTS_TABLE[dowhat]] = True # set groups we weren't sent any checkboxes for to # all false (nothing checked) groups_no_checks = filter( lambda (groupname): (groupname not in groups_dict), groups) for groupname in groups_no_checks: groups_dict[groupname] = [False, False, False, False] wikiacl.setACL(pagename, groups_dict, request) return page.send_page(msg=_("Security settings sucessfully changed!")) formhtml = ['<h3>Security settings for "%s":</h3>' % pagename] button = _("Save") url = page.url() d = {'url': url, 'actname': actname, 'button': button} formhtml.append( '<form method="POST" action="%(url)s">\n' '<input type="hidden" name="action" value="%(actname)s">\n' % d) custom_groups = user.getGroupList(request, exclude_special_groups=True) grouplist = ['All', 'Known'] + custom_groups for groupname in grouplist: # "All" and "Known" are a bit condense if groupname == 'All': written_groupname = 'Everybody' elif groupname == 'Known': written_groupname = 'Logged in people' else: written_groupname = groupname group = wikiacl.Group(groupname, request, fresh=True) # we want to show the 'change security' option only if # it makes some sense show_admin = groupname in custom_groups formhtml.append('<h6>%s</h6>' % written_groupname) formhtml.append('<input type="hidden" name="%s_groupname" ' 'value="1">' % quoteWikiname(groupname)) if group.may(page, 'read'): formhtml.append('<input type="checkbox" checked ' 'name="%s_may_read" value="1">' % quoteWikiname(groupname)) else: formhtml.append('<input type="checkbox" name="%s_may_read" ' 'value="1">' % quoteWikiname(groupname)) formhtml.append(' read ') if group.may(page, 'edit'): formhtml.append('<input type="checkbox" checked ' 'name="%s_may_edit" value="1">' % quoteWikiname(groupname)) else: formhtml.append('<input type="checkbox" name="%s_may_edit" ' 'value="1">' % quoteWikiname(groupname)) formhtml.append(' edit ') if group.may(page, 'delete'): formhtml.append('<input type="checkbox" checked ' 'name="%s_may_delete" value="1">' % quoteWikiname(groupname)) else: formhtml.append('<input type="checkbox" name="%s_may_delete" ' 'value="1">' % quoteWikiname(groupname)) formhtml.append(' delete ') if show_admin: if group.may(page, 'admin'): formhtml.append('<input type="checkbox" checked ' 'name="%s_may_admin" value="1">' % quoteWikiname(groupname)) else: formhtml.append('<input type="checkbox" name="%s_may_admin" ' 'value="1">' % quoteWikiname(groupname)) formhtml.append(' change security ') formhtml.append( '<p><input type="submit" name="button" value="%(button)s">\n' '</p>\n' '</form>' % d) page.send_page(msg=''.join(formhtml))