Display question details to specific groups

This commit is contained in:
Tasos Katsoulas 2022-08-18 14:13:14 +03:00
Родитель f69b6e6224
Коммит d7c40183a0
5 изменённых файлов: 139 добавлений и 114 удалений

Просмотреть файл

@ -421,116 +421,118 @@
{% endif %}
</div>
</li>
<li class="mzp-c-details">
<h3 class="sidebar-subheading sidebar-nav--heading-item is-accordion-heading">{{ _('Question Details') }}</h3>
<div id="question-details" class="question-details">
<form method="post" action="{{ url('questions.edit_details', question.id) }}">
<div class="folder">
{% if product or (user and user.has_perm('questions.change_question')) %}
<div class="sidebox tight condensed">
<span class="title">{{ _('Product') }}:</span>
{% if product %}
<span class="detail">{{ pgettext('DB: products.Product.title', product.title) }}</span>
{% endif %}
{% if user and user.has_perm('questions.change_question') %}
<select id="details-product" name="product">
{% for p in all_products %}
<option {% if product and p.id == product.id %}selected="selected"{% endif %} value="{{ p.id }}" data-url="{{ url('products.product', p.slug) }}">{{ p.title }}</option>
{% if is_trusted_user(request.user) %}
<li class="mzp-c-details">
<h3 class="sidebar-subheading sidebar-nav--heading-item is-accordion-heading">{{ _('Question Details') }}</h3>
<div id="question-details" class="question-details">
<form method="post" action="{{ url('questions.edit_details', question.id) }}">
<div class="folder">
{% if product or (user and user.has_perm('questions.change_question')) %}
<div class="sidebox tight condensed">
<span class="title">{{ _('Product') }}:</span>
{% if product %}
<span class="detail">{{ pgettext('DB: products.Product.title', product.title) }}</span>
{% endif %}
{% if user and user.has_perm('questions.change_question') %}
<select id="details-product" name="product">
{% for p in all_products %}
<option {% if product and p.id == product.id %}selected="selected"{% endif %} value="{{ p.id }}" data-url="{{ url('products.product', p.slug) }}">{{ p.title }}</option>
{% endfor %}
</select>
{% endif %}
</div>
{% endif %}
{% if topic or (user and user.has_perm('questions.change_question')) %}
<div class="sidebox tight condensed">
<span class="title">{{ _('Topic') }}:</span>
{% if topic %}
<span class="detail">{{ pgettext('DB: products.Topic.title', topic.title) }}</span>
{% endif %}
{% if user and user.has_perm('questions.change_question') %}
<select id="details-topic" name="topic">
{% for t in all_topics %}
<option {% if topic and t.id == topic.id %}selected="selected"{% endif %} value="{{ t.id }}">{{ t.title }}</option>
{% endfor %}
</select>
{% endif %}
</div>
{% endif %}
{% if user and user.has_perm('questions.change_question') %}
<div class="sidebox tight condensed" id="question-locale">
<span class="title">{{ _('Locale') }}:</span>
<span class="detail">{{ settings.LANGUAGES_DICT[question.locale.lower()] }}</span>
<select name="locale">
{% for lang in AAQ_LANGUAGES %}
<option {% if question.locale == lang %}selected="selected"{% endif %} value="{{ lang }}">{{ settings.LANGUAGES_DICT[lang.lower()] }}</option>
{% endfor %}
</select>
{% endif %}
</div>
{% endif %}
</div>
{% if topic or (user and user.has_perm('questions.change_question')) %}
<div class="sidebox tight condensed">
<span class="title">{{ _('Topic') }}:</span>
{% if topic %}
<span class="detail">{{ pgettext('DB: products.Topic.title', topic.title) }}</span>
{% endif %}
{% if user and user.has_perm('questions.change_question') %}
<select id="details-topic" name="topic">
{% for t in all_topics %}
<option {% if topic and t.id == topic.id %}selected="selected"{% endif %} value="{{ t.id }}">{{ t.title }}</option>
{% endfor %}
</select>
{% endif %}
</div>
{% endif %}
<div class="sumo-button-wrap">
<button id="details-submit" type="submit" class="sumo-button button-sm primary-button">{{ _('Save changes') }}</button>
</div>
{% endif %}
{% if user and user.has_perm('questions.change_question') %}
<div class="sidebox tight condensed" id="question-locale">
<span class="title">{{ _('Locale') }}:</span>
<span class="detail">{{ settings.LANGUAGES_DICT[question.locale.lower()] }}</span>
<select name="locale">
{% for lang in AAQ_LANGUAGES %}
<option {% if question.locale == lang %}selected="selected"{% endif %} value="{{ lang }}">{{ settings.LANGUAGES_DICT[lang.lower()] }}</option>
{% endfor %}
</select>
</div>
<div class="sidebox tight {% if user and user.has_perm('questions.change_question') %}condensed{% endif %}" id="system-details">
<span class="title">{{ _('System Details') }}:</span>
{% block system_info %}
<ul class="system">
{% if question.metadata.os %}
{% set os = question.metadata.os %}
{% set os_lower = os.lower() %}
<li class="{% if os_lower.find('mac') >= 0 %}mac{% elif os_lower.find('linux') >= 0 %}linux{% elif os_lower.find('win') >= 0 %}windows{% endif %}">{{ os }}</li>
{% endif %}
{% if question.metadata.ff_version %}
<li class="ff">Firefox {{ question.metadata.ff_version }}</li>
{% endif %}
{% if question.metadata.device %}
<li>{{ _('Device:') }} {{ question.metadata.device }}</li>
{% endif %}
</ul>
{% endblock %}
<a id="show-more-details" href="javascript:;" data-sumo-modal="more-system-details">{{ _('More system details') }}</a>
<div class="sumo-button-wrap">
<button id="details-submit" type="submit" class="sumo-button button-sm primary-button">{{ _('Save changes') }}</button>
</div>
{% endif %}
<div class="sidebox tight {% if user and user.has_perm('questions.change_question') %}condensed{% endif %}" id="system-details">
<span class="title">{{ _('System Details') }}:</span>
{% block system_info %}
<ul class="system">
{% if question.metadata.os %}
{% set os = question.metadata.os %}
{% set os_lower = os.lower() %}
<li class="{% if os_lower.find('mac') >= 0 %}mac{% elif os_lower.find('linux') >= 0 %}linux{% elif os_lower.find('win') >= 0 %}windows{% endif %}">{{ os }}</li>
<section id="more-system-details" class="mzp-u-modal-content text-body-md" title="{{ _('Additional System Details') }}" data-target="#show-more-details">
<h2 class="sumo-page-subheading">{{ _('Additional System Details') }}</h2>
{% if question.metadata.sites_affected %}
<h3 class="sumo-card-heading">{{ _('Sites Affected') }}</h3>
<p>{{ question.metadata.sites_affected }}</p>
{% endif %}
{% if question.metadata.ff_version %}
<li class="ff">Firefox {{ question.metadata.ff_version }}</li>
{% if question.metadata.crash_id %}
<h3 class="sumo-card-heading">{{ _('Crash ID') }}</h3>
<p>{{ question.metadata.crash_id }}</p>
{% endif %}
{% if question.metadata.device %}
<li>{{ _('Device:') }} {{ question.metadata.device }}</li>
{% if question.metadata.frequency %}
<h3 class="sumo-card-heading">{{ _('This happened') }}</h3>
<p>{{ frequencies[question.metadata.frequency] }}</p>
{% endif %}
</ul>
{% endblock %}
<a id="show-more-details" href="javascript:;" data-sumo-modal="more-system-details">{{ _('More system details') }}</a>
{% if question.metadata.started %}
<h3 class="sumo-card-heading">{{ _('This started when...') }}</h3>
<p>{{ question.metadata.started }}</p>
{% endif %}
{% if question.metadata.plugins %}
<h3 class="sumo-card-heading">{{ _('Installed Plug-ins') }}</h3>
<p><span class="plugins">
{{ question.metadata.plugins|wiki_to_html }}
</span></p>
{% endif %}
{{ troubleshooting_info(question) }}
</section>
</div>
<section id="more-system-details" class="mzp-u-modal-content text-body-md" title="{{ _('Additional System Details') }}" data-target="#show-more-details">
<h2 class="sumo-page-subheading">{{ _('Additional System Details') }}</h2>
{% if question.metadata.sites_affected %}
<h3 class="sumo-card-heading">{{ _('Sites Affected') }}</h3>
<p>{{ question.metadata.sites_affected }}</p>
{% endif %}
{% if question.metadata.crash_id %}
<h3 class="sumo-card-heading">{{ _('Crash ID') }}</h3>
<p>{{ question.metadata.crash_id }}</p>
{% endif %}
{% if question.metadata.frequency %}
<h3 class="sumo-card-heading">{{ _('This happened') }}</h3>
<p>{{ frequencies[question.metadata.frequency] }}</p>
{% endif %}
{% if question.metadata.started %}
<h3 class="sumo-card-heading">{{ _('This started when...') }}</h3>
<p>{{ question.metadata.started }}</p>
{% endif %}
{% if question.metadata.plugins %}
<h3 class="sumo-card-heading">{{ _('Installed Plug-ins') }}</h3>
<p><span class="plugins">
{{ question.metadata.plugins|wiki_to_html }}
</span></p>
{% endif %}
{{ troubleshooting_info(question) }}
</section>
{% if user and user.has_perm('questions.change_question') %}
<div class="sidebox tight">
<a href="#" id="details-edit">{{ _('Edit details') }}</a>
</div>
{% endif %}
</div>
{% if user and user.has_perm('questions.change_question') %}
<div class="sidebox tight">
<a href="#" id="details-edit">{{ _('Edit details') }}</a>
</div>
{% endif %}
</div>
{% csrf_token %}
</form>
</div>
</li>
{% csrf_token %}
</form>
</div>
</li>
{% endif %}
{% if related_documents or related_questions %}
<li class="sidebar-subheading sidebar-nav--heading-item">{{ _('See also') }}</li>

