Skip to content

Commit 974660b

Browse files
committed
feat(authorization): make view_user product/product_type panels read-only under legacy
Restore the "Product Types this User can access" / "Products this User can access" panels that I'd just stripped, but rebuild them as legacy-correct, read-only listings: * dojo/user/views.py:view_user computes accessible_product_types and accessible_products from authorized_users (with the cascade Product_Type → Product). The Pro-driven product_type_members / product_members context vars are kept so the Pro template override can keep rendering the RBAC version. * view_user.html (both UI trees) renders the new context vars in the user_product_types_panel / user_products_panel blocks. Drops the Add hamburger, the per-row Edit/Delete ellipsis dropdown, and the Role column — all of those write to or describe Product_Member rows which are inert under legacy and the Product_Member table is no longer editable from OS. * Pro's pro/templates/dojo/view_user.html already overrides both blocks with the RBAC-driven content, so Pro renders unchanged.
1 parent 59f7b16 commit 974660b

3 files changed

Lines changed: 139 additions & 5 deletions

File tree

dojo/templates/dojo/view_user.html

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,69 @@ <h4 class="pull-left">{% trans "Contact Information" %}</h4>
101101
</table>
102102
</div>
103103
</div>
104-
{% block user_product_types_panel %}{% endblock %}
105-
{% block user_products_panel %}{% endblock %}
104+
{% block user_product_types_panel %}
105+
<div class="panel panel-default">
106+
<div class="panel-heading">
107+
<div class="clearfix">
108+
<h4 class="pull-left">{{ labels.ORG_USERS_LABEL }}</h4>
109+
</div>
110+
</div>
111+
{% if accessible_product_types %}
112+
<div class="table-responsive">
113+
<table class="tablesorter-bootstrap table table-condensed table-striped">
114+
<thead>
115+
<tr>
116+
<th>{{ labels.ORG_LABEL }}</th>
117+
</tr>
118+
</thead>
119+
<tbody>
120+
{% for pt in accessible_product_types %}
121+
<tr>
122+
<td name="member_product_type"><a href="{% url 'view_product_type' pt.id %}">{{ pt.name }}</a></td>
123+
</tr>
124+
{% endfor %}
125+
</tbody>
126+
</table>
127+
</div>
128+
{% else %}
129+
<div class="panel-body">
130+
<small class="text-muted"><em>{{ labels.ORG_USERS_NO_ACCESS_MESSAGE }}</em></small>
131+
</div>
132+
{% endif %}
133+
</div>
134+
{% endblock user_product_types_panel %}
135+
{% block user_products_panel %}
136+
<div class="panel panel-default">
137+
<div class="panel-heading">
138+
<div class="clearfix">
139+
<h4 class="pull-left">{{ labels.ASSET_USERS_ACCESS_LABEL }}</h4>
140+
</div>
141+
</div>
142+
{% if accessible_products %}
143+
<div class="table-responsive">
144+
<table class="tablesorter-bootstrap table table-condensed table-striped">
145+
<thead>
146+
<tr>
147+
<th>{{ labels.ASSET_LABEL }}</th>
148+
</tr>
149+
</thead>
150+
<tbody>
151+
{% for p in accessible_products %}
152+
<tr>
153+
<td name="member_product"><a href="{% url 'view_product' p.id %}">{{ p.name }}</a></td>
154+
</tr>
155+
{% endfor %}
156+
</tbody>
157+
</table>
158+
</div>
159+
{% else %}
160+
<div class="panel-body">
161+
<small class="text-muted"><em>{{ labels.ASSET_USERS_NO_ACCESS_MESSAGE }}</em></small>
162+
</div>
163+
{% endif %}
164+
</div>
165+
{% endblock user_products_panel %}
166+
106167
{% block user_groups_panel %}{% endblock %}
107168
</div>
108169
<div class="col-md-4">

