def wrapper(request, *args, **kw): allow_access = ( acl.is_user_any_kind_of_reviewer(request.user) or acl.action_allowed(request, permissions.RATINGS_MODERATE)) if allow_access: return f(request, *args, **kw) raise PermissionDenied
def get_queryset(self): alog = ActivityLog.objects.for_versions(self.get_version_object()) if not acl.is_user_any_kind_of_reviewer(self.request.user, allow_viewers=True): alog = alog.transform( ActivityLog.transformer_anonymize_user_for_developer) return alog.filter(action__in=amo.LOG_REVIEW_QUEUE_DEVELOPER)
def wrapper(request, *args, **kw): allow_access = (acl.is_user_any_kind_of_reviewer(request.user) or acl.action_allowed(request, permissions.RATINGS_MODERATE)) if allow_access: return f(request, *args, **kw) raise PermissionDenied
def send_notifications(signal=None, sender=None, **kw): if sender.channel != amo.RELEASE_CHANNEL_LISTED: return subscribers = sender.addon.reviewersubscription_set.all() if not subscribers: return for subscriber in subscribers: user = subscriber.user is_reviewer = (user and not user.deleted and user.email and acl.is_user_any_kind_of_reviewer(user)) if is_reviewer: subscriber.send_notification(sender)
def send_notifications(signal=None, sender=None, **kw): if sender.channel != amo.RELEASE_CHANNEL_LISTED: return subscribers = sender.addon.reviewersubscription_set.all() if not subscribers: return for subscriber in subscribers: user = subscriber.user is_reviewer = ( user and not user.deleted and user.email and acl.is_user_any_kind_of_reviewer(user)) if is_reviewer: subscriber.send_notification(sender)
def wrapper(request, *args, **kw): if acl.is_user_any_kind_of_reviewer(request.user): return f(request, *args, **kw) raise PermissionDenied
def wrapper(request, *args, **kw): if acl.is_user_any_kind_of_reviewer(request.user): return f(request, *args, **kw) raise PermissionDenied
def notify_about_activity_log(addon, version, note, perm_setting=None, send_to_reviewers=True, send_to_staff=True): """Notify relevant users about an ActivityLog note.""" comments = (note.details or {}).get('comments') if not comments: # Just use the name of the action if no comments provided. Alas we # can't know the locale of recipient, and our templates are English # only so prevent language jumble by forcing into en-US. with translation.override(settings.LANGUAGE_CODE): comments = '%s' % amo.LOG_BY_ID[note.action].short else: htmlparser = HTMLParser() comments = htmlparser.unescape(comments) # Collect add-on authors (excl. the person who sent the email.) and build # the context for them. addon_authors = set(addon.authors.all()) - {note.user} author_context_dict = { 'name': addon.name, 'number': version.version, 'author': note.user.name, 'comments': comments, 'url': absolutify(addon.get_dev_url('versions')), 'SITE_URL': settings.SITE_URL, 'email_reason': 'you are listed as an author of this add-on', 'is_info_request': note.action == amo.LOG.REQUEST_INFORMATION.id, } # Not being localised because we don't know the recipients locale. with translation.override('en-US'): if note.action == amo.LOG.REQUEST_INFORMATION.id: if addon.pending_info_request: days_left = ( # We pad the time left with an extra hour so that the email # does not end up saying "6 days left" because a few # seconds or minutes passed between the datetime was saved # and the email was sent. addon.pending_info_request + timedelta(hours=1) - datetime.now()).days if days_left > 9: author_context_dict['number_of_days_left'] = ('%d days' % days_left) elif days_left > 1: author_context_dict['number_of_days_left'] = ( '%s (%d) days' % (apnumber(days_left), days_left)) else: author_context_dict['number_of_days_left'] = 'one (1) day' subject = u'Mozilla Add-ons: Action Required for %s %s' % ( addon.name, version.version) reviewer_subject = u'Mozilla Add-ons: %s %s' % (addon.name, version.version) else: subject = reviewer_subject = u'Mozilla Add-ons: %s %s' % ( addon.name, version.version) # Build and send the mail for authors. template = template_from_user(note.user, version) from_email = formataddr((note.user.name, NOTIFICATIONS_FROM_EMAIL)) send_activity_mail(subject, template.render(author_context_dict), version, addon_authors, from_email, note.id, perm_setting) if send_to_reviewers or send_to_staff: # If task_user doesn't exist that's no big issue (i.e. in tests) try: task_user = {get_task_user()} except UserProfile.DoesNotExist: task_user = set() if send_to_reviewers: # Collect reviewers on the thread (excl. the email sender and task user # for automated messages), build the context for them and send them # their copy. log_users = { alog.user for alog in ActivityLog.objects.for_version(version) if acl.is_user_any_kind_of_reviewer(alog.user) } reviewers = log_users - addon_authors - task_user - {note.user} reviewer_context_dict = author_context_dict.copy() reviewer_context_dict['url'] = absolutify( reverse('reviewers.review', kwargs={ 'addon_id': version.addon.pk, 'channel': amo.CHANNEL_CHOICES_API[version.channel] }, add_prefix=False)) reviewer_context_dict['email_reason'] = 'you reviewed this add-on' send_activity_mail(reviewer_subject, template.render(reviewer_context_dict), version, reviewers, from_email, note.id, perm_setting) if send_to_staff: # Collect staff that want a copy of the email, build the context for # them and send them their copy. staff = set( UserProfile.objects.filter(groups__name=ACTIVITY_MAIL_GROUP)) staff_cc = (staff - reviewers - addon_authors - task_user - {note.user}) staff_cc_context_dict = reviewer_context_dict.copy() staff_cc_context_dict['email_reason'] = ( 'you are member of the activity email cc group') send_activity_mail(reviewer_subject, template.render(staff_cc_context_dict), version, staff_cc, from_email, note.id, perm_setting)
def action_from_user(user, version): if version.addon.authors.filter(pk=user.pk).exists(): return amo.LOG.DEVELOPER_REPLY_VERSION elif acl.is_user_any_kind_of_reviewer(user): return amo.LOG.REVIEWER_REPLY_VERSION
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if (not self.instance or not acl.is_user_any_kind_of_reviewer(self.instance)): self.fields.pop('reviewer_name', None)
def notify_about_activity_log(addon, version, note, perm_setting=None, send_to_reviewers=True, send_to_staff=True): """Notify relevant users about an ActivityLog note.""" comments = (note.details or {}).get('comments') if not comments: # Just use the name of the action if no comments provided. Alas we # can't know the locale of recipient, and our templates are English # only so prevent language jumble by forcing into en-US. with translation.override(settings.LANGUAGE_CODE): comments = '%s' % amo.LOG_BY_ID[note.action].short else: htmlparser = HTMLParser() comments = htmlparser.unescape(comments) # Collect add-on authors (excl. the person who sent the email.) and build # the context for them. addon_authors = set(addon.authors.all()) - {note.user} author_context_dict = { 'name': addon.name, 'number': version.version, 'author': note.user.name, 'comments': comments, 'url': absolutify(addon.get_dev_url('versions')), 'SITE_URL': settings.SITE_URL, 'email_reason': 'you are listed as an author of this add-on', 'is_info_request': note.action == amo.LOG.REQUEST_INFORMATION.id, } # Not being localised because we don't know the recipients locale. with translation.override('en-US'): if note.action == amo.LOG.REQUEST_INFORMATION.id: if addon.pending_info_request: days_left = ( # We pad the time left with an extra hour so that the email # does not end up saying "6 days left" because a few # seconds or minutes passed between the datetime was saved # and the email was sent. addon.pending_info_request + timedelta(hours=1) - datetime.now() ).days if days_left > 9: author_context_dict['number_of_days_left'] = ( '%d days' % days_left) elif days_left > 1: author_context_dict['number_of_days_left'] = ( '%s (%d) days' % (apnumber(days_left), days_left)) else: author_context_dict['number_of_days_left'] = 'one (1) day' subject = u'Mozilla Add-ons: Action Required for %s %s' % ( addon.name, version.version) reviewer_subject = u'Mozilla Add-ons: %s %s' % ( addon.name, version.version) else: subject = reviewer_subject = u'Mozilla Add-ons: %s %s' % ( addon.name, version.version) # Build and send the mail for authors. template = template_from_user(note.user, version) from_email = formataddr((note.user.name, NOTIFICATIONS_FROM_EMAIL)) send_activity_mail( subject, template.render(author_context_dict), version, addon_authors, from_email, note.id, perm_setting) if send_to_reviewers or send_to_staff: # If task_user doesn't exist that's no big issue (i.e. in tests) try: task_user = {get_task_user()} except UserProfile.DoesNotExist: task_user = set() if send_to_reviewers: # Collect reviewers on the thread (excl. the email sender and task user # for automated messages), build the context for them and send them # their copy. log_users = { alog.user for alog in ActivityLog.objects.for_version(version) if acl.is_user_any_kind_of_reviewer(alog.user)} reviewers = log_users - addon_authors - task_user - {note.user} reviewer_context_dict = author_context_dict.copy() reviewer_context_dict['url'] = absolutify( reverse('reviewers.review', kwargs={ 'addon_id': version.addon.pk, 'channel': amo.CHANNEL_CHOICES_API[version.channel] }, add_prefix=False)) reviewer_context_dict['email_reason'] = 'you reviewed this add-on' send_activity_mail( reviewer_subject, template.render(reviewer_context_dict), version, reviewers, from_email, note.id, perm_setting) if send_to_staff: # Collect staff that want a copy of the email, build the context for # them and send them their copy. staff = set( UserProfile.objects.filter(groups__name=ACTIVITY_MAIL_GROUP)) staff_cc = ( staff - reviewers - addon_authors - task_user - {note.user}) staff_cc_context_dict = reviewer_context_dict.copy() staff_cc_context_dict['email_reason'] = ( 'you are member of the activity email cc group') send_activity_mail( reviewer_subject, template.render(staff_cc_context_dict), version, staff_cc, from_email, note.id, perm_setting)
def template_from_user(user, version): template = 'activity/emails/developer.txt' if (not version.addon.authors.filter(pk=user.pk).exists() and acl.is_user_any_kind_of_reviewer(user)): template = 'activity/emails/from_reviewer.txt' return loader.get_template(template)
def action_from_user(user, version): if version.addon.authors.filter(pk=user.pk).exists(): return amo.LOG.DEVELOPER_REPLY_VERSION elif acl.is_user_any_kind_of_reviewer(user): return amo.LOG.REVIEWER_REPLY_VERSION
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if (not self.instance or not acl.is_user_any_kind_of_reviewer(self.instance)): self.fields.pop('reviewer_name', None)
def global_settings(request): """ Storing standard AMO-wide information used in global headers, such as account links and settings. """ account_links = [] tools_links = [] context = {} tools_title = ugettext('Tools') is_reviewer = False if request.user.is_authenticated(): is_reviewer = acl.is_user_any_kind_of_reviewer(request.user) account_links.append({'text': ugettext('My Profile'), 'href': request.user.get_url_path()}) if request.user.is_artist: account_links.append({'text': ugettext('My Themes'), 'href': request.user.get_themes_url_path()}) account_links.append({'text': ugettext('Account Settings'), 'href': reverse('users.edit')}) account_links.append({ 'text': ugettext('My Collections'), 'href': reverse('collections.user', args=[request.user.username])}) if request.user.favorite_addons: account_links.append( {'text': ugettext('My Favorites'), 'href': reverse('collections.detail', args=[request.user.username, 'favorites'])}) account_links.append({ 'text': ugettext('Log out'), 'href': reverse('users.logout') + '?to=' + urlquote(request.path), }) if request.user.is_developer: tools_links.append({'text': ugettext('Manage My Submissions'), 'href': reverse('devhub.addons')}) tools_links.append( {'text': ugettext('Submit a New Add-on'), 'href': reverse('devhub.submit.agreement')}) no_more_lwt = waffle.switch_is_active('disable-lwt-uploads') tools_links.append( {'text': ugettext('Submit a New Theme'), 'href': reverse('devhub.submit.agreement' if no_more_lwt else 'devhub.themes.submit')}) tools_links.append( {'text': ugettext('Developer Hub'), 'href': reverse('devhub.index')}) tools_links.append( {'text': ugettext('Manage API Keys'), 'href': reverse('devhub.api_key')} ) if is_reviewer: tools_links.append({'text': ugettext('Reviewer Tools'), 'href': reverse('reviewers.dashboard')}) if acl.action_allowed(request, amo.permissions.ANY_ADMIN): tools_links.append({'text': ugettext('Admin Tools'), 'href': reverse('zadmin.index')}) context['user'] = request.user else: context['user'] = AnonymousUser() context.update({'account_links': account_links, 'settings': settings, 'amo': amo, 'tools_links': tools_links, 'tools_title': tools_title, 'ADMIN_MESSAGE': get_config('site_notice'), 'is_reviewer': is_reviewer}) return context
def has_permission(self, request, view): allow_viewers = request.method in SAFE_METHODS return acl.is_user_any_kind_of_reviewer(request.user, allow_viewers=allow_viewers)
def type_of_user(user, version): if version.addon.authors.filter(pk=user.pk).exists(): return USER_TYPE_ADDON_AUTHOR if acl.is_user_any_kind_of_reviewer(user): return USER_TYPE_ADDON_REVIEWER
def notify_about_activity_log(addon, version, note, perm_setting=None, send_to_reviewers=True, send_to_staff=True): """Notify relevant users about an ActivityLog note.""" comments = (note.details or {}).get('comments') if not comments: # Just use the name of the action if no comments provided. Alas we # can't know the locale of recipient, and our templates are English # only so prevent language jumble by forcing into en-US. with translation.override(settings.LANGUAGE_CODE): comments = '%s' % amo.LOG_BY_ID[note.action].short else: comments = unescape(comments) type_of_sender = type_of_user(note.user, version) sender_name = (ADDON_REVIEWER_NAME if type_of_sender == USER_TYPE_ADDON_REVIEWER else note.user.name) # Collect add-on authors (excl. the person who sent the email.) and build # the context for them. addon_authors = set(addon.authors.all()) - {note.user} author_context_dict = { 'name': addon.name, 'number': version.version, 'author': sender_name, 'comments': comments, 'url': absolutify(addon.get_dev_url('versions')), 'SITE_URL': settings.SITE_URL, 'email_reason': 'you are listed as an author of this add-on', } # Not being localised because we don't know the recipients locale. with translation.override('en-US'): subject = reviewer_subject = 'Mozilla Add-ons: {} {}'.format( addon.name, version.version, ) # Build and send the mail for authors. template = template_from_user(note.user, version) from_email = formataddr((sender_name, NOTIFICATIONS_FROM_EMAIL)) send_activity_mail( subject, template.render(author_context_dict), version, addon_authors, from_email, note.id, perm_setting, ) if send_to_reviewers or send_to_staff: # If task_user doesn't exist that's no big issue (i.e. in tests) try: task_user = {get_task_user()} except UserProfile.DoesNotExist: task_user = set() # Update the author and from_email to use the real name because it will # be used in emails to reviewers and staff, and not add-on developers. from_email = formataddr((note.user.name, NOTIFICATIONS_FROM_EMAIL)) reviewer_context_dict = author_context_dict.copy() reviewer_context_dict['author'] = note.user.name if send_to_reviewers: # Collect reviewers on the thread (excl. the email sender and task user # for automated messages) and send them their copy. log_users = { alog.user for alog in ActivityLog.objects.for_versions(version) if acl.is_user_any_kind_of_reviewer(alog.user) } reviewers = log_users - addon_authors - task_user - {note.user} reviewer_context_dict['url'] = absolutify( reverse( 'reviewers.review', kwargs={ 'addon_id': version.addon.pk, 'channel': amo.CHANNEL_CHOICES_API[version.channel], }, add_prefix=False, )) reviewer_context_dict['email_reason'] = 'you reviewed this add-on' send_activity_mail( reviewer_subject, template.render(reviewer_context_dict), version, reviewers, from_email, note.id, perm_setting, ) if send_to_staff: # Collect staff that want a copy of the email, build the context for # them and send them their copy. staff = set( UserProfile.objects.filter(groups__name=ACTIVITY_MAIL_GROUP)) staff_cc = staff - reviewers - addon_authors - task_user - {note.user} staff_cc_context_dict = reviewer_context_dict.copy() staff_cc_context_dict[ 'email_reason'] = 'you are member of the activity email cc group' send_activity_mail( reviewer_subject, template.render(staff_cc_context_dict), version, staff_cc, from_email, note.id, perm_setting, )
def has_permission(self, request, view): return acl.is_user_any_kind_of_reviewer(request.user)
def template_from_user(user, version): template = 'activity/emails/developer.txt' if (not version.addon.authors.filter(pk=user.pk).exists() and acl.is_user_any_kind_of_reviewer(user)): template = 'activity/emails/from_reviewer.txt' return loader.get_template(template)
def wrapper(request, *args, **kw): if acl.is_user_any_kind_of_reviewer( request.user, allow_viewers=(request.method == 'GET')): return f(request, *args, **kw) raise PermissionDenied
def global_settings(request): """ Storing standard AMO-wide information used in global headers, such as account links and settings. """ account_links = [] tools_links = [] context = {} tools_title = gettext('Tools') is_reviewer = False # We're using `getattr` here because `request.user` can be missing, # e.g in case of a 500-server error. if getattr(request, 'user', AnonymousUser()).is_authenticated: is_reviewer = acl.is_user_any_kind_of_reviewer(request.user) account_links.append({ 'text': gettext('My Profile'), 'href': request.user.get_url_path() }) account_links.append({ 'text': gettext('Account Settings'), 'href': reverse('users.edit') }) account_links.append({ 'text': gettext('My Collections'), 'href': reverse('collections.list') }) account_links.append({ 'text': gettext('Log out'), 'href': reverse('devhub.logout') + '?to=' + quote(request.path), }) if request.user.is_developer: tools_links.append({ 'text': gettext('Manage My Submissions'), 'href': reverse('devhub.addons'), }) tools_links.append({ 'text': gettext('Submit a New Add-on'), 'href': reverse('devhub.submit.agreement'), }) tools_links.append({ 'text': gettext('Submit a New Theme'), 'href': reverse('devhub.submit.agreement'), }) tools_links.append({ 'text': gettext('Developer Hub'), 'href': reverse('devhub.index') }) tools_links.append({ 'text': gettext('Manage API Keys'), 'href': reverse('devhub.api_key') }) if is_reviewer: tools_links.append({ 'text': gettext('Reviewer Tools'), 'href': reverse('reviewers.dashboard'), }) if acl.action_allowed(request, amo.permissions.ANY_ADMIN): tools_links.append({ 'text': gettext('Admin Tools'), 'href': reverse('admin:index') }) context['user'] = request.user else: context['user'] = AnonymousUser() context.update({ 'account_links': account_links, 'settings': settings, 'amo': amo, 'tools_links': tools_links, 'tools_title': tools_title, 'is_reviewer': is_reviewer, }) return context
def global_settings(request): """ Storing standard AMO-wide information used in global headers, such as account links and settings. """ account_links = [] tools_links = [] context = {} tools_title = ugettext('Tools') is_reviewer = False if request.user.is_authenticated(): is_reviewer = acl.is_user_any_kind_of_reviewer(request.user) account_links.append({'text': ugettext('My Profile'), 'href': request.user.get_url_path()}) if request.user.is_artist: account_links.append({'text': ugettext('My Themes'), 'href': request.user.get_themes_url_path()}) account_links.append({'text': ugettext('Account Settings'), 'href': reverse('users.edit')}) account_links.append({ 'text': ugettext('My Collections'), 'href': reverse('collections.user', args=[request.user.username])}) if request.user.favorite_addons: account_links.append( {'text': ugettext('My Favorites'), 'href': reverse('collections.detail', args=[request.user.username, 'favorites'])}) account_links.append({ 'text': ugettext('Log out'), 'href': reverse('users.logout') + '?to=' + urlquote(request.path), }) if request.user.is_developer: tools_links.append({'text': ugettext('Manage My Submissions'), 'href': reverse('devhub.addons')}) links = [ {'text': ugettext('Submit a New Add-on'), 'href': reverse('devhub.submit.agreement')}, {'text': ugettext('Submit a New Theme'), 'href': reverse('devhub.themes.submit')}, {'text': ugettext('Developer Hub'), 'href': reverse('devhub.index')}, ] links.append({'text': ugettext('Manage API Keys'), 'href': reverse('devhub.api_key')}) tools_links += links if is_reviewer: tools_links.append({'text': ugettext('Reviewer Tools'), 'href': reverse('reviewers.dashboard')}) if (acl.action_allowed(request, amo.permissions.ADMIN) or acl.action_allowed(request, amo.permissions.ADMIN_TOOLS_VIEW)): tools_links.append({'text': ugettext('Admin Tools'), 'href': reverse('zadmin.index')}) context['user'] = request.user else: context['user'] = AnonymousUser() context.update({'account_links': account_links, 'settings': settings, 'amo': amo, 'tools_links': tools_links, 'tools_title': tools_title, 'ADMIN_MESSAGE': get_config('site_notice'), 'is_reviewer': is_reviewer}) return context