[wiki-lenny] Suppresion de share/

Qui est maintenant directement inclut dans le paquet debian custom

darcs-hash:20090310190607-bd074-6f18fc89ebf2acc3e566cce67afbb41958b8162c.gz
This commit is contained in:
Antoine Durand-Gasselin 2009-03-10 20:06:07 +01:00
parent eae0d21f83
commit 264f35fcd5
16 changed files with 0 additions and 14505 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,432 +0,0 @@
# -*- coding: iso-8859-1 -*-
"""
MoinMoin - Formatter Package and FormatterBase
See "base.py" for the formatter interface.
@copyright: 2000-2004 by Juergen Hermann <jh@web.de>
@license: GNU GPL, see COPYING for details.
"""
import re
from MoinMoin import log
logging = log.getLogger(__name__)
from MoinMoin.util import pysupport
from MoinMoin import wikiutil
from MoinMoin.support.python_compatibility import rsplit
modules = pysupport.getPackageModules(__file__)
class FormatterBase:
""" This defines the output interface used all over the rest of the code.
Note that no other means should be used to generate _content_ output,
while navigational elements (HTML page header/footer) and the like
can be printed directly without violating output abstraction.
"""
hardspace = ' '
def __init__(self, request, **kw):
self.request = request
self._ = request.getText
self._store_pagelinks = kw.get('store_pagelinks', 0)
self._terse = kw.get('terse', 0)
self.pagelinks = []
self.in_p = 0
self.in_pre = 0
self._highlight_re = None
self._base_depth = 0
def set_highlight_re(self, hi_re=None):
""" set the highlighting regular expression (e.g. for search terms)
@param hi_re: either a valid re as str/unicode (you may want to use
re.escape before passing generic strings!) or a compiled
re object. raises re.error for invalid re.
"""
if isinstance(hi_re, (str, unicode)):
hi_re = re.compile(hi_re, re.U + re.IGNORECASE)
self._highlight_re = hi_re
def lang(self, on, lang_name):
return ""
def setPage(self, page):
self.page = page
def sysmsg(self, on, **kw):
""" Emit a system message (embed it into the page).
Normally used to indicate disabled options, or invalid markup.
"""
return ""
# Document Level #####################################################
def startDocument(self, pagename):
return ""
def endDocument(self):
return ""
def startContent(self, content_id="content", **kw):
if self.page:
self.request.begin_include(self.page.page_name)
return ""
def endContent(self):
if self.page:
self.request.end_include()
return ""
# Links ##############################################################
def pagelink(self, on, pagename='', page=None, **kw):
""" make a link to page <pagename>. Instead of supplying a pagename,
it is also possible to give a live Page object, then page.page_name
will be used.
"""
if not self._store_pagelinks or not on or kw.get('generated'):
return ''
if not pagename and page:
pagename = page.page_name
pagename = self.request.normalizePagename(pagename)
if pagename and pagename not in self.pagelinks:
self.pagelinks.append(pagename)
def interwikilink(self, on, interwiki='', pagename='', **kw):
""" calls pagelink() for internal interwikilinks
to make sure they get counted for self.pagelinks.
IMPORTANT: on and off must be called with same parameters, see
also the text_html formatter.
"""
wikitag, wikiurl, wikitail, wikitag_bad = wikiutil.resolve_interwiki(self.request, interwiki, pagename)
if wikitag == 'Self' or wikitag == self.request.cfg.interwikiname:
if '#' in wikitail:
wikitail, kw['anchor'] = rsplit(wikitail, '#', 1)
wikitail = wikiutil.url_unquote(wikitail)
return self.pagelink(on, wikitail, **kw)
return ''
def url(self, on, url=None, css=None, **kw):
raise NotImplementedError
# Attachments ######################################################
def attachment_link(self, on, url=None, **kw):
raise NotImplementedError
def attachment_image(self, url, **kw):
raise NotImplementedError
def attachment_drawing(self, url, text, **kw):
raise NotImplementedError
def attachment_inlined(self, url, text, **kw):
from MoinMoin.action import AttachFile
import os
_ = self.request.getText
pagename, filename = AttachFile.absoluteName(url, self.page.page_name)
fname = wikiutil.taintfilename(filename)
fpath = AttachFile.getFilename(self.request, pagename, fname)
ext = os.path.splitext(filename)[1]
Parser = wikiutil.getParserForExtension(self.request.cfg, ext)
if Parser is not None:
try:
content = file(fpath, 'r').read()
# Try to decode text. It might return junk, but we don't
# have enough information with attachments.
content = wikiutil.decodeUnknownInput(content)
colorizer = Parser(content, self.request, filename=filename)
colorizer.format(self)
except IOError:
pass
return (self.attachment_link(1, url) +
self.text(text) +
self.attachment_link(0))
def anchordef(self, name):
return ""
def line_anchordef(self, lineno):
return ""
def anchorlink(self, on, name='', **kw):
return ""
def line_anchorlink(self, on, lineno=0):
return ""
def image(self, src=None, **kw):
"""An inline image.
Extra keyword arguments are according to the HTML <img> tag attributes.
In particular an 'alt' or 'title' argument should give a description
of the image.
"""
title = src
for titleattr in ('title', 'html__title', 'alt', 'html__alt'):
if titleattr in kw:
title = kw[titleattr]
break
if title:
return '[Image:%s]' % title
return '[Image]'
# generic transclude/include:
def transclusion(self, on, **kw):
raise NotImplementedError
def transclusion_param(self, **kw):
raise NotImplementedError
def smiley(self, text):
return text
def nowikiword(self, text):
return self.text(text)
# Text and Text Attributes ###########################################
def text(self, text, **kw):
if not self._highlight_re:
return self._text(text)
result = []
lastpos = 0
match = self._highlight_re.search(text)
while match and lastpos < len(text):
# add the match we found
result.append(self._text(text[lastpos:match.start()]))
result.append(self.highlight(1))
result.append(self._text(match.group(0)))
result.append(self.highlight(0))
# search for the next one
lastpos = match.end() + (match.end() == lastpos)
match = self._highlight_re.search(text, lastpos)
result.append(self._text(text[lastpos:]))
return ''.join(result)
def _text(self, text):
raise NotImplementedError
def strong(self, on, **kw):
raise NotImplementedError
def emphasis(self, on, **kw):
raise NotImplementedError
def underline(self, on, **kw):
raise NotImplementedError
def highlight(self, on, **kw):
raise NotImplementedError
def sup(self, on, **kw):
raise NotImplementedError
def sub(self, on, **kw):
raise NotImplementedError
def strike(self, on, **kw):
raise NotImplementedError
def code(self, on, **kw):
raise NotImplementedError
def preformatted(self, on, **kw):
self.in_pre = on != 0
def small(self, on, **kw):
raise NotImplementedError
def big(self, on, **kw):
raise NotImplementedError
# special markup for syntax highlighting #############################
def code_area(self, on, code_id, **kw):
raise NotImplementedError
def code_line(self, on):
raise NotImplementedError
def code_token(self, tok_text, tok_type):
raise NotImplementedError
# Paragraphs, Lines, Rules ###########################################
def linebreak(self, preformatted=1):
raise NotImplementedError
def paragraph(self, on, **kw):
self.in_p = on != 0
def rule(self, size=0, **kw):
raise NotImplementedError
def icon(self, type):
return type
# Lists ##############################################################
def number_list(self, on, type=None, start=None, **kw):
raise NotImplementedError
def bullet_list(self, on, **kw):
raise NotImplementedError
def listitem(self, on, **kw):
raise NotImplementedError
def definition_list(self, on, **kw):
raise NotImplementedError
def definition_term(self, on, compact=0, **kw):
raise NotImplementedError
def definition_desc(self, on, **kw):
raise NotImplementedError
def heading(self, on, depth, **kw):
raise NotImplementedError
# Tables #############################################################
def table(self, on, attrs={}, **kw):
raise NotImplementedError
def table_row(self, on, attrs={}, **kw):
raise NotImplementedError
def table_cell(self, on, attrs={}, **kw):
raise NotImplementedError
# Dynamic stuff / Plugins ############################################
def macro(self, macro_obj, name, args, markup=None):
# call the macro
try:
return macro_obj.execute(name, args)
except ImportError, err:
errmsg = unicode(err)
if not name in errmsg:
raise
if markup:
return (self.span(1, title=errmsg) +
self.text(markup) +
self.span(0))
else:
return self.text(errmsg)
def _get_bang_args(self, line):
if line.startswith('#!'):
try:
name, args = line[2:].split(None, 1)
except ValueError:
return ''
else:
return args
return None
def parser(self, parser_name, lines):
""" parser_name MUST be valid!
writes out the result instead of returning it!
"""
# attention: this is copied into text_python!
parser = wikiutil.searchAndImportPlugin(self.request.cfg, "parser", parser_name)
args = None
if lines:
args = self._get_bang_args(lines[0])
logging.debug("formatter.parser: parser args %r" % args)
if args is not None:
lines = lines[1:]
if lines and not lines[0]:
lines = lines[1:]
if lines and not lines[-1].strip():
lines = lines[:-1]
p = parser('\n'.join(lines), self.request, format_args=args)
p.format(self)
del p
return ''
# Other ##############################################################
def div(self, on, **kw):
""" open/close a blocklevel division """
return ""
def span(self, on, **kw):
""" open/close a inline span """
return ""
def rawHTML(self, markup):
""" This allows emitting pre-formatted HTML markup, and should be
used wisely (i.e. very seldom).
Using this event while generating content results in unwanted
effects, like loss of markup or insertion of CDATA sections
when output goes to XML formats.
"""
import formatter, htmllib
from MoinMoin.util import simpleIO
# Regenerate plain text
f = simpleIO()
h = htmllib.HTMLParser(formatter.AbstractFormatter(formatter.DumbWriter(f)))
h.feed(markup)
h.close()
return self.text(f.getvalue())
def escapedText(self, on, **kw):
""" This allows emitting text as-is, anything special will
be escaped (at least in HTML, some text output format
would possibly do nothing here)
"""
return ""
def comment(self, text, **kw):
return ""
# ID handling #################################################
def sanitize_to_id(self, text):
'''
Take 'text' and return something that is a valid ID
for this formatter.
The default returns the first non-space character of the string.
Because of the way this is used, it must be idempotent,
i.e. calling it on an already sanitized id must yield the
original id.
'''
return text.strip()[:1]
def make_id_unique(self, id):
'''
Take an ID and make it unique in the current namespace.
'''
ns = self.request.include_id
if not ns is None:
ns = self.sanitize_to_id(ns)
id = self.sanitize_to_id(id)
id = self.request.make_unique_id(id, ns)
return id
def qualify_id(self, id):
'''
Take an ID and return a string that is qualified by
the current namespace; this default implementation
is suitable if the dot ('.') is valid in IDs for your
formatter.
'''
ns = self.request.include_id
if not ns is None:
ns = self.sanitize_to_id(ns)
return '%s.%s' % (ns, id)
return id

