Add moderator permission for flair.

This commit is contained in:
Logan Hanks
2012-12-12 17:10:32 -08:00
parent 5315281f82
commit dc5cc92962
6 changed files with 56 additions and 36 deletions

View File

@@ -2513,7 +2513,7 @@ class ApiController(RedditController, OAuth2ResourceController):
form.set_html(".status", _('saved'))
@require_oauth2_scope("modflair")
@validatedForm(VFlairManager(),
@validatedForm(VSrModerator(perms='flair'),
VModhash(),
user = VFlairAccount("name"),
link = VFlairLink('link'),
@@ -2528,7 +2528,8 @@ class ApiController(RedditController, OAuth2ResourceController):
else:
site = Subreddit._byID(link.sr_id, data=True)
# make sure c.user has permission to set flair on this link
if not c.user_is_admin and not site.is_moderator(c.user):
if not (c.user_is_admin
or site.is_moderator_with_perms(c.user, 'flair')):
abort(403, 'forbidden')
else:
flair_type = USER_FLAIR
@@ -2587,7 +2588,7 @@ class ApiController(RedditController, OAuth2ResourceController):
form.set_html('.status', _('saved'))
@require_oauth2_scope("modflair")
@validatedForm(VFlairManager(),
@validatedForm(VSrModerator(perms='flair'),
VModhash(),
user = VFlairAccount("name"))
@api_doc(api_section.flair)
@@ -2609,7 +2610,7 @@ class ApiController(RedditController, OAuth2ResourceController):
jquery('.tagline .id-%s' % user._fullname).parent().html(unflair)
@require_oauth2_scope("modflair")
@validate(VFlairManager(),
@validate(VSrModerator(perms='flair'),
VModhash(),
flair_csv = nop('flair_csv'))
@api_doc(api_section.flair)
@@ -2687,7 +2688,7 @@ class ApiController(RedditController, OAuth2ResourceController):
@require_oauth2_scope("modflair")
@validatedForm(
VFlairManager(),
VSrModerator(perms='flair'),
VModhash(),
flair_enabled = VBoolean("flair_enabled"),
flair_position = VOneOf("flair_position", ("left", "right")),
@@ -2734,7 +2735,7 @@ class ApiController(RedditController, OAuth2ResourceController):
return BoringPage(_("API"), content = flair).render()
@require_oauth2_scope("modflair")
@validatedForm(VFlairManager(),
@validatedForm(VSrModerator(perms='flair'),
VModhash(),
flair_template = VFlairTemplateByID('flair_template_id'),
text = VFlairText('text'),
@@ -2804,7 +2805,7 @@ class ApiController(RedditController, OAuth2ResourceController):
details='flair_template')
@require_oauth2_scope("modflair")
@validatedForm(VFlairManager(),
@validatedForm(VSrModerator(perms='flair'),
VModhash(),
flair_template = VFlairTemplateByID('flair_template_id'))
@api_doc(api_section.flair)
@@ -2816,7 +2817,7 @@ class ApiController(RedditController, OAuth2ResourceController):
details='flair_delete_template')
@require_oauth2_scope("modflair")
@validatedForm(VFlairManager(), VModhash(),
@validatedForm(VSrModerator(perms='flair'), VModhash(),
flair_type = VOneOf('flair_type', (USER_FLAIR, LINK_FLAIR),
default=USER_FLAIR))
@api_doc(api_section.flair)
@@ -2836,7 +2837,8 @@ class ApiController(RedditController, OAuth2ResourceController):
else:
site = Subreddit._byID(link.sr_id, data=True)
return FlairSelector(link=link, site=site).render()
if user and not (c.user_is_admin or c.site.is_moderator(c.user)):
if user and not (c.user_is_admin
or c.site.is_moderator_with_perms(c.user, 'flair')):
# ignore user parameter if c.user is not mod/admin
user = None
return FlairSelector(user=user).render()
@@ -2874,7 +2876,8 @@ class ApiController(RedditController, OAuth2ResourceController):
flair_template = None
text = None
if not site.is_moderator(c.user) and not c.user_is_admin:
if not (c.user_is_admin
or site.is_moderator_with_perms(c.user, 'flair')):
if not self_assign_enabled:
# TODO: serve error to client
g.log.debug('flair self-assignment not permitted')
@@ -2900,7 +2903,8 @@ class ApiController(RedditController, OAuth2ResourceController):
setattr(user, 'flair_%s_css_class' % site._id, css_class)
user._commit()
if ((site.is_moderator(c.user) or c.user_is_admin)
if ((c.user_is_admin
or site.is_moderator_with_perms(c.user, 'flair'))
and c.user != user):
ModAction.create(site, c.user, action='editflair',
target=user, details='flair_edit')
@@ -2922,7 +2926,7 @@ class ApiController(RedditController, OAuth2ResourceController):
link._commit()
changed(link)
if ((site.is_moderator(c.user) or c.user_is_admin)):
if c.user_is_admin or site.is_moderator_with_perms(c.user, 'flair'):
ModAction.create(site, c.user, action='editflair',
target=link, details='flair_edit')

View File

@@ -590,7 +590,15 @@ class FrontController(RedditController, OAuth2ResourceController):
def _edit_normal_reddit(self, location, num, after, reverse, count, created,
name, user):
# moderator is either reddit's moderator or an admin
is_moderator = c.user_is_loggedin and c.site.is_moderator(c.user) or c.user_is_admin
moderator_rel = c.user_is_loggedin and c.site.get_moderator(c.user)
is_moderator = c.user_is_admin or moderator_rel
is_unlimited_moderator = c.user_is_admin or (
moderator_rel and moderator_rel.is_superuser())
is_moderator_with_perms = lambda *perms: (
c.user_is_admin
or moderator_rel and all(moderator_rel.has_permission(perm)
for perm in perms))
extension_handling = False
if is_moderator and location == 'edit':
pane = PaneStack()
@@ -600,7 +608,7 @@ class FrontController(RedditController, OAuth2ResourceController):
c.site = Subreddit._byID(c.site._id, data=True, stale=False)
pane.append(CreateSubreddit(site = c.site))
elif location == 'moderators':
pane = ModList(editable = is_moderator)
pane = ModList(editable=is_unlimited_moderator)
elif is_moderator and location == 'banned':
pane = BannedList(editable = is_moderator)
elif is_moderator and location == 'wikibanned':
@@ -640,7 +648,7 @@ class FrontController(RedditController, OAuth2ResourceController):
extension_handling = "private"
elif (is_moderator or c.user_is_sponsor) and location == 'traffic':
pane = trafficpages.SubredditTraffic()
elif is_moderator and location == 'flair':
elif is_moderator_with_perms('flair') and location == 'flair':
c.allow_styles = True
pane = FlairPane(num, after, reverse, name, user)
elif c.user_is_sponsor and location == 'ads':

View File

@@ -274,8 +274,9 @@ class Reddit(Templated):
NamedButton("spam", css_class="reddit-spam")]
if is_single_subreddit:
buttons += [NamedButton("banned", css_class="reddit-ban"),
NamedButton("flair", css_class="reddit-flair")]
buttons.append(NamedButton("banned", css_class="reddit-ban"))
if c.site.is_moderator_with_perms(c.user, 'flair'):
buttons.append(NamedButton("flair", css_class="reddit-flair"))
buttons += [NamedButton("log", css_class="reddit-moderationlog"),
NamedButton("unmoderated", css_class="reddit-unmoderated")]
@@ -2509,7 +2510,8 @@ class WrappedUser(CachedTemplate):
if include_flair_selector:
if (not getattr(c.site, 'flair_self_assign_enabled', True)
and not (c.user_is_admin or c.site.is_moderator(c.user))):
and not (c.user_is_admin
or c.site.is_moderator_with_perms(c.user, 'flair'))):
include_flair_selector = False
target = None
@@ -2734,7 +2736,8 @@ class FlairPrefs(CachedTemplate):
class FlairSelectorLinkSample(CachedTemplate):
def __init__(self, link, site, flair_template):
flair_position = getattr(site, 'link_flair_position', 'right')
admin = bool(c.user_is_admin or site.is_moderator(c.user))
admin = bool(c.user_is_admin
or site.is_moderator_with_perms(c.user, 'flair'))
CachedTemplate.__init__(
self,
title=link.title,
@@ -2752,7 +2755,8 @@ class FlairSelector(CachedTemplate):
user = c.user
if site is None:
site = c.site
admin = bool(c.user_is_admin or site.is_moderator(c.user))
admin = bool(c.user_is_admin
or site.is_moderator_with_perms(c.user, 'flair'))
if link:
flair_type = LINK_FLAIR

View File

@@ -87,8 +87,6 @@ class LinkButtons(PrintableButtons):
else:
show_unmarknsfw = False
show_flair = thing.can_ban or is_author
# do we show the delete button?
show_delete = is_author and delete and not thing._deleted
# disable the delete button for live sponsored links
@@ -128,7 +126,7 @@ class LinkButtons(PrintableButtons):
show_distinguish = show_distinguish,
show_marknsfw = show_marknsfw,
show_unmarknsfw = show_unmarknsfw,
show_flair = show_flair,
show_flair = thing.can_flair,
show_comments = comments,
# promotion
promoted = thing.promoted,

View File

@@ -873,14 +873,6 @@ class VSrModerator(Validator):
abort(403, "forbidden")
return self.set_error('MODERATOR_REQUIRED', code=403)
class VFlairManager(VSrModerator):
"""Validates that a user is permitted to manage flair for a subreddit.
Currently this is the same as VSrModerator. It's a separate class to act as
a placeholder if we ever need to give mods a way to delegate this aspect of
subreddit administration."""
pass
class VCanDistinguish(VByName):
def run(self, thing_name, how):
if c.user_is_admin:

View File

@@ -84,11 +84,17 @@ class Builder(object):
subreddits = Subreddit.load_subreddits(items, stale=self.stale)
if not user:
can_ban_set = set()
else:
can_ban_set = set(id for (id,sr) in subreddits.iteritems()
if sr.can_ban(user))
can_ban_set = set()
can_flair_set = set()
can_own_flair_set = set()
if user:
for sr_id, sr in subreddits.iteritems():
if sr.can_ban(user):
can_ban_set.add(sr_id)
if sr.is_moderator_with_perms(user, 'flair'):
can_flair_set.add(sr_id)
if sr.link_flair_self_assign_enabled:
can_own_flair_set.add(sr_id)
#get likes/dislikes
try:
@@ -222,6 +228,7 @@ class Builder(object):
w.show_reports = False
w.show_spam = False
w.can_ban = False
w.can_flair = False
w.use_big_modbuttons = self.spam_listing
if (c.user_is_admin
@@ -255,6 +262,13 @@ class Builder(object):
w.show_reports = True
w.use_big_modbuttons = True
if (c.user_is_admin
or (user and hasattr(item, 'sr_id')
and (item.sr_id in can_flair_set
or (w.author and w.author._id == user._id
and item.sr_id in can_own_flair_set)))):
w.can_flair = True
# recache the user object: it may be None if user is not logged in,
# whereas now we are happy to have the UnloggedUser object
user = c.user