better permission handling for auth.wiki, not yet for wiki_media
This commit is contained in:
@@ -1 +1 @@
|
|||||||
Version 2.00.0 (2012-07-31 22:03:43) dev
|
Version 2.00.0 (2012-08-01 01:02:41) dev
|
||||||
|
|||||||
+64
-35
@@ -3079,9 +3079,10 @@ class Auth(object):
|
|||||||
new_record[key] = value
|
new_record[key] = value
|
||||||
id = archive_table.insert(**new_record)
|
id = archive_table.insert(**new_record)
|
||||||
return id
|
return id
|
||||||
def wiki(self,slug=None,env=None):
|
def wiki(self,slug=None,env=None,manage_permissions=False,force_prefix=''):
|
||||||
if not hasattr(self,'_wiki'):
|
if not hasattr(self,'_wiki'):
|
||||||
self._wiki = Wiki(self,env=env)
|
self._wiki = Wiki(self,manage_permissions=manage_permissions,
|
||||||
|
force_prefix=force_prefix,env=env)
|
||||||
else:
|
else:
|
||||||
self._wiki.env.update(env or {})
|
self._wiki.env.update(env or {})
|
||||||
return self._wiki.read(slug)['content'] if slug else self._wiki()
|
return self._wiki.read(slug)['content'] if slug else self._wiki()
|
||||||
@@ -4393,15 +4394,18 @@ class Wiki(object):
|
|||||||
rows_page = 25
|
rows_page = 25
|
||||||
regex_redirect = re.compile('redirect\s+(\w+\://\S+)\s*')
|
regex_redirect = re.compile('redirect\s+(\w+\://\S+)\s*')
|
||||||
def __init__(self,auth,env=None,automenu=True,render='markmin',
|
def __init__(self,auth,env=None,automenu=True,render='markmin',
|
||||||
manage_permissions=False,force_prefix=None):
|
manage_permissions=False,force_prefix=''):
|
||||||
self.env = env or {}
|
self.env = env or {}
|
||||||
if render == 'markmin':
|
if render == 'markmin':
|
||||||
render = lambda t,env=self.env: \
|
render = lambda t,env=self.env: \
|
||||||
MARKMIN(t.body,url=True,environment=env).xml()
|
MARKMIN(t.body,url=True,environment=env).xml()
|
||||||
self.auth = auth
|
self.auth = auth
|
||||||
self.automenu = automenu
|
self.automenu = automenu
|
||||||
|
if self.auth.user:
|
||||||
|
self.force_prefix = force_prefix % self.auth.user
|
||||||
|
else:
|
||||||
|
self.force_prefix = force_prefix
|
||||||
perms = self.manage_permissions = manage_permissions
|
perms = self.manage_permissions = manage_permissions
|
||||||
self.force_prefix = force_prefix or ''
|
|
||||||
db = auth.db
|
db = auth.db
|
||||||
db.define_table(
|
db.define_table(
|
||||||
'wiki_page',
|
'wiki_page',
|
||||||
@@ -4441,7 +4445,33 @@ class Wiki(object):
|
|||||||
if tag: db.wiki_tag.insert(name=tag,wiki_page=page.id)
|
if tag: db.wiki_tag.insert(name=tag,wiki_page=page.id)
|
||||||
db.wiki_page._after_insert.append(update_tags_insert)
|
db.wiki_page._after_insert.append(update_tags_insert)
|
||||||
db.wiki_page._after_update.append(update_tags_update)
|
db.wiki_page._after_update.append(update_tags_update)
|
||||||
|
# WIKI ACCESS POLICY
|
||||||
|
def not_authorized(self,page=None):
|
||||||
|
raise HTTH(401)
|
||||||
|
def can_read(self,page):
|
||||||
|
if 'everybody' in page.can_read or not self.manage_permissions:
|
||||||
|
return True
|
||||||
|
elif self.auth.user:
|
||||||
|
groups = self.auth.user_groups.values()
|
||||||
|
if ('wiki_editor' in groups or
|
||||||
|
set(groups).intersection(set(page.can_read+page.can_edit)) or
|
||||||
|
page.created_by==self.auth.user.id): return True
|
||||||
|
return False
|
||||||
|
def can_edit(self,page=None):
|
||||||
|
if not self.auth.user: redirect(self.auth.settings.login_url)
|
||||||
|
groups = self.auth.user_groups.values()
|
||||||
|
return ('wiki_editor' in groups or
|
||||||
|
(page is None and 'wiki_author' in groups) or
|
||||||
|
not page is None and (
|
||||||
|
set(groups).intersection(set(page.can_edit)) or
|
||||||
|
page.created_by==self.auth.user.id))
|
||||||
|
def can_manage(self):
|
||||||
|
if not self.auth.user: redirect(self.auth.settings.login_url)
|
||||||
|
groups = self.auth.user_groups.values()
|
||||||
|
return 'wiki_editor' in groups
|
||||||
|
def can_search(self):
|
||||||
|
return True
|
||||||
|
### END POLICY
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
request = current.request
|
request = current.request
|
||||||
if self.automenu:
|
if self.automenu:
|
||||||
@@ -4468,29 +4498,19 @@ class Wiki(object):
|
|||||||
else:
|
else:
|
||||||
return self.read(request.args(0) or 'index')
|
return self.read(request.args(0) or 'index')
|
||||||
|
|
||||||
def first_paragraph(self,mm):
|
def first_paragraph(self,page):
|
||||||
if self.manage_permissions:
|
if not self.can_read(page):
|
||||||
return ''
|
mm = page.body.replace('\r','')
|
||||||
mm = mm.replace('\r','')
|
ps = [p for p in mm.split('\n\n') \
|
||||||
ps = [p for p in mm.split('\n\n') \
|
if not p.startswith('#') and p.strip()]
|
||||||
if not p.startswith('#') and p.strip()]
|
if ps: return ps[0]
|
||||||
if ps: return ps[0]
|
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def check_permission(self,page,field='can_read'):
|
|
||||||
if not self.manage_permissions:
|
|
||||||
return True
|
|
||||||
groups = set(page.get(field,None) or [])
|
|
||||||
if Wiki.everybody in groups or \
|
|
||||||
self.auth.user and groups.intersect(self.auth.user_groups.values()):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
def read(self,slug):
|
def read(self,slug):
|
||||||
if slug in '_cloud':
|
if slug in '_cloud':
|
||||||
return self.cloud()
|
return self.cloud()
|
||||||
page = self.auth.db.wiki_page(slug=slug)
|
page = self.auth.db.wiki_page(slug=slug)
|
||||||
#if page and not self.check_permission(page,'can_read'):
|
if not self.can_read(page): return self.not_authorized(page)
|
||||||
# raise HTTP(401)
|
|
||||||
if current.request.extension == 'html':
|
if current.request.extension == 'html':
|
||||||
if not page:
|
if not page:
|
||||||
url = URL(args=('_edit',slug))
|
url = URL(args=('_edit',slug))
|
||||||
@@ -4520,30 +4540,31 @@ class Wiki(object):
|
|||||||
raise HTTP(401, "Not Authorized")
|
raise HTTP(401, "Not Authorized")
|
||||||
return True
|
return True
|
||||||
def edit(self,slug):
|
def edit(self,slug):
|
||||||
self.check_editor()
|
|
||||||
auth = self.auth
|
auth = self.auth
|
||||||
db = auth.db
|
db = auth.db
|
||||||
page = db.wiki_page(slug=slug)
|
page = db.wiki_page(slug=slug)
|
||||||
|
if not self.can_edit(page): return self.not_authorized(page)
|
||||||
title_guess = ' '.join(c.capitalize() for c in slug.split('-'))
|
title_guess = ' '.join(c.capitalize() for c in slug.split('-'))
|
||||||
if not page:
|
if not page:
|
||||||
if not slug.startswith(self.force_prefix):
|
if not slug.startswith(self.force_prefix):
|
||||||
session.flash='slug bust have "%s" prefix' % self.force_prefix
|
current.session.flash='slug must have "%s" prefix' \
|
||||||
redirect(URL(args=('_edit',force_prefix+slug)))
|
% self.force_prefix
|
||||||
db.wiki_page.can_read = [Wiki.everybody]
|
redirect(URL(args=('_edit',self.force_prefix+slug)))
|
||||||
db.wiki_page.can_edit = [auth.user_group_role()]
|
db.wiki_page.can_read.default = [Wiki.everybody]
|
||||||
|
db.wiki_page.can_edit.default = [auth.user_group_role()]
|
||||||
db.wiki_page.title.default = title_guess
|
db.wiki_page.title.default = title_guess
|
||||||
db.wiki_page.slug.default = slug
|
db.wiki_page.slug.default = slug
|
||||||
db.wiki_page.menu.default = slug
|
db.wiki_page.menu.default = slug
|
||||||
db.wiki_page.body.default = '## %s\n\npage content' % title_guess
|
db.wiki_page.body.default = '## %s\n\npage content' % title_guess
|
||||||
elif not self.check_permission(page,'can_edit'):
|
|
||||||
raise HTTP(401)
|
|
||||||
form = SQLFORM(db.wiki_page,page,deletable=True,showid=False).process()
|
form = SQLFORM(db.wiki_page,page,deletable=True,showid=False).process()
|
||||||
if form.accepted:
|
if form.accepted:
|
||||||
current.session.flash = 'page created'
|
current.session.flash = 'page created'
|
||||||
redirect(URL(args=slug))
|
redirect(URL(args=slug))
|
||||||
|
elif form.deleted:
|
||||||
|
redirect(URL())
|
||||||
return dict(content=form)
|
return dict(content=form)
|
||||||
def pages(self):
|
def pages(self):
|
||||||
self.check_editor()
|
if not self.can_manage(): return self.not_authorized()
|
||||||
self.auth.db.wiki_page.title.represent = lambda title,row: \
|
self.auth.db.wiki_page.title.represent = lambda title,row: \
|
||||||
A(title,_href=URL(args=row.slug))
|
A(title,_href=URL(args=row.slug))
|
||||||
content=SQLFORM.smartgrid(
|
content=SQLFORM.smartgrid(
|
||||||
@@ -4561,6 +4582,9 @@ class Wiki(object):
|
|||||||
request, db = current.request, self.auth.db
|
request, db = current.request, self.auth.db
|
||||||
media = db.wiki_media(id)
|
media = db.wiki_media(id)
|
||||||
if media:
|
if media:
|
||||||
|
if self.manage_permissions:
|
||||||
|
page = db.wiki_page(media.page)
|
||||||
|
if not self.can_read(page): return self.not_authorized(page)
|
||||||
request.args = [media.file]
|
request.args = [media.file]
|
||||||
return current.response.download(request,db)
|
return current.response.download(request,db)
|
||||||
else:
|
else:
|
||||||
@@ -4573,9 +4597,10 @@ class Wiki(object):
|
|||||||
orderby = db.wiki_page.menu)
|
orderby = db.wiki_page.menu)
|
||||||
menu = []
|
menu = []
|
||||||
tree = {'.':menu}
|
tree = {'.':menu}
|
||||||
|
regex = re.compile('\d\:')
|
||||||
for row in rows:
|
for row in rows:
|
||||||
if row.menu:
|
if row.menu:
|
||||||
key = './'+row.menu
|
key = './'+regex.sub('',row.menu)
|
||||||
base = key.rsplit('/',1)[0]
|
base = key.rsplit('/',1)[0]
|
||||||
subtree = tree[key] = []
|
subtree = tree[key] = []
|
||||||
if base in tree:
|
if base in tree:
|
||||||
@@ -4583,23 +4608,27 @@ class Wiki(object):
|
|||||||
request.args(0)==row.slug,
|
request.args(0)==row.slug,
|
||||||
URL(controller,function,args=row.slug),
|
URL(controller,function,args=row.slug),
|
||||||
subtree))
|
subtree))
|
||||||
if self.check_editor(act=False):
|
#if self.auth.user:
|
||||||
|
if True:
|
||||||
submenu = []
|
submenu = []
|
||||||
|
menu.append((current.T('[Wiki]'),None,None,submenu))
|
||||||
if URL() == URL(controller,function) and \
|
if URL() == URL(controller,function) and \
|
||||||
not str(request.args(0)).startswith('_'):
|
not str(request.args(0)).startswith('_'):
|
||||||
submenu.append((current.T('Edit'),None,
|
submenu.append((current.T('Edit'),None,
|
||||||
URL(controller,function,
|
URL(controller,function,
|
||||||
args=('_edit',request.args(0) or 'index'))))
|
args=('_edit',request.args(0) or 'index'))))
|
||||||
|
# if self.can_manage():
|
||||||
submenu.append((current.T('Manage Pages'),None,
|
submenu.append((current.T('Manage Pages'),None,
|
||||||
URL(controller,function,args=('_pages'))))
|
URL(controller,function,args=('_pages'))))
|
||||||
|
# if self.can_search():
|
||||||
submenu.append((current.T('Search Pages'),None,
|
submenu.append((current.T('Search Pages'),None,
|
||||||
URL(controller,function,args=('_search'))))
|
URL(controller,function,args=('_search'))))
|
||||||
submenu.append((current.T('Tag Cloud'),None,
|
submenu.append((current.T('Tag Cloud'),None,
|
||||||
URL(controller,function,args=('_cloud'))))
|
URL(controller,function,args=('_cloud'))))
|
||||||
menu.append((current.T('[Wiki]'),None,None,submenu))
|
|
||||||
return menu
|
return menu
|
||||||
def search(self,tags=None,query=None,cloud=True,preview=True,
|
def search(self,tags=None,query=None,cloud=True,preview=True,
|
||||||
limitby=(0,100),orderby=None):
|
limitby=(0,100),orderby=None):
|
||||||
|
if not self.can_search(): return self.not_authorized()
|
||||||
request = current.request
|
request = current.request
|
||||||
content = CAT()
|
content = CAT()
|
||||||
if tags is None and query is None:
|
if tags is None and query is None:
|
||||||
@@ -4630,7 +4659,7 @@ class Wiki(object):
|
|||||||
def link(t):
|
def link(t):
|
||||||
return A(t,_href=URL(args='_search',vars=dict(tags=t)))
|
return A(t,_href=URL(args='_search',vars=dict(tags=t)))
|
||||||
items = [DIV(H3(A(p.title,_href=URL(args=p.slug))),
|
items = [DIV(H3(A(p.title,_href=URL(args=p.slug))),
|
||||||
MARKMIN(self.first_paragraph(p.body)) \
|
MARKMIN(self.first_paragraph(p)) \
|
||||||
if preview else '',
|
if preview else '',
|
||||||
SPAN(*[link(t.strip()) for t in \
|
SPAN(*[link(t.strip()) for t in \
|
||||||
p.tags or [] if t.strip()]),
|
p.tags or [] if t.strip()]),
|
||||||
|
|||||||
Reference in New Issue
Block a user