View file

@ -1,438 +0,0 @@
# -*- coding: iso-8859-1 -*-
"""
MoinMoin - Formatter Package and FormatterBase
See "base.py" for the formatter interface.
@copyright: 2000-2004 by Juergen Hermann <jh@web.de>
@license: GNU GPL, see COPYING for details.
"""
import re
from MoinMoin import log
logging = log.getLogger(__name__)
from MoinMoin.util import pysupport
from MoinMoin import wikiutil
from MoinMoin.support.python_compatibility import rsplit
modules = pysupport.getPackageModules(__file__)
class FormatterBase:
""" This defines the output interface used all over the rest of the code.
Note that no other means should be used to generate _content_ output,
while navigational elements (HTML page header/footer) and the like
can be printed directly without violating output abstraction.
"""
hardspace = ' '
def __init__(self, request, **kw):
self.request = request
self._ = request.getText
self._store_pagelinks = kw.get('store_pagelinks', 0)
self._terse = kw.get('terse', 0)
self.pagelinks = []
self.in_p = 0
self.in_pre = 0
self._highlight_re = None
self._base_depth = 0
def set_highlight_re(self, hi_re=None):
""" set the highlighting regular expression (e.g. for search terms)
@param hi_re: either a valid re as str/unicode (you may want to use
re.escape before passing generic strings!) or a compiled
re object. raises re.error for invalid re.
"""
if isinstance(hi_re, (str, unicode)):
hi_re = re.compile(hi_re, re.U + re.IGNORECASE)
self._highlight_re = hi_re
def lang(self, on, lang_name):
return ""
def setPage(self, page):
self.page = page
def sysmsg(self, on, **kw):
""" Emit a system message (embed it into the page).
Normally used to indicate disabled options, or invalid markup.
"""
return ""
# Document Level #####################################################
def startDocument(self, pagename):
return ""
def endDocument(self):
return ""
def startContent(self, content_id="content", **kw):
if self.page:
self.request.begin_include(self.page.page_name)
return ""
def endContent(self):
if self.page:
self.request.end_include()
return ""
# Links ##############################################################
def pagelink(self, on, pagename='', page=None, **kw):
""" make a link to page <pagename>. Instead of supplying a pagename,
it is also possible to give a live Page object, then page.page_name
will be used.
"""
if not self._store_pagelinks or not on or kw.get('generated'):
return ''
if not pagename and page:
pagename = page.page_name
pagename = self.request.normalizePagename(pagename)
if pagename and pagename not in self.pagelinks:
self.pagelinks.append(pagename)
def interwikilink(self, on, interwiki='', pagename='', **kw):
""" calls pagelink() for internal interwikilinks
to make sure they get counted for self.pagelinks.
IMPORTANT: on and off must be called with same parameters, see
also the text_html formatter.
"""
wikitag, wikiurl, wikitail, wikitag_bad = wikiutil.resolve_interwiki(self.request, interwiki, pagename)
if wikitag == 'Self' or wikitag == self.request.cfg.interwikiname:
if '#' in wikitail:
wikitail, kw['anchor'] = rsplit(wikitail, '#', 1)
wikitail = wikiutil.url_unquote(wikitail)
return self.pagelink(on, wikitail, **kw)
return ''
def url(self, on, url=None, css=None, **kw):
raise NotImplementedError
# Attachments ######################################################
def attachment_link(self, on, url=None, **kw):
raise NotImplementedError
def attachment_image(self, url, **kw):
raise NotImplementedError
def attachment_drawing(self, url, text, **kw):
raise NotImplementedError
def attachment_inlined(self, url, text, **kw):
from MoinMoin.action import AttachFile
import os
_ = self.request.getText
pagename, filename = AttachFile.absoluteName(url, self.page.page_name)
fname = wikiutil.taintfilename(filename)
fpath = AttachFile.getFilename(self.request, pagename, fname)
ext = os.path.splitext(filename)[1]
Parser = wikiutil.getParserForExtension(self.request.cfg, ext)
if Parser is not None:
try:
content = file(fpath, 'r').read()
# Try to decode text. It might return junk, but we don't
# have enough information with attachments.
content = wikiutil.decodeUnknownInput(content)
colorizer = Parser(content, self.request, filename=filename)
colorizer.format(self)
except IOError:
pass
return (self.attachment_link(1, url) +
self.text(text) +
self.attachment_link(0))
def anchordef(self, name):
return ""
def line_anchordef(self, lineno):
return ""
def anchorlink(self, on, name='', **kw):
return ""
def line_anchorlink(self, on, lineno=0):
return ""
def image(self, src=None, **kw):
"""An inline image.
Extra keyword arguments are according to the HTML <img> tag attributes.
In particular an 'alt' or 'title' argument should give a description
of the image.
"""
title = src
for titleattr in ('title', 'html__title', 'alt', 'html__alt'):
if titleattr in kw:
title = kw[titleattr]
break
if title:
return '[Image:%s]' % title
return '[Image]'
# generic transclude/include:
def transclusion(self, on, **kw):
raise NotImplementedError
def transclusion_param(self, **kw):
raise NotImplementedError
def smiley(self, text):
return text
def nowikiword(self, text):
return self.text(text)
# Text and Text Attributes ###########################################
def text(self, text, **kw):
if not self._highlight_re:
return self._text(text)
result = []
lastpos = 0
match = self._highlight_re.search(text)
while match and lastpos < len(text):
# add the match we found
result.append(self._text(text[lastpos:match.start()]))
result.append(self.highlight(1))
result.append(self._text(match.group(0)))
result.append(self.highlight(0))
# search for the next one
lastpos = match.end() + (match.end() == lastpos)
match = self._highlight_re.search(text, lastpos)
result.append(self._text(text[lastpos:]))
return ''.join(result)
def _text(self, text):
raise NotImplementedError
def strong(self, on, **kw):
raise NotImplementedError
def emphasis(self, on, **kw):
raise NotImplementedError
def underline(self, on, **kw):
raise NotImplementedError
def highlight(self, on, **kw):
raise NotImplementedError
def sup(self, on, **kw):
raise NotImplementedError
def sub(self, on, **kw):
raise NotImplementedError
def strike(self, on, **kw):
raise NotImplementedError
def code(self, on, **kw):
raise NotImplementedError
def preformatted(self, on, **kw):
self.in_pre = on != 0
def small(self, on, **kw):
raise NotImplementedError
def big(self, on, **kw):
raise NotImplementedError
# special markup for syntax highlighting #############################
def code_area(self, on, code_id, **kw):
raise NotImplementedError
def code_line(self, on):
raise NotImplementedError
def code_token(self, tok_text, tok_type):
raise NotImplementedError
def crans_box(self, title, content, color=None):
raise NotImplementedError
def crans_portal(self, entries):
raise NotImplementedError
# Paragraphs, Lines, Rules ###########################################
def linebreak(self, preformatted=1):
raise NotImplementedError
def paragraph(self, on, **kw):
self.in_p = on != 0
def rule(self, size=0, **kw):
raise NotImplementedError
def icon(self, type):
return type
# Lists ##############################################################
def number_list(self, on, type=None, start=None, **kw):
raise NotImplementedError
def bullet_list(self, on, **kw):
raise NotImplementedError
def listitem(self, on, **kw):
raise NotImplementedError
def definition_list(self, on, **kw):
raise NotImplementedError
def definition_term(self, on, compact=0, **kw):
raise NotImplementedError
def definition_desc(self, on, **kw):
raise NotImplementedError
def heading(self, on, depth, **kw):
raise NotImplementedError
# Tables #############################################################
def table(self, on, attrs={}, **kw):
raise NotImplementedError
def table_row(self, on, attrs={}, **kw):
raise NotImplementedError
def table_cell(self, on, attrs={}, **kw):
raise NotImplementedError
# Dynamic stuff / Plugins ############################################
def macro(self, macro_obj, name, args, markup=None):
# call the macro
try:
return macro_obj.execute(name, args)
except ImportError, err:
errmsg = unicode(err)
if not name in errmsg:
raise
if markup:
return (self.span(1, title=errmsg) +
self.text(markup) +
self.span(0))
else:
return self.text(errmsg)
def _get_bang_args(self, line):
if line.startswith('#!'):
try:
name, args = line[2:].split(None, 1)
except ValueError:
return ''
else:
return args
return None
def parser(self, parser_name, lines):
""" parser_name MUST be valid!
writes out the result instead of returning it!
"""
# attention: this is copied into text_python!
parser = wikiutil.searchAndImportPlugin(self.request.cfg, "parser", parser_name)
args = None
if lines:
args = self._get_bang_args(lines[0])
logging.debug("formatter.parser: parser args %r" % args)
if args is not None:
lines = lines[1:]
if lines and not lines[0]:
lines = lines[1:]
if lines and not lines[-1].strip():
lines = lines[:-1]
p = parser('\n'.join(lines), self.request, format_args=args)
p.format(self)
del p
return ''
# Other ##############################################################
def div(self, on, **kw):
""" open/close a blocklevel division """
return ""
def span(self, on, **kw):
""" open/close a inline span """
return ""
def rawHTML(self, markup):
""" This allows emitting pre-formatted HTML markup, and should be
used wisely (i.e. very seldom).
Using this event while generating content results in unwanted
effects, like loss of markup or insertion of CDATA sections
when output goes to XML formats.
"""
import formatter, htmllib
from MoinMoin.util import simpleIO
# Regenerate plain text
f = simpleIO()
h = htmllib.HTMLParser(formatter.AbstractFormatter(formatter.DumbWriter(f)))
h.feed(markup)
h.close()
return self.text(f.getvalue())
def escapedText(self, on, **kw):
""" This allows emitting text as-is, anything special will
be escaped (at least in HTML, some text output format
would possibly do nothing here)
"""
return ""
def comment(self, text, **kw):
return ""
# ID handling #################################################
def sanitize_to_id(self, text):
'''
Take 'text' and return something that is a valid ID
for this formatter.
The default returns the first non-space character of the string.
Because of the way this is used, it must be idempotent,
i.e. calling it on an already sanitized id must yield the
original id.
'''
return text.strip()[:1]
def make_id_unique(self, id):
'''
Take an ID and make it unique in the current namespace.
'''
ns = self.request.include_id
if not ns is None:
ns = self.sanitize_to_id(ns)
id = self.sanitize_to_id(id)
id = self.request.make_unique_id(id, ns)
return id
def qualify_id(self, id):
'''
Take an ID and return a string that is qualified by
the current namespace; this default implementation
is suitable if the dot ('.') is valid in IDs for your
formatter.
'''
ns = self.request.include_id
if not ns is None:
ns = self.sanitize_to_id(ns)
return '%s.%s' % (ns, id)
return id

