Skip to content

Commit c588350

Browse files
Merge pull request #380 from MySecondLanguage/admin-mutation
Admin mutation
2 parents d79268e + 8bc722f commit c588350

File tree

14 files changed

+167
-49
lines changed

14 files changed

+167
-49
lines changed

nxtbn/cart/admin_query.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from nxtbn.cart.models import Cart
55
from nxtbn.cart.admin_types import CartItemType, CartType
6-
from nxtbn.core.admin_permissions import gql_staff_required
6+
from nxtbn.core.admin_permissions import gql_store_admin_required
77

88

99
class AdminCartQuery(graphene.ObjectType):
@@ -13,18 +13,18 @@ class AdminCartQuery(graphene.ObjectType):
1313

1414
items_in_cart = graphene.List(CartItemType, cart_id=graphene.ID(required=True))
1515

16-
@gql_staff_required
16+
@gql_store_admin_required
1717
def resolve_carts(self, info, **kwargs):
1818
return Cart.objects.all()
1919

20-
@gql_staff_required
20+
@gql_store_admin_required
2121
def resolve_cart_by_user(self, info, user_id):
2222
try:
2323
return Cart.objects.get(user_id=user_id)
2424
except Cart.DoesNotExist:
2525
return None
2626

27-
@gql_staff_required
27+
@gql_store_admin_required
2828
def resolve_items_in_cart(self, info, cart_id):
2929
try:
3030
cart = Cart.objects.get(id=cart_id)

nxtbn/core/admin_mutation.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import graphene
33

44
from nxtbn.core import CurrencyTypes
5+
from nxtbn.core.admin_permissions import gql_required_perm
56
from nxtbn.core.admin_types import CurrencyExchangeType
67
from nxtbn.core.models import CurrencyExchange
78
from nxtbn.users import UserRole
@@ -20,6 +21,7 @@ class Arguments:
2021

2122
currency_exchange = graphene.Field(CurrencyExchangeType)
2223

24+
@gql_required_perm(CurrencyExchange, 'add_currencyexchange')
2325
@staticmethod
2426
def mutate(root, info, input):
2527
# Validate base_currency
@@ -47,6 +49,7 @@ class Arguments:
4749

4850
currency_exchange = graphene.Field(CurrencyExchangeType)
4951

52+
@gql_required_perm(CurrencyExchange, 'change_currencyexchange')
5053
@staticmethod
5154
def mutate(root, info, id, input):
5255
try:
@@ -64,6 +67,7 @@ class Arguments:
6467

6568
success = graphene.Boolean() # Indicate whether the operation was successful
6669

70+
@gql_required_perm(CurrencyExchange, 'delete_currencyexchange')
6771
@staticmethod
6872
def mutate(root, info, id):
6973
try:

nxtbn/core/admin_permissions.py

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ def has_required_perm(user, code: str, model_cls=None):
150150
return user.has_perm(perm_code)
151151

152152

153-
def gql_required_perm(code: str): # Used in graphql only
153+
def gql_required_perm(model, code: str): # model argument will be the model class
154154
def decorator(func):
155155
@functools.wraps(func)
156156
def wrapper(self, info, *args, **kwargs):
@@ -159,13 +159,22 @@ def wrapper(self, info, *args, **kwargs):
159159

160160
if user.is_anonymous:
161161
raise GraphQLError("Authentication required")
162-
163-
if operation == "query":
162+
163+
if not user.is_staff:
164+
raise GraphQLError("Permission denied")
165+
166+
if user.is_superuser:
164167
return func(self, info, *args, **kwargs)
165-
166168

169+
if user.is_store_admin:
170+
return func(self, info, *args, **kwargs)
167171

168-
if not user.has_perm(code): # Check if user has the required permission
172+
if operation == "query":
173+
return func(self, info, *args, **kwargs)
174+
175+
# Check if the user has permission for the model
176+
perm_code = f"{model._meta.app_label}.{code}" # Constructing the permission name
177+
if not user.has_perm(perm_code): # Check if the user has the required permission for the model
169178
raise GraphQLError("Permission denied") # Block unauthorized access
170179

171180
return func(self, info, *args, **kwargs) # Call the actual resolver
@@ -176,17 +185,49 @@ def wrapper(self, info, *args, **kwargs):
176185

177186

178187

179-
def gql_staff_required(func): # Used in graphql only
188+
def gql_store_admin_required(func): # Used in graphql only
180189
@functools.wraps(func)
181190
def wrapper(self, info, *args, **kwargs):
182191
user = info.context.user
183192

184193
if user.is_anonymous:
185194
raise GraphQLError("Authentication required")
195+
196+
if not user.is_staff:
197+
raise GraphQLError("Permission denied")
198+
199+
if user.is_superuser:
200+
return func(self, info, *args, **kwargs)
186201

