diff --git a/r2/r2/controllers/listingcontroller.py b/r2/r2/controllers/listingcontroller.py index a1a63c0cb..2129eccca 100755 --- a/r2/r2/controllers/listingcontroller.py +++ b/r2/r2/controllers/listingcontroller.py @@ -856,7 +856,9 @@ class MessageController(ListingController): elif self.where == 'moderator' and self.subwhere == 'unread': if c.default_sr: srids = Subreddit.reverse_moderator_ids(c.user) - srs = Subreddit._byID(srids, data = False, return_dict = False) + srs = [sr for sr in Subreddit._byID(srids, data=False, + return_dict=False) + if sr.is_moderator_with_perms(c.user, 'mail')] q = queries.get_unread_subreddit_messages_multi(srs) else: q = queries.get_unread_subreddit_messages(c.site) @@ -884,7 +886,9 @@ class MessageController(ListingController): uri='/message/{where}', uri_variants=['/message/inbox', '/message/unread', '/message/sent']) def GET_listing(self, where, mark, message, subwhere = None, **env): - if not (c.default_sr or c.site.is_moderator(c.user) or c.user_is_admin): + if not (c.default_sr + or c.site.is_moderator_with_perms(c.user, 'mail') + or c.user_is_admin): abort(403, "forbidden") if isinstance(c.site, MultiReddit): if not (c.user_is_admin or c.site.is_moderator(c.user)): diff --git a/r2/r2/lib/comment_tree.py b/r2/r2/lib/comment_tree.py index 2ee9cc56c..5b40a8a34 100755 --- a/r2/r2/lib/comment_tree.py +++ b/r2/r2/lib/comment_tree.py @@ -357,13 +357,16 @@ def subreddit_messages(sr, update = False): def moderator_messages(sr_ids): from r2.models import Subreddit + srs = Subreddit._byID(sr_ids) + sr_ids = [sr_id for sr_id, sr in srs.iteritems() + if sr.is_moderator_with_perms(c.user, 'mail')] + def multi_load_tree(sr_ids): - srs = Subreddit._byID(sr_ids, return_dict = False) res = {} - for sr in srs: - trees = subreddit_messages_nocache(sr) + for sr_id in sr_ids: + trees = subreddit_messages_nocache(srs[sr_id]) if trees: - res[sr._id] = trees + res[sr_id] = trees return res res = sgm(g.permacache, sr_ids, miss_fn = multi_load_tree, diff --git a/r2/r2/lib/pages/pages.py b/r2/r2/lib/pages/pages.py index dd0e4ee97..f14e90167 100755 --- a/r2/r2/lib/pages/pages.py +++ b/r2/r2/lib/pages/pages.py @@ -252,9 +252,10 @@ class Reddit(Templated): css_class="reddit-edit", dest="edit")) - buttons.append(NamedButton("modmail", - dest="message/inbox", - css_class="moderator-mail")) + if c.site.is_moderator_with_perms(c.user, 'mail'): + buttons.append(NamedButton("modmail", + dest="message/inbox", + css_class="moderator-mail")) if is_single_subreddit: if c.site.is_moderator_with_perms(c.user, 'access'): diff --git a/r2/r2/lib/permissions.py b/r2/r2/lib/permissions.py index c0e6f1b87..f451091b5 100644 --- a/r2/r2/lib/permissions.py +++ b/r2/r2/lib/permissions.py @@ -83,6 +83,10 @@ class ModeratorPermissionSet(PermissionSet): title=_('flair'), description=_('manage user flair, link flair, and flair templates'), ), + mail=dict( + title=_('mail'), + description=_('read and reply to moderator mail'), + ), posts=dict( title=_('posts'), description=_( diff --git a/r2/r2/models/_builder.pyx b/r2/r2/models/_builder.pyx index 8c01b863f..59eb745fd 100644 --- a/r2/r2/models/_builder.pyx +++ b/r2/r2/models/_builder.pyx @@ -311,7 +311,7 @@ class _MessageBuilder(Builder): # m is wrapped at this time, so it should have an SR subreddit = getattr(m, "subreddit", None) - if subreddit and subreddit.is_moderator(c.user): + if subreddit and subreddit.is_moderator_with_perms(c.user, 'mail'): return True return False diff --git a/r2/r2/models/builder.py b/r2/r2/models/builder.py index 06369e01c..a3a583cd2 100755 --- a/r2/r2/models/builder.py +++ b/r2/r2/models/builder.py @@ -646,6 +646,7 @@ class TopCommentBuilder(CommentBuilder): def get_items(self, num = 10): final = CommentBuilder.get_items(self, num = num) return [ cm for cm in final if not cm.deleted ] + class SrMessageBuilder(MessageBuilder): def __init__(self, sr, **kw): self.sr = sr diff --git a/r2/r2/models/link.py b/r2/r2/models/link.py index 5e89f353a..844572563 100755 --- a/r2/r2/models/link.py +++ b/r2/r2/models/link.py @@ -1258,7 +1258,7 @@ class Message(Thing, Printable): return True elif self.sr_id: sr = Subreddit._byID(self.sr_id) - is_moderator = sr.is_moderator(c.user) + is_moderator = sr.is_moderator_with_perms(c.user, 'mail') # moderators can view messages on subreddits they moderate if is_moderator: return True @@ -1710,8 +1710,10 @@ class ModeratorInbox(Relation(Subreddit, Message)): if not sr._loaded: sr._load() - moderators = Account._byID(sr.moderator_ids(), data=True, - return_dict=False) + mod_perms = sr.moderators_with_perms() + mod_ids = set(mod_id for mod_id, perms in mod_perms.iteritems() + if perms.get('mail', False)) + moderators = Account._byID(mod_ids, data=True, return_dict=False) for m in moderators: if obj.author_id != m._id and not getattr(m, 'modmsgtime', None): m.modmsgtime = obj._date