View file

@ -1,31 +0,0 @@
# -*- coding: iso-8859-1 -*-
"""
MoinMoin - pagelinks Formatter
@copyright: 2005 Nir Soffer <nirs@freeshell.org>
@license: GNU GPL, see COPYING for details.
"""
from MoinMoin.formatter import FormatterBase
class Formatter(FormatterBase):
""" Collect pagelinks and format nothing :-) """
def pagelink(self, on, pagename='', page=None, **kw):
FormatterBase.pagelink(self, on, pagename, page, **kw)
return self.null()
def null(self, *args, **kw):
return ''
# All these must be overriden here because they raise
# NotImplementedError!@#! or return html?! in the base class.
set_highlight_re = rawHTML = url = image = smiley = text = null
strong = emphasis = underline = highlight = sup = sub = strike = null
code = preformatted = small = big = code_area = code_line = null
code_token = linebreak = paragraph = rule = icon = null
number_list = bullet_list = listitem = definition_list = null
definition_term = definition_desc = heading = table = null
table_row = table_cell = attachment_link = attachment_image = attachment_drawing = null
transclusion = transclusion_param = null

View file

@ -1,33 +0,0 @@
# -*- coding: iso-8859-1 -*-
"""
MoinMoin - pagelinks Formatter
@copyright: 2005 Nir Soffer <nirs@freeshell.org>
@license: GNU GPL, see COPYING for details.
"""
from MoinMoin.formatter import FormatterBase
class Formatter(FormatterBase):
""" Collect pagelinks and format nothing :-) """
def pagelink(self, on, pagename='', page=None, **kw):
FormatterBase.pagelink(self, on, pagename, page, **kw)
return self.null()
def null(self, *args, **kw):
return ''
# All these must be overriden here because they raise
# NotImplementedError!@#! or return html?! in the base class.
set_highlight_re = rawHTML = url = image = smiley = text = null
strong = emphasis = underline = highlight = sup = sub = strike = null
code = preformatted = small = big = code_area = code_line = null
code_token = linebreak = paragraph = rule = icon = null
number_list = bullet_list = listitem = definition_list = null
definition_term = definition_desc = heading = table = null
table_row = table_cell = attachment_link = attachment_image = attachment_drawing = null
transclusion = transclusion_param = null
### HACK SAUVAGE 1/1
crans_box = crans_portal = null
### FIN HACK 1/1

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,234 +0,0 @@
# -*- coding: iso-8859-1 -*-
"""
MoinMoin - Dump a MoinMoin wiki to static pages
@copyright: 2002-2004 Juergen Hermann <jh@web.de>,
2005-2006 MoinMoin:ThomasWaldmann
@license: GNU GPL, see COPYING for details.
"""
import sys, os, time, codecs, shutil, re, errno
from MoinMoin import config, wikiutil, Page, user
from MoinMoin import script
from MoinMoin.action import AttachFile
url_prefix_static = "."
logo_html = '<img src="logo.png">'
HTML_SUFFIX = ".html"
page_template = u'''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=%(charset)s">
<title>%(pagename)s</title>
<link rel="stylesheet" type="text/css" media="all" charset="utf-8" href="%(theme)s/css/common.css">
<link rel="stylesheet" type="text/css" media="screen" charset="utf-8" href="%(theme)s/css/screen.css">
<link rel="stylesheet" type="text/css" media="print" charset="utf-8" href="%(theme)s/css/print.css">
<style type="text/css">
ul.pagetitle{
display: inline;
margin: 0;
padding: 0;
font-size: 1.5em;
}
li.pagetitle{
display: inline;
margin: 0;
}
td.noborder {
border: 0;
}
</style>
</head>
<body>
<table>
<tr>
<td class="noborder">
%(logo_html)s
</td>
<td class="noborder">
<ul class="pagetitle">
<li class="pagetitle"><a class="backlink">%(pagename)s</a>
</ul>
<br><br>
%(navibar_html)s
</td>
</tr>
</table>
<hr>
<div id="page">
%(pagehtml)s
</div>
<hr>
%(timestamp)s
</body>
</html>
'''
def _attachment(request, pagename, filename, outputdir, **kw):
filename = filename.encode(config.charset)
source_dir = AttachFile.getAttachDir(request, pagename)
source_file = os.path.join(source_dir, filename)
dest_dir = os.path.join(outputdir, "attachments", wikiutil.quoteWikinameFS(pagename))
dest_file = os.path.join(dest_dir, filename)
dest_url = "attachments/%s/%s" % (wikiutil.quoteWikinameFS(pagename), wikiutil.url_quote(filename))
if os.access(source_file, os.R_OK):
if not os.access(dest_dir, os.F_OK):
try:
os.makedirs(dest_dir)
except:
script.fatal("Cannot create attachment directory '%s'" % dest_dir)
elif not os.path.isdir(dest_dir):
script.fatal("'%s' is not a directory" % dest_dir)
shutil.copyfile(source_file, dest_file)
script.log('Writing "%s"...' % dest_url)
return dest_url
else:
return ""
class PluginScript(script.MoinScript):
"""\
Purpose:
========
This tool allows you to dump MoinMoin wiki pages to static HTML files.
Detailed Instructions:
======================
General syntax: moin [options] export dump [dump-options]
[options] usually should be:
--config-dir=/path/to/my/cfg/ --wiki-url=wiki.example.org/
[dump-options] see below:
0. You must run this script as owner of the wiki files, usually this is the
web server user.
1. To dump all the pages on the wiki to the directory '/mywiki'
moin ... export dump --target-dir=/mywiki
2. To dump all the pages readable by 'JohnSmith' on the wiki to the directory
'/mywiki'
moin ... export dump --target-dir=/mywiki --username JohnSmith
"""
def __init__(self, argv=None, def_values=None):
script.MoinScript.__init__(self, argv, def_values)
self.parser.add_option(
"-t", "--target-dir", dest = "target_dir",
help = "Write html dump to DIRECTORY"
)
self.parser.add_option(
"-u", "--username", dest = "dump_user",
help = "User the dump will be performed as (for ACL checks, etc)"
)
def mainloop(self):
""" moin-dump's main code. """
# Prepare output directory
if not self.options.target_dir:
script.fatal("you must use --target-dir=/your/output/path to specify the directory we write the html files to")
outputdir = os.path.abspath(self.options.target_dir)
try:
os.mkdir(outputdir)
script.log("Created output directory '%s'!" % outputdir)
except OSError, err:
if err.errno != errno.EEXIST:
script.fatal("Cannot create output directory '%s'!" % outputdir)
# Insert config dir or the current directory to the start of the path.
config_dir = self.options.config_dir
if config_dir and os.path.isfile(config_dir):
config_dir = os.path.dirname(config_dir)
if config_dir and not os.path.isdir(config_dir):
script.fatal("bad path given to --config-dir option")
sys.path.insert(0, os.path.abspath(config_dir or os.curdir))
self.init_request()
request = self.request
# fix url_prefix_static so we get relative paths in output html
request.cfg.url_prefix_static = url_prefix_static
# use this user for permissions checks
request.user = user.User(request, name=self.options.dump_user)
pages = request.rootpage.getPageList(user='') # get list of all pages in wiki
pages.sort()
if self.options.page: # did user request a particular page or group of pages?
try:
namematch = re.compile(self.options.page)
pages = [page for page in pages if namematch.match(page)]
if not pages:
pages = [self.options.page]
except:
pages = [self.options.page]
wikiutil.quoteWikinameURL = lambda pagename, qfn=wikiutil.quoteWikinameFS: (qfn(pagename) + HTML_SUFFIX)
AttachFile.getAttachUrl = lambda pagename, filename, request, **kw: _attachment(request, pagename, filename, outputdir, **kw)
errfile = os.path.join(outputdir, 'error.log')
errlog = open(errfile, 'w')
errcnt = 0
page_front_page = wikiutil.getLocalizedPage(request, request.cfg.page_front_page).page_name
page_title_index = wikiutil.getLocalizedPage(request, 'TitleIndex').page_name
page_word_index = wikiutil.getLocalizedPage(request, 'WordIndex').page_name
navibar_html = ''
for p in [page_front_page, page_title_index, page_word_index]:
navibar_html += '[<a href="%s">%s</a>]&nbsp;' % (wikiutil.quoteWikinameURL(p), wikiutil.escape(p))
urlbase = request.url # save wiki base url
for pagename in pages:
# we have the same name in URL and FS
file = wikiutil.quoteWikinameURL(pagename)
script.log('Writing "%s"...' % file)
try:
pagehtml = ''
request.url = urlbase + pagename # add current pagename to url base
page = Page.Page(request, pagename)
request.page = page
try:
request.reset()
pagehtml = request.redirectedOutput(page.send_page, count_hit=0, content_only=1)
except:
errcnt = errcnt + 1
print >> sys.stderr, "*** Caught exception while writing page!"
print >> errlog, "~" * 78
print >> errlog, file # page filename
import traceback
traceback.print_exc(None, errlog)
finally:
timestamp = time.strftime("%Y-%m-%d %H:%M")
filepath = os.path.join(outputdir, file)
fileout = codecs.open(filepath, 'w', config.charset)
fileout.write(page_template % {
'charset': config.charset,
'pagename': pagename,
'pagehtml': pagehtml,
'logo_html': logo_html,
'navibar_html': navibar_html,
'timestamp': timestamp,
'theme': request.cfg.theme_default,
})
fileout.close()
# copy FrontPage to "index.html"
indexpage = page_front_page
if self.options.page:
indexpage = pages[0] # index page has limited use when dumping specific pages, but create one anyway
shutil.copyfile(
os.path.join(outputdir, wikiutil.quoteWikinameFS(indexpage) + HTML_SUFFIX),
os.path.join(outputdir, 'index' + HTML_SUFFIX)
)
errlog.close()
if errcnt:
print >> sys.stderr, "*** %d error(s) occurred, see '%s'!" % (errcnt, errfile)