Просмотреть файл

@ -1214,3 +1214,14 @@ CSP_CONNECT_SRC = (
"https://*.google-analytics.com",
"https://location.services.mozilla.com",
)
# Trusted Contributor Groups
TRUSTED_GROUPS = [
"Forum Moderators",
"Administrators",
"SUMO Locale Leaders",
"Knowledge Base Reviewers",
"Reviewers",
# Temporary workaround to exempt individual users if needed
"Escape Spam Filtering",
]

Просмотреть файл

@ -1,16 +1,6 @@
from django import forms
from kitsune.sumo.utils import check_for_spam_content
TRUSTED_GROUPS = [
"Forum Moderators",
"Administrators",
"SUMO Locale Leaders",
"Knowledge Base Reviewers",
"Reviewers",
# Temporary workaround to exempt individual users if needed
"Escape Spam Filtering",
]
from kitsune.sumo.utils import check_for_spam_content, is_trusted_user
class KitsuneBaseForumForm(forms.Form):
@ -43,7 +33,7 @@ class KitsuneBaseForumForm(forms.Form):
# Exclude moderators and trusted contributors
if not (
self.user.groups.filter(name__in=TRUSTED_GROUPS).exists()
is_trusted_user(self.user)
or self.user.has_perm("flagit.can_moderate")
or self.user.has_perm("sumo.bypass_ratelimit")
) and check_for_spam_content(cdata):

