Refactor permissions system to be more reusable.

These changes are necessary to allow plugins (such as liveupdate) to
reuse core parts of the permission system.
This commit is contained in:
Neil Williams
2014-03-10 13:39:44 -07:00
parent 5f063a094a
commit 2d1a5e5495
4 changed files with 47 additions and 32 deletions

View File

@@ -21,6 +21,7 @@
# Inc. All Rights Reserved.
###############################################################################
import inspect
import sys
import os.path
from subprocess import Popen, PIPE
@@ -34,6 +35,7 @@ from r2.lib.translation import (
validate_plural_forms,
)
from r2.lib.plugin import PluginLoader
from r2.lib.permissions import ModeratorPermissionSet
try:
@@ -224,8 +226,8 @@ class DataSource(Source):
class PermissionsDataSource(DataSource):
"""DataSource for PermissionEditor configuration data."""
def __init__(self):
pass
def __init__(self, permission_sets):
self.permission_sets = permission_sets
@classmethod
def _make_marked_json(cls, obj):
@@ -247,17 +249,17 @@ class PermissionsDataSource(DataSource):
raise ValueError, "unsupported type"
def get_source(self):
from r2.lib.permissions import ModeratorPermissionSet
permissions = self._make_marked_json({
"moderator": ModeratorPermissionSet.info,
"moderator_invite": ModeratorPermissionSet.info,
})
return "r.permissions = %s" % permissions
permission_set_info = {k: v.info for k, v in
self.permission_sets.iteritems()}
permissions = self._make_marked_json(permission_set_info)
return "r.permissions = _.extend(r.permissions || {}, %s)" % permissions
@property
def dependencies(self):
return (super(PermissionsDataSource, self).dependencies +
[os.path.join(REDDIT_ROOT, "lib/permissions.py")])
dependencies = set(super(PermissionsDataSource, self).dependencies)
for permission_set in self.permission_sets.itervalues():
dependencies.add(inspect.getsourcefile(permission_set))
return list(dependencies)
class TemplateFileSource(DataSource, FileSource):
@@ -459,7 +461,10 @@ module["reddit"] = LocalizedModule("reddit.js",
"multi.js",
"recommender.js",
"saved.js",
PermissionsDataSource(),
PermissionsDataSource({
"moderator": ModeratorPermissionSet,
"moderator_invite": ModeratorPermissionSet,
}),
wrap=catch_errors,
)

View File

@@ -20,7 +20,8 @@
# Inc. All Rights Reserved.
###############################################################################
from pylons.i18n import _
from pylons.i18n import N_
class PermissionSet(dict):
ALL = 'all'
@@ -72,29 +73,29 @@ class PermissionSet(dict):
class ModeratorPermissionSet(PermissionSet):
info = dict(
access=dict(
title=_('access'),
description=_('manage the lists of contributors and banned users'),
title=N_('access'),
description=N_('manage the lists of contributors and banned users'),
),
config=dict(
title=_('config'),
description=_('edit settings, sidebar, css, and images'),
title=N_('config'),
description=N_('edit settings, sidebar, css, and images'),
),
flair=dict(
title=_('flair'),
description=_('manage user flair, link flair, and flair templates'),
title=N_('flair'),
description=N_('manage user flair, link flair, and flair templates'),
),
mail=dict(
title=_('mail'),
description=_('read and reply to moderator mail'),
title=N_('mail'),
description=N_('read and reply to moderator mail'),
),
posts=dict(
title=_('posts'),
description=_(
title=N_('posts'),
description=N_(
'use the approve, remove, spam, distinguish, and nsfw buttons'),
),
wiki=dict(
title=_('wiki'),
description=_('manage the wiki and access to the wiki'),
title=N_('wiki'),
description=N_('manage the wiki and access to the wiki'),
),
)

View File

@@ -116,6 +116,7 @@ class UserListing(TableListing):
destination = 'friend'
has_add_form = True
headers = None
permissions_form = None
def __init__(self,
builder,
@@ -219,6 +220,18 @@ class InvitedModListing(UserListing):
form_title = _('invite moderator')
remove_self_title = _('you are a moderator of this subreddit. %(action)s')
@property
def permissions_form(self):
from r2.lib.permissions import ModeratorPermissionSet
from r2.lib.pages import ModeratorPermissions
return ModeratorPermissions(
user=None,
permissions_type=self.type,
permissions=ModeratorPermissionSet(all=True),
editable=True,
embedded=True,
)
def sort_moderators(self, items):
items = [(item, item.rel.get_permissions()) for item in items]
for item, permissions in items:

View File

@@ -25,9 +25,7 @@
%>
<%namespace file="utils.html" import="error_field, plain_link" />
<%def name="add_form(title, dest, add_type, container_name, verb=None)">
<% from r2.models import ModeratorPermissionSet %>
<% from r2.lib.pages import ModeratorPermissions %>
<%def name="add_form(title, dest, add_type, container_name, verb=None, permissions_form=None)">
<form action="/post/${dest}"
method="post" class="pretty-form medium-text friend-add"
onsubmit="return post_form(this, '${dest}')"
@@ -48,10 +46,8 @@
%else:
<input type="text" name="name" id="name">
%endif
%if add_type == "moderator_invite":
${ModeratorPermissions(None, 'moderator_invite',
ModeratorPermissionSet(all=True),
editable=True, embedded=True)}
%if permissions_form:
${permissions_form}
&#32;
<span class="permissions-edit">
(<a href="javascript:void(0)">${_('change')}</a>)
@@ -113,7 +109,7 @@
<div class="${thing._class} usertable">
%if thing.addable and thing.has_add_form:
${add_form(thing.form_title, thing.destination, thing.type, thing.container_name)}
${add_form(thing.form_title, thing.destination, thing.type, thing.container_name, permissions_form=thing.permissions_form)}
%endif
%if thing.show_jump_to: