--- trac/wiki/web_ui.py.orig 2006-10-03 13:40:33.000000000 -0700
+++ trac/wiki/web_ui.py 2006-10-03 14:17:58.000000000 -0700
@@ -36,6 +36,7 @@
from trac.wiki.model import WikiPage
from trac.wiki.formatter import wiki_to_html, wiki_to_oneliner
from trac.mimeview.api import Mimeview, IContentConverter
+from trac.wiki.rbac import WikiAuthorizer
class InvalidWikiPage(TracError):
@@ -49,6 +50,8 @@
page_manipulators = ExtensionPoint(IWikiPageManipulator)
+ authz = property(fget=lambda self: self._get_authz())
+
# IContentConverter methods
def get_supported_conversions(self):
yield ('txt', 'Plain Text', 'txt', 'text/x-trac-wiki', 'text/plain', 9)
@@ -93,6 +96,7 @@
if pagename.endswith('/'):
req.redirect(req.href.wiki(pagename.strip('/')))
+ self.authz.assert_authorization(req.perm, req.authname, pagename, 'WIKI_VIEW')
db = self.env.get_db_cnx()
page = WikiPage(self.env, pagename, version, db)
@@ -135,6 +139,13 @@
req.hdf['wiki.action'] = action
req.hdf['wiki.current_href'] = req.href.wiki(page.name)
+ for permission in self.get_permission_actions():
+ if isinstance(permission, (list, tuple)):
+ permission = permission[0]
+ self.log.debug("PERMISSION: %s", permission)
+ req.hdf['trac.acl.' + permission] =\
+ self.authz.has_authorization(req.perm, req.authname, page.name, permission)
+
return 'wiki.cs', None
# ITimelineEventProvider methods
@@ -154,19 +165,20 @@
"FROM wiki WHERE time>=%s AND time<=%s",
(start, stop))
for t,name,comment,author,version in cursor:
- title = Markup('%s edited by %s',
- wiki.format_page_name(name), author)
- diff_link = html.A('diff', href=href.wiki(name, action='diff',
- version=version))
- if format == 'rss':
- comment = wiki_to_html(comment or '--', self.env, req, db,
- absurls=True)
- else:
- comment = wiki_to_oneliner(comment, self.env, db,
- shorten=True)
- if version > 1:
- comment = Markup('%s (%s)', comment, diff_link)
- yield 'wiki', href.wiki(name), title, t, author, comment
+ if self.authz.has_authorization(req.perm, req.authname, name, 'WIKI_VIEW'):
+ title = Markup('%s edited by %s',
+ wiki.format_page_name(name), author)
+ diff_link = html.A('diff', href=href.wiki(name, action='diff',
+ version=version))
+ if format == 'rss':
+ comment = wiki_to_html(comment or '--', self.env, req, db,
+ absurls=True)
+ else:
+ comment = wiki_to_oneliner(comment, self.env, db,
+ shorten=True)
+ if version > 1:
+ comment = Markup('%s (%s)', comment, diff_link)
+ yield 'wiki', href.wiki(name), title, t, author, comment
# Attachments
def display(id):
@@ -179,6 +191,9 @@
# Internal methods
+ def _get_authz(self):
+ return WikiAuthorizer(self.env)
+
def _set_title(self, req, page, action):
title = name = WikiSystem(self.env).format_page_name(page.name)
if action:
@@ -192,6 +207,7 @@
req.perm.assert_permission('WIKI_ADMIN')
else:
req.perm.assert_permission('WIKI_DELETE')
+ self.authz.assert_authorization(req.perm, req.authname, page.name, 'WIKI_DELETE')
if req.args.has_key('cancel'):
req.redirect(req.href.wiki(page.name))
@@ -218,8 +234,10 @@
req.perm.assert_permission('WIKI_ADMIN')
elif not page.exists:
req.perm.assert_permission('WIKI_CREATE')
+ self.authz.assert_authorization(req.perm, req.authname, page.name, 'WIKI_CREATE')
else:
req.perm.assert_permission('WIKI_MODIFY')
+ self.authz.assert_authorization(req.perm, req.authname, page.name, 'WIKI_MODIFY')
page.text = req.args.get('text')
if req.perm.has_permission('WIKI_ADMIN'):
@@ -245,6 +263,7 @@
req.perm.assert_permission('WIKI_ADMIN')
else:
req.perm.assert_permission('WIKI_DELETE')
+ self.authz.assert_authorization(req.perm, req.authname, page.name, 'WIKI_DELETE')
version = None
if req.args.has_key('delete_version'):
@@ -265,6 +284,7 @@
def _render_diff(self, req, db, page):
req.perm.assert_permission('WIKI_VIEW')
+ self.authz.assert_authorization(req.perm, req.authname, page.name, 'WIKI_VIEW')
if not page.exists:
raise TracError("Version %s of page %s does not exist" %
@@ -350,6 +370,7 @@
def _render_editor(self, req, db, page, preview=False):
req.perm.assert_permission('WIKI_MODIFY')
+ self.authz.assert_authorization(req.perm, req.authname, page.name, 'WIKI_MODIFY')
if req.args.has_key('text'):
page.text = req.args.get('text')
@@ -396,6 +417,7 @@
page.
"""
req.perm.assert_permission('WIKI_VIEW')
+ self.authz.assert_authorization(req.perm, req.authname, page.name, 'WIKI_VIEW')
if not page.exists:
raise TracError, "Page %s does not exist" % page.name
@@ -419,6 +441,7 @@
def _render_view(self, req, db, page):
req.perm.assert_permission('WIKI_VIEW')
+ self.authz.assert_authorization(req.perm, req.authname, page.name, 'WIKI_VIEW')
page_name = self._set_title(req, page, '')
if page.name == 'WikiStart':
@@ -457,14 +480,16 @@
'age': pretty_timedelta(page.time)
}
else:
- if not req.perm.has_permission('WIKI_CREATE'):
+ if not req.perm.has_permission('WIKI_CREATE') and\
+ self.authz.has_authorization(req.perm, req.authname, page.name, 'WIKI_CREATE'):
raise HTTPNotFound('Page %s not found', page.name)
req.hdf['wiki.page_html'] = html.P('Describe "%s" here' % page_name)
# Show attachments
req.hdf['wiki.attachments'] = attachments_to_hdf(self.env, req, db,
'wiki', page.name)
- if req.perm.has_permission('WIKI_MODIFY'):
+ if req.perm.has_permission('WIKI_MODIFY') and\
+ self.authz.has_authorization(req.perm, req.authname, page.name, 'WIKI_MODIFY'):
attach_href = req.href.attachment('wiki', page.name)
req.hdf['wiki.attach_href'] = attach_href
@@ -488,5 +513,6 @@
"AND " + sql_query, args)
for name, date, author, text in cursor:
- yield (req.href.wiki(name), '%s: %s' % (name, shorten_line(text)),
- date, author, shorten_result(text, terms))
+ if self.authz.has_authorization(req.perm, req.authname, name, 'WIKI_VIEW'):
+ yield (req.href.wiki(name), '%s: %s' % (name, shorten_line(text)),
+ date, author, shorten_result(text, terms))
--- trac/wiki/rbac.py.orig 2006-02-13 15:32:45.000000000 -0800
+++ trac/wiki/rbac.py 2006-02-13 15:29:34.000000000 -0800
@@ -0,0 +1,82 @@
+from trac.core import *
+from trac.perm import PermissionError
+from trac.versioncontrol.svn_authz import RealSubversionAuthorizer
+from trac.versioncontrol import Authorizer, PermissionDenied
+
+def SubversionAuthorizer(env, authname):
+ authz_file = env.config.get('wiki', 'authz_file') or\
+ env.config.get('trac', 'authz_file')
+ if not authz_file:
+ return Authorizer()
+
+ module_name = env.config.get('wiki', 'authz_svn_module_name')
+ db = env.get_db_cnx()
+ return ExtendedSubversionAuthorizer(db, authname, module_name, authz_file)
+
+class IWikiAuthzProvider(Interface):
+ """Interface for classes that provide some method of checking a
+ user's access to a portion of the wiki."""
+
+ def has_authorization(user, path, operation):
+ """Verify that the given username is authorized to perform
+ the given operation on the given path.
+ returns boolean."""
+
+class WikiAuthorizer(Component):
+ providers = ExtensionPoint(IWikiAuthzProvider)
+
+ def _accumulate(self, current, result):
+ authmode = self.env.config.get('wiki', 'authorization_mode')
+
+ if authmode == 'require_all':
+ return current & result
+ elif authmode == 'require_one':
+ return current | result
+ else:
+ return True
+
+ def has_authorization(self, perm, user, path, operation):
+ if not perm.has_permission('WIKI_VIEW'):
+ return False
+
+ authzed = True
+ for provider in self.providers:
+ authzed = self._accumulate(authzed, provider.has_authorization(user, path, operation))
+ return authzed or perm.has_permission('TRAC_ADMIN')
+
+ def assert_authorization(self, perm, user, path, operation):
+ if not self.has_authorization(perm, user, path, operation):
+ raise PermissionDenied,\
+ '%s authorization on %s is necessary to perform this operation.' % (operation, 'wiki:' + path)
+
+
+class WikiSubversionAuthorizer(Component):
+ implements(IWikiAuthzProvider)
+
+ def has_authorization(self, user, path, operation):
+ path = '/' + path
+ authorizer = SubversionAuthorizer(self.env, user)
+ self.log.debug("Authorize %s check for: %s on %s:%s", operation, user, authorizer.module_name, path)
+ return authorizer.has_authorization(path, operation)
+
+class ExtendedSubversionAuthorizer(RealSubversionAuthorizer):
+ """Provides extended semantics for the subversion-based authorization"""
+
+ opmap = {'WIKI_CREATE':'c', 'WIKI_DELETE':'d', 'WIKI_MODIFY':'w', 'WIKI_VIEW':'r', 'WIKI_ADMIN':'a'}
+
+ def has_authorization(self, path, op):
+ self._set_opcheck('WIKI_ADMIN')
+ if self.has_permission(path):
+ return True
+ else:
+ self._set_opcheck(op)
+ return self.has_permission(path)
+
+ def _set_opcheck(self, op):
+ op = self.opmap[op]
+ self._get_permission = lambda section, subject: self.__get_permission(section, subject, op)
+
+ def __get_permission(self, section, subject, op):
+ if self.conf_authz.has_option(section, subject):
+ return op in self.conf_authz.get(section, subject)
+ return None