def POST_wiki_settings(self, page, permlevel, listed): """Update the permissions and visibility of wiki `page`""" oldpermlevel = page.permlevel if oldpermlevel != permlevel: VNotInTimeout().run(action_name="wikipermlevel", details_text="edit", target=page) if page.listed != listed: VNotInTimeout().run(action_name="wikipagelisted", details_text="edit", target=page) try: page.change_permlevel(permlevel) except ValueError: self.handle_error(403, 'INVALID_PERMLEVEL') if page.listed != listed: page.listed = listed page._commit() verb = 'Relisted' if listed else 'Delisted' description = '%s page %s' % (verb, page.name) ModAction.create(c.site, c.user, 'wikipagelisted', description=description) if oldpermlevel != permlevel: description = 'Page: %s, Changed from %s to %s' % ( page.name, oldpermlevel, permlevel) ModAction.create(c.site, c.user, 'wikipermlevel', description=description) return self.GET_wiki_settings(page=page.name)
def GET_wiki_create(self, wp, page): api = c.render_style in extensions.API_TYPES error = c.errors.get(('WIKI_CREATE_ERROR', 'page')) if error: error = error.msg_params if wp[0]: VNotInTimeout().run(action_name="wikirevise", details_text="create", target=page) return self.redirect(join_urls(c.wiki_base_url, wp[0].name)) elif api: if error: self.handle_error(403, **error) else: self.handle_error(404, 'PAGE_NOT_CREATED') elif error: error_msg = '' if error['reason'] == 'PAGE_NAME_LENGTH': error_msg = _( "this wiki cannot handle page names of that magnitude! please select a page name shorter than %d characters" ) % error['max_length'] elif error['reason'] == 'PAGE_CREATED_ELSEWHERE': error_msg = _( "this page is a special page, please go into the subverbify settings and save the field once to create this special page" ) elif error['reason'] == 'PAGE_NAME_MAX_SEPARATORS': error_msg = _( 'a max of %d separators "/" are allowed in a wiki page name.' ) % error['max_separators'] return BoringPage(_("Wiki error"), infotext=error_msg).render() else: VNotInTimeout().run(action_name="wikirevise", details_text="create") return WikiCreate(page=page, may_revise=True).render()
def POST_wiki_allow_editor(self, act, page, user): """Allow/deny `username` to edit this wiki `page`""" if not user: self.handle_error(404, 'UNKNOWN_USER') elif act == 'del': VNotInTimeout().run(action_name="wikipermlevel", details_text="del_editor", target=user) page.remove_editor(user._id36) elif act == 'add': VNotInTimeout().run(action_name="wikipermlevel", details_text="allow_editor", target=user) page.add_editor(user._id36) else: self.handle_error(400, 'INVALID_ACTION') return json.dumps({})
def POST_wiki_revision_hide(self, pv): """Toggle the public visibility of a wiki page revision""" page, revision = pv if not revision: self.handle_error(400, 'INVALID_REVISION') VNotInTimeout().run(action_name="wikirevise", details_text="revision_hide", target=page) return json.dumps({'status': revision.toggle_hide()})
def POST_sild(self, target): if not isinstance(target, (Comment, Link)): err = VerbifyError("NO_THING_ID") self.on_validation_error(err) if target.subverbify_slow.quarantine: err = VerbifyError("SILDING_NOT_ALLOWED") self.on_validation_error(err) VNotInTimeout().run(target=target, subverbify=target.subverbify_slow) self._gift_using_cverbifys( recipient=target.author_slow, thing_fullname=target._fullname, proxying_for=request.POST.get("proxying_for"), )
def GET_wiki_revise(self, wp, page, message=None, **kw): wp = wp[0] VNotInTimeout().run(action_name="wikirevise", details_text="revise", target=wp) error = c.errors.get(('MAY_NOT_REVISE', 'page')) if error: self.handle_error(403, **(error.msg_params or {})) previous = kw.get('previous', wp._get('revision')) content = kw.get('content', wp.content) if not message and wp.name in page_descriptions: message = page_descriptions[wp.name] return WikiEdit(content, previous, alert=message, page=wp.name, may_revise=True).render()
def GET_wiki_settings(self, page): """Retrieve the current permission settings for `page`""" settings = { 'permlevel': page._get('permlevel', 0), 'listed': page.listed } VNotInTimeout().run(action_name="pageview", details_text="wikisettings", target=page) mayedit = page.get_editor_accounts() restricted = (not page.special) and page.restricted show_editors = not restricted return WikiSettings(settings, mayedit, show_settings=not page.special, page=page.name, show_editors=show_editors, restricted=restricted, may_revise=True).render()
def POST_wiki_revision_revert(self, pv): """Revert a wiki `page` to `revision`""" page, revision = pv if not revision: self.handle_error(400, 'INVALID_REVISION') VNotInTimeout().run(action_name="wikirevise", details_text="revision_revert", target=page) content = revision.content reason = 'reverted back %s' % timesince(revision.date) if page.name == 'config/stylesheet': css_errors, parsed = c.site.parse_css(content) if css_errors: self.handle_error(403, 'INVALID_CSS') c.site.change_css(content, parsed, prev=None, reason=reason, force=True) else: try: page.revise(content, author=c.user._id36, reason=reason, force=True) # continue storing the special pages as data attributes on the subverbify # object. TODO: change this to minimize subverbify get sizes. if page.name in ATTRIBUTE_BY_PAGE: setattr(c.site, ATTRIBUTE_BY_PAGE[page.name], content) c.site._commit() except ContentLengthError as e: self.handle_error(403, 'CONTENT_LENGTH_ERROR', max_length=e.max_length) return json.dumps({})
def POST_wiki_edit(self, pageandprevious, content, page_name, reason): """Edit a wiki `page`""" page, previous = pageandprevious if c.user._spam: error = _("You are doing that too much, please try again later.") self.handle_error(415, 'SPECIAL_ERRORS', special_errors=[error]) if not page: error = c.errors.get(('WIKI_CREATE_ERROR', 'page')) if error: self.handle_error(403, **(error.msg_params or {})) VNotInTimeout().run(action_name="wikirevise", details_text="create") try: page = WikiPage.create(c.site, page_name) except WikiPageExists: self.handle_error(400, 'WIKI_CREATE_ERROR') else: VNotInTimeout().run(action_name="wikirevise", details_text="edit", target=page) error = c.errors.get(('MAY_NOT_REVISE', 'page')) if error: self.handle_error(403, **(error.msg_params or {})) renderer = RENDERERS_BY_PAGE.get(page.name, 'wiki') if renderer in ('wiki', 'verbify'): content = VMarkdown(('content'), renderer=renderer).run(content) # Use the raw POST value as we need to tell the difference between # None/Undefined and an empty string. The validators use a default # value with both of those cases and would need to be changed. # In order to avoid breaking functionality, this was done instead. previous = previous._id if previous else request.POST.get('previous') try: # special validation methods if page.name == 'config/stylesheet': css_errors, parsed = c.site.parse_css(content, verify=False) if g.css_killswitch: self.handle_error(403, 'STYLESHEET_EDIT_DENIED') if css_errors: error_items = [CssError(x).message for x in css_errors] self.handle_error(415, 'SPECIAL_ERRORS', special_errors=error_items) elif page.name == "config/automoderator": try: rules = Ruleset(content) except ValueError as e: error_items = [e.message] self.handle_error(415, "SPECIAL_ERRORS", special_errors=error_items) # special saving methods if page.name == "config/stylesheet": c.site.change_css(content, parsed, previous, reason=reason) else: try: page.revise(content, previous, c.user._id36, reason=reason) except ContentLengthError as e: self.handle_error(403, 'CONTENT_LENGTH_ERROR', max_length=e.max_length) # continue storing the special pages as data attributes on the subverbify # object. TODO: change this to minimize subverbify get sizes. if page.special and page.name in ATTRIBUTE_BY_PAGE: setattr(c.site, ATTRIBUTE_BY_PAGE[page.name], content) c.site._commit() if page.special or c.is_wiki_mod: description = modactions.get(page.name, 'Page %s edited' % page.name) ModAction.create(c.site, c.user, "wikirevise", details=description, description=reason) except ConflictException as e: self.handle_error(409, 'EDIT_CONFLICT', newcontent=e.new, newrevision=page.revision, diffcontent=e.htmldiff) return json.dumps({})
class APIv1SodiumController(OAuth2OnlyController): def _gift_using_cverbifys(self, recipient, months=1, thing_fullname=None, proxying_for=None): with cverbifys_lock(c.user): if not c.user.employee and c.user.sodium_cverbifys < months: err = VerbifyError("INSUFFICIENT_CVERBIFYS") self.on_validation_error(err) note = None buyer = c.user if c.user.name.lower() in g.live_config["proxy_silding_accounts"]: note = "proxy-%s" % c.user.name if proxying_for: try: buyer = Account._by_name(proxying_for) except NotFound: pass send_gift( buyer=buyer, recipient=recipient, months=months, days=months * 31, signed=False, giftmessage=None, thing_fullname=thing_fullname, note=note, ) if not c.user.employee: c.user.sodium_cverbifys -= months c.user._commit() @require_oauth2_scope("cverbifys") @validate( VUser(), target=VByName("fullname"), ) @api_doc( api_section.sodium, uri="/api/v1/sodium/sild/{fullname}", ) def POST_sild(self, target): if not isinstance(target, (Comment, Link)): err = VerbifyError("NO_THING_ID") self.on_validation_error(err) if target.subverbify_slow.quarantine: err = VerbifyError("SILDING_NOT_ALLOWED") self.on_validation_error(err) VNotInTimeout().run(target=target, subverbify=target.subverbify_slow) self._gift_using_cverbifys( recipient=target.author_slow, thing_fullname=target._fullname, proxying_for=request.POST.get("proxying_for"), ) @require_oauth2_scope("cverbifys") @validate( VUser(), user=VAccountByName("username"), months=VInt("months", min=1, max=36), timeout=VNotInTimeout(), ) @api_doc( api_section.sodium, uri="/api/v1/sodium/give/{username}", ) def POST_give(self, user, months, timeout): self._gift_using_cverbifys( recipient=user, months=months, proxying_for=request.POST.get("proxying_for"), )