View file

@ -1,215 +0,0 @@
# -*- coding: iso-8859-1 -*-
"""
MoinMoin - Dump a MoinMoin wiki to static pages
@copyright: 2002-2004 Juergen Hermann <jh@web.de>,
2005-2006 MoinMoin:ThomasWaldmann
@license: GNU GPL, see COPYING for details.
"""
import sys, os, time, codecs, shutil, re, errno
from MoinMoin import config, wikiutil, Page, user
from MoinMoin import script
from MoinMoin.action import AttachFile
url_prefix_static = "."
logo_html = '<img src="logo.png">'
HTML_SUFFIX = ".html"
### TEMPLATE MODIFIÉ
page_template = u'''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=%(charset)s">
<title>%(pagename)s</title>
<link rel="stylesheet" type="text/css" media="all" charset="utf-8" href="/style.css">
<link rel="stylesheet" type="text/css" media="all" charset="utf-8" href="%(theme)s/css/common.css">
<link rel="stylesheet" type="text/css" media="screen" charset="utf-8" href="%(theme)s/css/screen.css">
<link rel="stylesheet" type="text/css" media="print" charset="utf-8" href="%(theme)s/css/print.css">
</head>
<body>
<p class="avertissement">
Ce site est une copie statique et partielle de ce que l'on peut trouver
sur le <a href="http://wiki.crans.org">wiki</a> de l'association. Si
vous êtes ici, alors que vous avez demandé un autre site, c'est sans
doute que vous êtes connecté au réseau wifi de l'association mais que
vous n'avez pas encore complété toutes les étapes nécessaires pour avoir
une connexion pleinement fonctionnelle. Ce site contient donc les infos
pour configurer correctement votre connexion.
</p>
<div id="title"><h1>%(pagename)s</h1></div>
%(pagehtml)s
<p class="creation">
Cette page a été extraite du wiki le %(timestamp)s. Vous pouvez l'<a href="http://wiki.crans.org/%(pagename)s?action=edit">éditer</a> ou <a href="http://www.crans.org/%(pagename)s">voir</a> la page originale.
</p>
</body>
</html>
'''
def _attachment(request, pagename, filename, outputdir, **kw):
filename = filename.encode(config.charset)
source_dir = AttachFile.getAttachDir(request, pagename)
source_file = os.path.join(source_dir, filename)
dest_dir = os.path.join(outputdir, "attachments", wikiutil.quoteWikinameFS(pagename))
dest_file = os.path.join(dest_dir, filename)
dest_url = "attachments/%s/%s" % (wikiutil.quoteWikinameFS(pagename), wikiutil.url_quote(filename))
if os.access(source_file, os.R_OK):
if not os.access(dest_dir, os.F_OK):
try:
os.makedirs(dest_dir)
except:
script.fatal("Cannot create attachment directory '%s'" % dest_dir)
elif not os.path.isdir(dest_dir):
script.fatal("'%s' is not a directory" % dest_dir)
shutil.copyfile(source_file, dest_file)
script.log('Writing "%s"...' % dest_url)
return dest_url
else:
return ""
class PluginScript(script.MoinScript):
"""\
Purpose:
========
This tool allows you to dump MoinMoin wiki pages to static HTML files.
Detailed Instructions:
======================
General syntax: moin [options] export dump [dump-options]
[options] usually should be:
--config-dir=/path/to/my/cfg/ --wiki-url=wiki.example.org/
[dump-options] see below:
0. You must run this script as owner of the wiki files, usually this is the
web server user.
1. To dump all the pages on the wiki to the directory '/mywiki'
moin ... export dump --target-dir=/mywiki
2. To dump all the pages readable by 'JohnSmith' on the wiki to the directory
'/mywiki'
moin ... export dump --target-dir=/mywiki --username JohnSmith
"""
def __init__(self, argv=None, def_values=None):
script.MoinScript.__init__(self, argv, def_values)
self.parser.add_option(
"-t", "--target-dir", dest = "target_dir",
help = "Write html dump to DIRECTORY"
)
self.parser.add_option(
"-u", "--username", dest = "dump_user",
help = "User the dump will be performed as (for ACL checks, etc)"
)
def mainloop(self):
""" moin-dump's main code. """
# Prepare output directory
if not self.options.target_dir:
script.fatal("you must use --target-dir=/your/output/path to specify the directory we write the html files to")
outputdir = os.path.abspath(self.options.target_dir)
try:
os.mkdir(outputdir)
script.log("Created output directory '%s'!" % outputdir)
except OSError, err:
if err.errno != errno.EEXIST:
script.fatal("Cannot create output directory '%s'!" % outputdir)
# Insert config dir or the current directory to the start of the path.
config_dir = self.options.config_dir
if config_dir and os.path.isfile(config_dir):
config_dir = os.path.dirname(config_dir)
if config_dir and not os.path.isdir(config_dir):
script.fatal("bad path given to --config-dir option")
sys.path.insert(0, os.path.abspath(config_dir or os.curdir))
self.init_request()
request = self.request
# fix url_prefix_static so we get relative paths in output html
request.cfg.url_prefix_static = url_prefix_static
# use this user for permissions checks
request.user = user.User(request, name=self.options.dump_user)
pages = request.rootpage.getPageList(user='') # get list of all pages in wiki
pages.sort()
if self.options.page: # did user request a particular page or group of pages?
try:
namematch = re.compile(self.options.page)
pages = [page for page in pages if namematch.match(page)]
if not pages:
pages = [self.options.page]
except:
pages = [self.options.page]
wikiutil.quoteWikinameURL = lambda pagename, qfn=wikiutil.quoteWikinameFS: (qfn(pagename) + HTML_SUFFIX)
AttachFile.getAttachUrl = lambda pagename, filename, request, **kw: _attachment(request, pagename, filename, outputdir, **kw)
errfile = os.path.join(outputdir, 'error.log')
errlog = open(errfile, 'w')
errcnt = 0
page_front_page = wikiutil.getLocalizedPage(request, request.cfg.page_front_page).page_name
page_title_index = wikiutil.getLocalizedPage(request, 'TitleIndex').page_name
page_word_index = wikiutil.getLocalizedPage(request, 'WordIndex').page_name
navibar_html = ''
for p in [page_front_page, page_title_index, page_word_index]:
navibar_html += '[<a href="%s">%s</a>]&nbsp;' % (wikiutil.quoteWikinameURL(p), wikiutil.escape(p))
urlbase = request.url # save wiki base url
for pagename in pages:
# we have the same name in URL and FS
file = wikiutil.quoteWikinameURL(pagename)
script.log('Writing "%s"...' % file)
try:
pagehtml = ''
request.url = urlbase + pagename # add current pagename to url base
page = Page.Page(request, pagename)
request.page = page
try:
request.reset()
pagehtml = request.redirectedOutput(page.send_page, count_hit=0, content_only=1)
except:
errcnt = errcnt + 1
print >> sys.stderr, "*** Caught exception while writing page!"
print >> errlog, "~" * 78
print >> errlog, file # page filename
import traceback
traceback.print_exc(None, errlog)
finally:
timestamp = time.strftime("%Y-%m-%d %H:%M")
filepath = os.path.join(outputdir, file)
fileout = codecs.open(filepath, 'w', config.charset)
fileout.write(page_template % {
'charset': config.charset,
'pagename': pagename,
'pagehtml': pagehtml,
'logo_html': logo_html,
'navibar_html': navibar_html,
'timestamp': timestamp,
'theme': request.cfg.theme_default,
})
fileout.close()
# copy FrontPage to "index.html"
indexpage = page_front_page
if self.options.page:
indexpage = pages[0] # index page has limited use when dumping specific pages, but create one anyway
shutil.copyfile(
os.path.join(outputdir, wikiutil.quoteWikinameFS(indexpage) + HTML_SUFFIX),
os.path.join(outputdir, 'index' + HTML_SUFFIX)
)
errlog.close()
if errcnt:
print >> sys.stderr, "*** %d error(s) occurred, see '%s'!" % (errcnt, errfile)