dojo/templates_classic/dojo/view_user.html

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,69 @@ <h4 class="pull-left">{% trans "Contact Information" %}</h4>
101101
</table>
102102
</div>
103103
</div>
104-
{% block user_product_types_panel %}{% endblock %}
105-
{% block user_products_panel %}{% endblock %}
104+
{% block user_product_types_panel %}
105+
<div class="panel panel-default">
106+
<div class="panel-heading">
107+
<div class="clearfix">
108+
<h4 class="pull-left">{{ labels.ORG_USERS_LABEL }}</h4>
109+
</div>
110+
</div>
111+
{% if accessible_product_types %}
112+
<div class="table-responsive">
113+
<table class="tablesorter-bootstrap table table-condensed table-striped">
114+
<thead>
115+
<tr>
116+
<th>{{ labels.ORG_LABEL }}</th>
117+
</tr>
118+
</thead>
119+
<tbody>
120+
{% for pt in accessible_product_types %}
121+
<tr>
122+
<td name="member_product_type"><a href="{% url 'view_product_type' pt.id %}">{{ pt.name }}</a></td>
123+
</tr>
124+
{% endfor %}
125+
</tbody>
126+
</table>
127+
</div>
128+
{% else %}
129+
<div class="panel-body">
130+
<small class="text-muted"><em>{{ labels.ORG_USERS_NO_ACCESS_MESSAGE }}</em></small>
131+
</div>
132+
{% endif %}
133+
</div>
134+
{% endblock user_product_types_panel %}
135+
{% block user_products_panel %}
136+
<div class="panel panel-default">
137+
<div class="panel-heading">
138+
<div class="clearfix">
139+
<h4 class="pull-left">{{ labels.ASSET_USERS_ACCESS_LABEL }}</h4>
140+
</div>
141+
</div>
142+
{% if accessible_products %}
143+
<div class="table-responsive">
144+
<table class="tablesorter-bootstrap table table-condensed table-striped">
145+
<thead>
146+
<tr>
147+
<th>{{ labels.ASSET_LABEL }}</th>
148+
</tr>
149+
</thead>
150+
<tbody>
151+
{% for p in accessible_products %}
152+
<tr>
153+
<td name="member_product"><a href="{% url 'view_product' p.id %}">{{ p.name }}</a></td>
154+
</tr>
155+
{% endfor %}
156+
</tbody>
157+
</table>
158+
</div>
159+
{% else %}
160+
<div class="panel-body">
161+
<small class="text-muted"><em>{{ labels.ASSET_USERS_NO_ACCESS_MESSAGE }}</em></small>
162+
</div>
163+
{% endif %}
164+
</div>
165+
{% endblock user_products_panel %}
166+
106167
{% block user_groups_panel %}{% endblock %}
107168
</div>
108169
<div class="col-md-4">

dojo/user/views.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
)
5050
from dojo.group.queries import get_authorized_group_members_for_user
5151
from dojo.labels import get_labels
52-
from dojo.models import Alerts, Dojo_User, UserContactInfo
52+
from dojo.models import Alerts, Dojo_User, Product, Product_Type, UserContactInfo
5353
from dojo.product.queries import get_authorized_product_members_for_user
5454
from dojo.product_type.queries import get_authorized_product_type_members_for_user
5555
from dojo.user.authentication import reset_token_for_user
@@ -408,6 +408,16 @@ def add_user(request):
408408

409409
def view_user(request, uid):
410410
user = get_object_or_404(Dojo_User, id=uid)
411+
# Legacy access lists: Product / Product_Type the user is on
412+
# via authorized_users (with cascade Product_Type → Product).
413+
accessible_product_types = Product_Type.objects.filter(
414+
authorized_users=user,
415+
).order_by("name")
416+
accessible_products = Product.objects.filter(
417+
Q(authorized_users=user) | Q(prod_type__authorized_users=user),
418+
).distinct().order_by("name")
419+
# kept for Pro template override `{% block user_product_types_panel %}` /
420+
# `{% block user_products_panel %}` at pro/templates/dojo/view_user.html
411421
product_members = get_authorized_product_members_for_user(user, "view")
412422
product_type_members = get_authorized_product_type_members_for_user(user, "view")
413423
group_members = get_authorized_group_members_for_user(user)
@@ -416,6 +426,8 @@ def view_user(request, uid):
416426
add_breadcrumb(title=_("View User"), top_level=False, request=request)
417427
return render(request, "dojo/view_user.html", {
418428
"user": user,
429+
"accessible_product_types": accessible_product_types,
430+
"accessible_products": accessible_products,
419431
"product_members": product_members,
420432
"product_type_members": product_type_members,
421433
"group_members": group_members,

0 commit comments

Comments
 (0)