187-
if not user.is_staff: # Check if the user is a staff member
188-
raise GraphQLError("Permission denied") # Block access if the user is not staff
202+
if user.is_store_admin:
203+
return func(self, info, *args, **kwargs)
189204

190205
return func(self, info, *args, **kwargs) # Call the actual resolver
191206

207+
return wrapper
208+
209+
210+
def gql_store_staff_required(func): # Used in graphql only
211+
@functools.wraps(func)
212+
def wrapper(self, info, *args, **kwargs):
213+
user = info.context.user
214+
215+
if user.is_anonymous:
216+
raise GraphQLError("Authentication required")
217+
218+
if not user.is_staff:
219+
raise GraphQLError("Permission denied")
220+
221+
if user.is_superuser:
222+
return func(self, info, *args, **kwargs)
223+
224+
if user.is_store_admin:
225+
return func(self, info, *args, **kwargs)
226+
227+
if user.is_store_staff:
228+
return func(self, info, *args, **kwargs)
229+
else:
230+
raise GraphQLError("Permission denied")
231+
232+
192233
return wrapper

nxtbn/core/admin_queries.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from graphql import GraphQLError
44

55
from nxtbn.core import CurrencyTypes
6-
from nxtbn.core.admin_permissions import gql_staff_required
6+
from nxtbn.core.admin_permissions import gql_store_admin_required
77
from nxtbn.core.admin_types import AdminCurrencyTypesEnum, CurrencyExchangeType
88
from nxtbn.core.models import CurrencyExchange
99
from graphene_django.filter import DjangoFilterConnectionField
@@ -14,7 +14,7 @@ class AdminCoreQuery(graphene.ObjectType):
1414
currency_exchange = graphene.Field(CurrencyExchangeType, id=graphene.ID(required=True))
1515
allowed_currency_list = graphene.List(AdminCurrencyTypesEnum)
1616

17-
@gql_staff_required
17+
@gql_store_admin_required
1818
def resolve_currency_exchanges(self, info, **kwargs):
1919
return CurrencyExchange.objects.all()
2020

@@ -24,7 +24,7 @@ def resolve_currency_exchange(self, info, id):
2424
except CurrencyExchange.DoesNotExist:
2525
return None
2626

27-
@gql_staff_required
27+
@gql_store_admin_required
2828
def resolve_allowed_currency_list(self, info):
2929
allowed_currency_list = settings.ALLOWED_CURRENCIES
3030

nxtbn/core/enum_perms.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,8 @@ class PermissionsEnum(models.TextChoices):
1515
CAN_BULK_PRODUCT_STATUS_UPDATE = "can_bulk_product_status_update"
1616
CAN_BULK_PRODUCT_DELETE = "can_bulk_product_delete"
1717

18+
CAN_RECEIVE_TRANSFERRED_STOCK = "can_receive_transferred_stock"
19+
CAN_MARK_STOCK_TRANSFER_AS_COMPLETED = "can_mark_stock_transfer_as_completed"
20+
1821
CAN_READ_CUSTOMER = "can_read_customer"
1922
CAN_UPDATE_CUSTOMER = "can_create_customer"

nxtbn/filemanager/api/dashboard/views.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from django_filters.rest_framework import DjangoFilterBackend
66

77