Просмотреть файл

@ -17,7 +17,7 @@ from django.utils.encoding import smart_bytes, smart_text
from django.utils.http import urlencode
from django.utils.timezone import get_default_timezone
from django.utils.translation import ugettext as _
from django.utils.translation import gettext_lazy as _lazy
from django.utils.translation import ugettext_lazy as _lazy
from django.utils.translation import ungettext
from django_jinja import library
from jinja2.utils import Markup
@ -26,6 +26,7 @@ from pytz import timezone
from kitsune.products.models import Product
from kitsune.sumo import parser
from kitsune.sumo.urlresolvers import reverse
from kitsune.sumo.utils import is_trusted_user as is_trusted_user_func
from kitsune.sumo.utils import webpack_static as webpack_static_func
from kitsune.users.models import Profile
from kitsune.wiki.showfor import showfor_data as _showfor_data
@ -549,3 +550,8 @@ def show_header_fx_download(context):
return product.slug != "firefox"
else:
return True
@library.global_function
def is_trusted_user(user):
return is_trusted_user_func(user)

Просмотреть файл

@ -13,7 +13,6 @@ from django.db.models.signals import pre_delete
from django.templatetags.static import static
from django.utils import translation
from django.utils.encoding import iri_to_uri
from django.utils.http import url_has_allowed_host_and_scheme, urlencode
from ratelimit.core import is_ratelimited as is_ratelimited_core
from timeout_decorator import timeout
@ -387,3 +386,20 @@ def webpack_static(source_path):
return ""
url = static(asset)
return url
def is_trusted_user(user: object) -> bool:
"""Given a user ID, checks for group membership.
If a user belongs to one of the trusted groups as defined in the project
settings, then is considered a trusted user.
"""
if not user or not user.is_authenticated:
return False
return any(
[
user.groups.filter(name__in=settings.TRUSTED_GROUPS).exists(),
user.is_superuser,
user.is_staff,
]
)