View file

@ -1,454 +0,0 @@
# -*- coding: iso-8859-1 -*-
"""
MoinMoin - Wiki Security Interface and Access Control Lists
This implements the basic interface for user permissions and
system policy. If you want to define your own policy, inherit
from the base class 'Permissions', so that when new permissions
are defined, you get the defaults.
Then assign your new class to "SecurityPolicy" in wikiconfig;
and I mean the class, not an instance of it!
@copyright: 2000-2004 Juergen Hermann <jh@web.de>,
2003-2008 MoinMoin:ThomasWaldmann,
2003 Gustavo Niemeyer,
2005 Oliver Graf,
2007 Alexander Schremmer
@license: GNU GPL, see COPYING for details.
"""
import re
from MoinMoin import wikiutil, user
from MoinMoin.Page import Page
#############################################################################
### Basic Permissions Interface -- most features enabled by default
#############################################################################
def _check(request, pagename, username, right):
""" Check <right> access permission for user <username> on page <pagename>
For cfg.acl_hierarchic=False we just check the page in question.
For cfg.acl_hierarchic=True we, we check each page in the hierarchy. We
start with the deepest page and recurse to the top of the tree.
If one of those permits, True is returned.
For both configurations, we check acl_rights_before before the page/default
acl and acl_rights_after after the page/default acl, of course.
This method should not be called by users, use __getattr__ instead.
@param request: the current request object
@param pagename: pagename to get permissions from
@param username: the user name
@param right: the right to check
@rtype: bool
@return: True if you have permission or False
"""
cache = request.cfg.cache
allowed = cache.acl_rights_before.may(request, username, right)
if allowed is not None:
return allowed
if request.cfg.acl_hierarchic:
pages = pagename.split('/') # create page hierarchy list
some_acl = False
for i in range(len(pages), 0, -1):
# Create the next pagename in the hierarchy
# starting at the leaf, going to the root
name = '/'.join(pages[:i])
# Get page acl and ask for permission
acl = Page(request, name).getACL(request)
if acl.acl:
some_acl = True
allowed = acl.may(request, username, right)
if allowed is not None:
return allowed
if not some_acl:
allowed = cache.acl_rights_default.may(request, username, right)
if allowed is not None:
return allowed
else:
if request.page is not None and pagename == request.page.page_name:
p = request.page # reuse is good
else:
p = Page(request, pagename)
acl = p.getACL(request) # this will be fast in a reused page obj
allowed = acl.may(request, username, right)
if allowed is not None:
return allowed
allowed = cache.acl_rights_after.may(request, username, right)
if allowed is not None:
return allowed
return False
class Permissions:
""" Basic interface for user permissions and system policy.
Note that you still need to allow some of the related actions, this
just controls their behavior, not their activation.
When sub classing this class, you must extend the class methods, not
replace them, or you might break the acl in the wiki. Correct sub
classing looks like this:
def read(self, pagename):
# Your special security rule
if something:
return false
# Do not return True or you break acl!
# This call will use the default acl rules
return Permissions.read(pagename)
"""
def __init__(self, user):
self.name = user.name
self.request = user._request
def save(self, editor, newtext, rev, **kw):
""" Check whether user may save a page.
`editor` is the PageEditor instance, the other arguments are
those of the `PageEditor.saveText` method.
@param editor: PageEditor instance.
@param newtext: new page text, you can enable of disable saving according
to the content of the text, e.g. prevent link spam.
@param rev: new revision number? XXX
@param kw: XXX
@rtype: bool
@return: True if you can save or False
"""
return self.write(editor.page_name)
def __getattr__(self, attr):
""" Shortcut to export getPermission function for all known ACL rights
if attr is one of the rights in acl_rights_valid, then return a
checking function for it. Else raise an AttributeError.
@param attr: one of ACL rights as defined in acl_rights_valid
@rtype: function
@return: checking function for that right, accepting a pagename
"""
request = self.request
if attr not in request.cfg.acl_rights_valid:
raise AttributeError, attr
return lambda pagename: _check(self.request, pagename, self.name, attr)
# make an alias for the default policy
Default = Permissions
class AccessControlList:
''' Access Control List
Control who may do what on or with a wiki page.
Syntax of an ACL string:
[+|-]User[,User,...]:[right[,right,...]] [[+|-]SomeGroup:...] ...
... [[+|-]Known:...] [[+|-]All:...]
"User" is a user name and triggers only if the user matches. Up
to version 1.2 only WikiNames were supported, as of version 1.3,
any name can be used in acl lines, including name with spaces
using esoteric languages.
"SomeGroup" is a page name matching cfg.page_group_regex with
some lines in the form " * Member", defining the group members.
"Known" is a group containing all valid / known users.
"All" is a group containing all users (Known and Anonymous users).
"right" may be an arbitrary word like read, write, delete, admin.
Only words in cfg.acl_validrights are accepted, others are
ignored. It is allowed to specify no rights, which means that no
rights are given.
How ACL is processed
When some user is trying to access some ACL-protected resource,
the ACLs will be processed in the order they are found. The first
matching ACL will tell if the user has access to that resource
or not.
For example, the following ACL tells that SomeUser is able to
read and write the resources protected by that ACL, while any
member of SomeGroup (besides SomeUser, if part of that group)
may also admin that, and every other user is able to read it.
SomeUser:read,write SomeGroup:read,write,admin All:read
In this example, SomeUser can read and write but can not admin,
revert or delete pages. Rights that are NOT specified on the
right list are automatically set to NO.
Using Prefixes
To make the system more flexible, there are also two modifiers:
the prefixes "+" and "-".
+SomeUser:read -OtherUser:write
The acl line above will grant SomeUser read right, and OtherUser
write right, but will NOT block automatically all other rights
for these users. For example, if SomeUser ask to write, the
above acl line does not define if he can or can not write. He
will be able to write if acl_rights_before or acl_rights_after
allow this (see configuration options).
Using prefixes, this acl line:
SomeUser:read,write SomeGroup:read,write,admin All:read
Can be written as:
-SomeUser:admin SomeGroup:read,write,admin All:read
Or even:
+All:read -SomeUser:admin SomeGroup:read,write,admin
Notice that you probably will not want to use the second and
third examples in ACL entries of some page. They are very
useful on the moin configuration entries though.
Configuration options
cfg.acl_rights_default
It is is ONLY used when no other ACLs are given.
Default: "Known:read,write,delete All:read,write",
cfg.acl_rights_before
When the page has ACL entries, this will be inserted BEFORE
any page entries.
Default: ""
cfg.acl_rights_after
When the page has ACL entries, this will be inserted AFTER
any page entries.
Default: ""
cfg.acl_rights_valid
These are the acceptable (known) rights (and the place to
extend, if necessary).
Default: ["read", "write", "delete", "admin"]
'''
special_users = ["All", "Known", "Trusted"] # order is important
def __init__(self, cfg, lines=[]):
"""Initialize an ACL, starting from <nothing>.
"""
if lines:
self.acl = [] # [ ('User', {"read": 0, ...}), ... ]
self.acl_lines = []
for line in lines:
self._addLine(cfg, line)
else:
self.acl = None
self.acl_lines = None
def _addLine(self, cfg, aclstring, remember=1):
""" Add another ACL line
This can be used in multiple subsequent calls to process longer lists.
@param cfg: current config
@param aclstring: acl string from page or cfg
@param remember: should add the line to self.acl_lines
"""
# Remember lines
if remember:
self.acl_lines.append(aclstring)
# Iterate over entries and rights, parsed by acl string iterator
acliter = ACLStringIterator(cfg.acl_rights_valid, aclstring)
for modifier, entries, rights in acliter:
if entries == ['Default']:
self._addLine(cfg, cfg.acl_rights_default, remember=0)
else:
for entry in entries:
rightsdict = {}
if modifier:
# Only user rights are added to the right dict.
# + add rights with value of 1
# - add right with value of 0
for right in rights:
rightsdict[right] = (modifier == '+')
else:
# All rights from acl_rights_valid are added to the
# dict, user rights with value of 1, and other with
# value of 0
for right in cfg.acl_rights_valid:
rightsdict[right] = (right in rights)
self.acl.append((entry, rightsdict))
def may(self, request, name, dowhat):
""" May <name> <dowhat>? Returns boolean answer.
Note: this check does NOT include the acl_rights_before / _after ACL,
but it WILL use acl_rights_default if there is no (page) ACL.
"""
if self.acl is None: # no #acl used on Page
acl = request.cfg.cache.acl_rights_default.acl
else: # we have a #acl on the page (self.acl can be [] if #acl is empty!)
acl = self.acl
is_group_member = request.dicts.has_member
group_re = request.cfg.cache.page_group_regexact
allowed = None
for entry, rightsdict in acl:
if entry in self.special_users:
handler = getattr(self, "_special_"+entry, None)
allowed = handler(request, name, dowhat, rightsdict)
elif group_re.search(entry):
if is_group_member(entry, name):
allowed = rightsdict.get(dowhat)
else:
for special in self.special_users:
if is_group_member(entry, special):
handler = getattr(self, "_special_" + special, None)
allowed = handler(request, name, dowhat, rightsdict)
break # order of self.special_users is important
elif entry == name:
allowed = rightsdict.get(dowhat)
if allowed is not None:
return allowed
return allowed # should be None
def getString(self, b='#acl ', e='\n'):
"""print the acl strings we were fed with"""
if self.acl_lines:
acl_lines = ''.join(["%s%s%s" % (b, l, e) for l in self.acl_lines])
else:
acl_lines = ''
return acl_lines
def _special_All(self, request, name, dowhat, rightsdict):
return rightsdict.get(dowhat)
def _special_Known(self, request, name, dowhat, rightsdict):
""" check if user <name> is known to us,
that means that there is a valid user account present.
works for subscription emails.
"""
if user.getUserId(request, name): # is a user with this name known?
return rightsdict.get(dowhat)
return None
def _special_Trusted(self, request, name, dowhat, rightsdict):
""" check if user <name> is known AND has logged in using a trusted
authentication method.
Does not work for subsription emails that should be sent to <user>,
as he is not logged in in that case.
"""
if (request.user.name == name and
request.user.auth_method in request.cfg.auth_methods_trusted):
return rightsdict.get(dowhat)
return None
def __eq__(self, other):
return self.acl_lines == other.acl_lines
def __ne__(self, other):
return self.acl_lines != other.acl_lines
class ACLStringIterator:
""" Iterator for acl string
Parse acl string and return the next entry on each call to
next. Implement the Iterator protocol.
Usage:
iter = ACLStringIterator(cfg.acl_rights_valid, 'user name:right')
for modifier, entries, rights in iter:
# process data
"""
def __init__(self, rights, aclstring):
""" Initialize acl iterator
@param rights: the acl rights to consider when parsing
@param aclstring: string to parse
"""
self.rights = rights
self.rest = aclstring.strip()
self.finished = 0
def __iter__(self):
""" Required by the Iterator protocol """
return self
def next(self):
""" Return the next values from the acl string
When the iterator is finished and you try to call next, it
raises a StopIteration. The iterator finish as soon as the
string is fully parsed or can not be parsed any more.
@rtype: 3 tuple - (modifier, [entry, ...], [right, ...])
@return: values for one item in an acl string
"""
# Handle finished state, required by iterator protocol
if self.rest == '':
self.finished = 1
if self.finished:
raise StopIteration
# Get optional modifier [+|-]entries:rights
modifier = ''
if self.rest[0] in ('+', '-'):
modifier, self.rest = self.rest[0], self.rest[1:]
# Handle the Default meta acl
if self.rest.startswith('Default ') or self.rest == 'Default':
self.rest = self.rest[8:]
entries, rights = ['Default'], []
# Handle entries:rights pairs
else:
# Get entries
try:
entries, self.rest = self.rest.split(':', 1)
except ValueError:
self.finished = 1
raise StopIteration("Can't parse rest of string")
if entries == '':
entries = []
else:
# TODO strip each entry from blanks?
entries = entries.split(',')
# Get rights
try:
rights, self.rest = self.rest.split(' ', 1)
# Remove extra white space after rights fragment,
# allowing using multiple spaces between items.
self.rest = self.rest.lstrip()
except ValueError:
rights, self.rest = self.rest, ''
rights = [r for r in rights.split(',') if r in self.rights]
return modifier, entries, rights
def parseACL(request, text):
""" Parse acl lines from text and return ACL object """
pi, dummy = wikiutil.get_processing_instructions(text)
acl_lines = [args for verb, args in pi if verb == 'acl']
return AccessControlList(request.cfg, acl_lines)