8+
from nxtbn.core.admin_permissions import CommonPermissions
89
from nxtbn.filemanager.models import Document, Image
910
from nxtbn.filemanager.api.dashboard.serializers import (
1011
DocumentSerializer,
@@ -21,6 +22,8 @@ class Meta:
2122
fields = ['id', 'name']
2223

2324
class ImageListView(generics.ListCreateAPIView):
25+
permission_classes = (CommonPermissions, )
26+
model = Image
2427
serializer_class = ImageSerializer
2528
queryset = Image.objects.all().order_by('-created_at')
2629
pagination_class = NxtbnPagination
@@ -29,19 +32,25 @@ class ImageListView(generics.ListCreateAPIView):
2932

3033

3134
class ImageDetailView(generics.RetrieveUpdateDestroyAPIView):
35+
permission_classes = (CommonPermissions, )
36+
model = Image
3237
queryset = Image.objects.all()
3338
serializer_class = ImageSerializer
3439
pagination_class = NxtbnPagination
3540
lookup_field = "id"
3641

3742

3843
class DocumentListView(generics.ListCreateAPIView):
44+
permission_classes = (CommonPermissions, )
45+
model = Document
3946
serializer_class = DocumentSerializer
4047
queryset = Document.objects.all()
4148
pagination_class = NxtbnPagination
4249

4350

4451
class DocumentDetailView(generics.RetrieveUpdateDestroyAPIView):
52+
permission_classes = (CommonPermissions, )
53+
model = Document
4554
queryset = Document.objects.all()
4655
serializer_class = DocumentSerializer
4756
pagination_class = NxtbnPagination

nxtbn/order/admin_queries.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import graphene
22
from graphene_django.filter import DjangoFilterConnectionField
33

4-
from nxtbn.core.admin_permissions import gql_staff_required
4+
from nxtbn.core.admin_permissions import gql_store_admin_required
55
from nxtbn.order.admin_types import OrderType
66
from nxtbn.order.models import Address, Order
77
from nxtbn.users import UserRole
@@ -13,11 +13,11 @@ class AdminOrderQuery(graphene.ObjectType):
1313

1414

1515

16-
@gql_staff_required
16+
@gql_store_admin_required
1717
def resolve_orders(self, info, **kwargs):
1818
return Order.objects.all()
1919

20-
@gql_staff_required
20+
@gql_store_admin_required
2121
def resolve_order(self, info, id):
2222
try:
2323
order = Order.objects.get(id=id)

nxtbn/product/admin_mutations.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import graphene
2+
from nxtbn.core.admin_permissions import gql_required_perm
23
from nxtbn.product.admin_types import CategoryTranslationType, CategoryType, CollectionTranslationType, ProductTagTranslationType, ProductTranslationType, ProductVariantTranslationType, SupplierTranslationType
34
from nxtbn.product.models import Category, CategoryTranslation, CollectionTranslation, ProductTagTranslation, ProductTranslation, ProductVariantTranslation, SupplierTranslation
45
from nxtbn.users import UserRole
@@ -18,6 +19,7 @@ class Arguments:
1819

1920
category = graphene.Field(CategoryType)
2021

22+
@gql_required_perm(Category, 'change_category')
2123
def mutate(self, info, id, input):
2224
category = Category.objects.get(id=id)
2325
category.name = input.name
@@ -45,6 +47,7 @@ class Arguments:
4547

4648
product_translation = graphene.Field(ProductTranslationType)
4749

50+
@gql_required_perm(ProductTranslation, 'change_producttranslation')
4851
def mutate(self, info, base_product_id, lang_code, name, summary, description, meta_title, meta_description):
4952
try:
5053
product_translation = ProductTranslation.objects.get(product_id=base_product_id, language_code=lang_code)
@@ -72,6 +75,7 @@ class Arguments:
7275

7376
category_translation = graphene.Field(CategoryTranslationType)
7477

78+
@gql_required_perm(CategoryTranslation, 'change_categorytranslation')
7579
def mutate(self, info, base_category_id, lang_code, name, description, meta_title, meta_description):
7680
try:
7781
category_translation = CategoryTranslation.objects.get(category_id=base_category_id, language_code=lang_code)
@@ -98,6 +102,7 @@ class Arguments:
98102

99103
supplier_translation = graphene.Field(SupplierTranslationType)
100104

105+
@gql_required_perm(SupplierTranslation, 'change_suppliertranslation')
101106
def mutate(self, info, base_supplier_id, lang_code, name, description, meta_title, meta_description):
102107
try:
103108
supplier_translation = SupplierTranslation.objects.get(supplier_id=base_supplier_id, language_code=lang_code)
@@ -121,6 +126,7 @@ class Arguments:
121126

122127
product_variant_translation = graphene.Field(ProductVariantTranslationType)
123128

129+
@gql_required_perm(ProductVariantTranslation, 'change_productvarianttranslation')
124130
def mutate(self, info, base_product_variant_id, lang_code, name, description, meta_title, meta_description):
125131
try:
126132
product_variant_translation = ProductVariantTranslation.objects.get(product_variant_id=base_product_variant_id, language_code=lang_code)
@@ -140,6 +146,7 @@ class Arguments:
140146

141147
product_tag_translation = graphene.Field(ProductTagTranslationType)
142148

149+
@gql_required_perm(ProductTagTranslation, 'change_producttagtranslation')
143150
def mutate(self, info, base_product_tag_id, lang_code, name, description, meta_title, meta_description):
144151
try:
145152
product_tag_translation = ProductTagTranslation.objects.get(product_tag_id=base_product_tag_id, language_code=lang_code)
@@ -162,6 +169,7 @@ class Arguments:
162169

163170
collection_translation = graphene.Field(CollectionTranslationType)
164171

172+
@gql_required_perm(CollectionTranslation, 'change_collectiontranslation')
165173
def mutate(self, info, base_collection_id, lang_code, name, description, meta_title, meta_description):
166174
try:
167175
collection_translation = CollectionTranslation.objects.get(collection_id=base_collection_id, language_code=lang_code)

0 commit comments

Comments
 (0)