View file

@ -1,501 +0,0 @@
# -*- coding: iso-8859-1 -*-
"""
MoinMoin - Wiki Security Interface and Access Control Lists
This implements the basic interface for user permissions and
system policy. If you want to define your own policy, inherit
from the base class 'Permissions', so that when new permissions
are defined, you get the defaults.
Then assign your new class to "SecurityPolicy" in wikiconfig;
and I mean the class, not an instance of it!
@copyright: 2000-2004 Juergen Hermann <jh@web.de>,
2003-2008 MoinMoin:ThomasWaldmann,
2003 Gustavo Niemeyer,
2005 Oliver Graf,
2007 Alexander Schremmer
@license: GNU GPL, see COPYING for details.
"""
import re
from MoinMoin import wikiutil, user
from MoinMoin.Page import Page
### HACK SAUVAGE 1/5
import sys
sys.path.append('/usr/scripts/gestion/')
from iptools import is_crans
### FIN HACK 1/5
#############################################################################
### Basic Permissions Interface -- most features enabled by default
#############################################################################
def _check(request, pagename, username, right):
""" Check <right> access permission for user <username> on page <pagename>
For cfg.acl_hierarchic=False we just check the page in question.
For cfg.acl_hierarchic=True we, we check each page in the hierarchy. We
start with the deepest page and recurse to the top of the tree.
If one of those permits, True is returned.
For both configurations, we check acl_rights_before before the page/default
acl and acl_rights_after after the page/default acl, of course.
This method should not be called by users, use __getattr__ instead.
@param request: the current request object
@param pagename: pagename to get permissions from
@param username: the user name
@param right: the right to check
@rtype: bool
@return: True if you have permission or False
"""
cache = request.cfg.cache
allowed = cache.acl_rights_before.may(request, username, right)
if allowed is not None:
return allowed
if request.cfg.acl_hierarchic:
pages = pagename.split('/') # create page hierarchy list
some_acl = False
for i in range(len(pages), 0, -1):
# Create the next pagename in the hierarchy
# starting at the leaf, going to the root
name = '/'.join(pages[:i])
# Get page acl and ask for permission
acl = Page(request, name).getACL(request)
if acl.acl:
some_acl = True
allowed = acl.may(request, username, right)
if allowed is not None:
return allowed
if not some_acl:
allowed = cache.acl_rights_default.may(request, username, right)
if allowed is not None:
return allowed
else:
if request.page is not None and pagename == request.page.page_name:
p = request.page # reuse is good
else:
p = Page(request, pagename)
acl = p.getACL(request) # this will be fast in a reused page obj
allowed = acl.may(request, username, right)
if allowed is not None:
return allowed
allowed = cache.acl_rights_after.may(request, username, right)
if allowed is not None:
return allowed
return False
class Permissions:
""" Basic interface for user permissions and system policy.
Note that you still need to allow some of the related actions, this
just controls their behavior, not their activation.
When sub classing this class, you must extend the class methods, not
replace them, or you might break the acl in the wiki. Correct sub
classing looks like this:
def read(self, pagename):
# Your special security rule
if something:
return false
# Do not return True or you break acl!
# This call will use the default acl rules
return Permissions.read(pagename)
"""
def __init__(self, user):
self.name = user.name
self.request = user._request
def save(self, editor, newtext, rev, **kw):
""" Check whether user may save a page.
`editor` is the PageEditor instance, the other arguments are
those of the `PageEditor.saveText` method.
@param editor: PageEditor instance.
@param newtext: new page text, you can enable of disable saving according
to the content of the text, e.g. prevent link spam.
@param rev: new revision number? XXX
@param kw: XXX
@rtype: bool
@return: True if you can save or False
"""
return self.write(editor.page_name)
def __getattr__(self, attr):
""" Shortcut to export getPermission function for all known ACL rights
if attr is one of the rights in acl_rights_valid, then return a
checking function for it. Else raise an AttributeError.
@param attr: one of ACL rights as defined in acl_rights_valid
@rtype: function
@return: checking function for that right, accepting a pagename
"""
request = self.request
if attr not in request.cfg.acl_rights_valid:
raise AttributeError, attr
return lambda pagename: _check(self.request, pagename, self.name, attr)
# make an alias for the default policy
Default = Permissions
class AccessControlList:
''' Access Control List
Control who may do what on or with a wiki page.
Syntax of an ACL string:
[+|-]User[,User,...]:[right[,right,...]] [[+|-]SomeGroup:...] ...
... [[+|-]Known:...] [[+|-]All:...]
"User" is a user name and triggers only if the user matches. Up
to version 1.2 only WikiNames were supported, as of version 1.3,
any name can be used in acl lines, including name with spaces
using esoteric languages.
"SomeGroup" is a page name matching cfg.page_group_regex with
some lines in the form " * Member", defining the group members.
"Known" is a group containing all valid / known users.
"All" is a group containing all users (Known and Anonymous users).
"right" may be an arbitrary word like read, write, delete, admin.
Only words in cfg.acl_validrights are accepted, others are
ignored. It is allowed to specify no rights, which means that no
rights are given.
How ACL is processed
When some user is trying to access some ACL-protected resource,
the ACLs will be processed in the order they are found. The first
matching ACL will tell if the user has access to that resource
or not.
For example, the following ACL tells that SomeUser is able to
read and write the resources protected by that ACL, while any
member of SomeGroup (besides SomeUser, if part of that group)
may also admin that, and every other user is able to read it.
SomeUser:read,write SomeGroup:read,write,admin All:read
In this example, SomeUser can read and write but can not admin,
revert or delete pages. Rights that are NOT specified on the
right list are automatically set to NO.
Using Prefixes
To make the system more flexible, there are also two modifiers:
the prefixes "+" and "-".
+SomeUser:read -OtherUser:write
The acl line above will grant SomeUser read right, and OtherUser
write right, but will NOT block automatically all other rights
for these users. For example, if SomeUser ask to write, the
above acl line does not define if he can or can not write. He
will be able to write if acl_rights_before or acl_rights_after
allow this (see configuration options).
Using prefixes, this acl line:
SomeUser:read,write SomeGroup:read,write,admin All:read
Can be written as:
-SomeUser:admin SomeGroup:read,write,admin All:read
Or even:
+All:read -SomeUser:admin SomeGroup:read,write,admin
Notice that you probably will not want to use the second and
third examples in ACL entries of some page. They are very
useful on the moin configuration entries though.
Configuration options
cfg.acl_rights_default
It is is ONLY used when no other ACLs are given.
Default: "Known:read,write,delete All:read,write",
cfg.acl_rights_before
When the page has ACL entries, this will be inserted BEFORE
any page entries.
Default: ""
cfg.acl_rights_after
When the page has ACL entries, this will be inserted AFTER
any page entries.
Default: ""
cfg.acl_rights_valid
These are the acceptable (known) rights (and the place to
extend, if necessary).
Default: ["read", "write", "delete", "admin"]
'''
#special_users = ["All", "Known", "Trusted"] # order is important
### HACK SAUVAGE 2/5
special_users = ["All", "Known", "Trusted", "Crans", "NoCrans"] # order is important
### FIN HACK 2/5
def __init__(self, cfg, lines=[]):
"""Initialize an ACL, starting from <nothing>.
"""
if lines:
self.acl = [] # [ ('User', {"read": 0, ...}), ... ]
self.acl_lines = []
for line in lines:
self._addLine(cfg, line)
else:
self.acl = None
self.acl_lines = None
def _addLine(self, cfg, aclstring, remember=1):
""" Add another ACL line
This can be used in multiple subsequent calls to process longer lists.
@param cfg: current config
@param aclstring: acl string from page or cfg
@param remember: should add the line to self.acl_lines
"""
# Remember lines
if remember:
self.acl_lines.append(aclstring)
# Iterate over entries and rights, parsed by acl string iterator
acliter = ACLStringIterator(cfg.acl_rights_valid, aclstring)
for modifier, entries, rights in acliter:
if entries == ['Default']:
self._addLine(cfg, cfg.acl_rights_default, remember=0)
else:
for entry in entries:
rightsdict = {}
if modifier:
# Only user rights are added to the right dict.
# + add rights with value of 1
# - add right with value of 0
for right in rights:
rightsdict[right] = (modifier == '+')
else:
# All rights from acl_rights_valid are added to the
# dict, user rights with value of 1, and other with
# value of 0
for right in cfg.acl_rights_valid:
rightsdict[right] = (right in rights)
self.acl.append((entry, rightsdict))
def may(self, request, name, dowhat):
""" May <name> <dowhat>? Returns boolean answer.
Note: this check does NOT include the acl_rights_before / _after ACL,
but it WILL use acl_rights_default if there is no (page) ACL.
"""
if self.acl is None: # no #acl used on Page
acl = request.cfg.cache.acl_rights_default.acl
else: # we have a #acl on the page (self.acl can be [] if #acl is empty!)
acl = self.acl
is_group_member = request.dicts.has_member
group_re = request.cfg.cache.page_group_regexact
allowed = None
for entry, rightsdict in acl:
if entry in self.special_users:
handler = getattr(self, "_special_"+entry, None)
allowed = handler(request, name, dowhat, rightsdict)
elif group_re.search(entry):
if is_group_member(entry, name):
allowed = rightsdict.get(dowhat)
else:
for special in self.special_users:
if is_group_member(entry, special):
handler = getattr(self, "_special_" + special, None)
allowed = handler(request, name, dowhat, rightsdict)
break # order of self.special_users is important
elif entry == name:
allowed = rightsdict.get(dowhat)
if allowed is not None:
return allowed
return allowed # should be None
def getString(self, b='#acl ', e='\n'):
"""print the acl strings we were fed with"""
if self.acl_lines:
acl_lines = ''.join(["%s%s%s" % (b, l, e) for l in self.acl_lines])
else:
acl_lines = ''
return acl_lines
def _special_All(self, request, name, dowhat, rightsdict):
### HACK SAUVAGE 3/5
if dowhat == "read" and is_page_public(request):
return True
### FIN HACK 3/5
return rightsdict.get(dowhat)
def _special_Known(self, request, name, dowhat, rightsdict):
""" check if user <name> is known to us,
that means that there is a valid user account present.
works for subscription emails.
"""
if user.getUserId(request, name): # is a user with this name known?
return rightsdict.get(dowhat)
return None
def _special_Trusted(self, request, name, dowhat, rightsdict):
""" check if user <name> is known AND has logged in using a trusted
authentication method.
Does not work for subsription emails that should be sent to <user>,
as he is not logged in in that case.
"""
if (request.user.name == name and
request.user.auth_method in request.cfg.auth_methods_trusted):
return rightsdict.get(dowhat)
return None
### HACK SAUVAGE 4/5
def _requete_interne(self, request):
try:
if is_crans(request.remote_addr):
return True
except:
pass
return False
def _special_Crans(self, request, name, dowhat, rightsdict):
if self._requete_interne(request):
return rightsdict.get(dowhat)
return None
def _special_NoCrans(self, request, name, dowhat, rightsdict):
if dowhat == "read" and is_page_public(request):
return True
if not self._requete_interne(request):
return rightsdict.get(dowhat)
return None
### FIN HACK 4/5
def __eq__(self, other):
return self.acl_lines == other.acl_lines
def __ne__(self, other):
return self.acl_lines != other.acl_lines
class ACLStringIterator:
""" Iterator for acl string
Parse acl string and return the next entry on each call to
next. Implement the Iterator protocol.
Usage:
iter = ACLStringIterator(cfg.acl_rights_valid, 'user name:right')
for modifier, entries, rights in iter:
# process data
"""
def __init__(self, rights, aclstring):
""" Initialize acl iterator
@param rights: the acl rights to consider when parsing
@param aclstring: string to parse
"""
self.rights = rights
self.rest = aclstring.strip()
self.finished = 0
def __iter__(self):
""" Required by the Iterator protocol """
return self
def next(self):
""" Return the next values from the acl string
When the iterator is finished and you try to call next, it
raises a StopIteration. The iterator finish as soon as the
string is fully parsed or can not be parsed any more.
@rtype: 3 tuple - (modifier, [entry, ...], [right, ...])
@return: values for one item in an acl string
"""
# Handle finished state, required by iterator protocol
if self.rest == '':
self.finished = 1
if self.finished:
raise StopIteration
# Get optional modifier [+|-]entries:rights
modifier = ''
if self.rest[0] in ('+', '-'):
modifier, self.rest = self.rest[0], self.rest[1:]
# Handle the Default meta acl
if self.rest.startswith('Default ') or self.rest == 'Default':
self.rest = self.rest[8:]
entries, rights = ['Default'], []
# Handle entries:rights pairs
else:
# Get entries
try:
entries, self.rest = self.rest.split(':', 1)
except ValueError:
self.finished = 1
raise StopIteration("Can't parse rest of string")
if entries == '':
entries = []
else:
# TODO strip each entry from blanks?
entries = entries.split(',')
# Get rights
try:
rights, self.rest = self.rest.split(' ', 1)
# Remove extra white space after rights fragment,
# allowing using multiple spaces between items.
self.rest = self.rest.lstrip()
except ValueError:
rights, self.rest = self.rest, ''
rights = [r for r in rights.split(',') if r in self.rights]
return modifier, entries, rights
def parseACL(request, text):
""" Parse acl lines from text and return ACL object """
pi, dummy = wikiutil.get_processing_instructions(text)
acl_lines = [args for verb, args in pi if verb == 'acl']
return AccessControlList(request.cfg, acl_lines)
### HACK SAUVAGE 5/5
def is_page_public(request):
#return True
## On recherche si la page est publique
this_page = request.page.page_name
categories = request.page.getCategories(request)
if u'CatégoriePagePublique' in categories:
return True
else:
return None
### FIN HACK 5/5

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff