FIX(winofy): add gooyal auth
add gooyal auth
This commit is contained in:
parent
52adc732fa
commit
d2cc4c2ec6
6 changed files with 108 additions and 15 deletions
40
.env.example
40
.env.example
|
|
@ -1,12 +1,11 @@
|
|||
SECRET_KEY=change-me
|
||||
DEBUG=True
|
||||
ALLOWED_HOSTS=localhost,127.0.0.1
|
||||
ALLOWED_HOSTS=winofy-staging.winsoo.ir,localhost,127.0.0.1
|
||||
|
||||
DB_NAME=winofy_dev
|
||||
DB_USER=
|
||||
DB_PASSWORD=
|
||||
DB_HOST=localhost
|
||||
DB_PORT=5432
|
||||
|
||||
REDIS_URL=redis://localhost:6379/1
|
||||
|
||||
|
|
@ -26,3 +25,40 @@ OAUTH2_PROVIDER_SCOPES=
|
|||
# macOS only — not needed on Linux where GDAL is on the system path
|
||||
# GDAL_LIBRARY_PATH=/opt/homebrew/lib/libgdal.dylib
|
||||
# GEOS_LIBRARY_PATH=/opt/homebrew/lib/libgeos_c.dylib
|
||||
|
||||
- API_BASE_PATH=api/
|
||||
- SECRET_KEY=change-me
|
||||
- ALLOWED_HOSTS=*
|
||||
- CSRF_TRUSTED_ORIGINS=http://*,https://*,http://*.winsoo.ir,https://*.winsoo.ir
|
||||
- TZ=Asia/Tehran
|
||||
- DB_NAME=reservation_db
|
||||
- DB_USER=root
|
||||
- DB_HOST=reservation_db
|
||||
- DB_PASSWORD=123456
|
||||
- DEBUG=true
|
||||
- BASE_OAUTH2_PROVIDER_PUBLIC_URL=https://accounts-staging.gooyal.ir/oauth2
|
||||
- BASE_OAUTH2_PROVIDER_PRIVATE_URL=https://accounts-staging.gooyal.ir/oauth2
|
||||
- CLIENT_ID=ULKUBOKeBGeP0hkTlzbfHhHXe4qfPZcg9H44qqh1
|
||||
- CLIENT_SECRET=Cq8ZVkkQdP8IHOKxum4lkBVZOXE9OLmqWY1oseePOQh7KmCjYryWbgN5aeqwtXr6EzK8ttdbFm5Yt25ApZkb6ceze3TOPlObQ125UARin9A7DbjuDOHPar2tEafPWHlL
|
||||
- SCOPES=wallet.wallet:get_balance wallet.application.deposit:verify wallet.application.deposit:submit wallet.application.withdraw:submit wallet.application.withdraw:verify walle>
|
||||
- OAUTH2_PROVIDER_BASE_PUBLIC_URL=https://accounts-staging.gooyal.ir/oauth2
|
||||
- OAUTH2_PROVIDER_BASE_PRIVATE_URL=https://accounts-staging.gooyal.ir/oauth2
|
||||
- OAUTH2_PROVIDER_CLIENT_ID=ULKUBOKeBGeP0hkTlzbfHhHXe4qfPZcg9H44qqh1
|
||||
- OAUTH2_PROVIDER_CLIENT_SECRET=Cq8ZVkkQdP8IHOKxum4lkBVZOXE9OLmqWY1oseePOQh7KmCjYryWbgN5aeqwtXr6EzK8ttdbFm5Yt25ApZkb6ceze3TOPlObQ125UARin9A7DbjuDOHPar2tEafPWHlL
|
||||
- OAUTH2_PROVIDER_SCOPES=wallet.wallet:get_balance wallet.application.deposit:verify wallet.application.deposit:submit wallet.application.withdraw:submit wallet.application.withd>
|
||||
- BASE_REDIS_URL=redis://redis:6379/3
|
||||
- REDIS_BASE_URL=redis://redis:6379/3
|
||||
- MINIO_ENDPOINT=drive.gooyal.ir
|
||||
- MINIO_ACCESS_KEY=Irg3u493z63iJG3wJxah
|
||||
- MINIO_SECRET_KEY=VctFgYVsvBSYd8gHanblS0QnRjot5tUFvtQLl3TX
|
||||
- MINIO_USE_HTTPS=True
|
||||
- MINIO_BUCKET_NAME=winsoo-reservation-media-files-bucket
|
||||
- NOTIFICATIONS_EVENT_QUEUE=5527eced-a7c9-49d6-a59b-0bc40a81a1d6
|
||||
- NOTIFICATIONS_OPERATOR_USER_UUID=7123eece-efda-4821-83a5-27dfa7bfd663
|
||||
- NOTIFICATIONS_BASE_PUBLIC_URL=https://notifications-staging.gooyal.ir
|
||||
- WALLET_BASE_PUBLIC_URL=https://wallet-staging.gooyal.ir
|
||||
- WALLET_RIAL=af7d967f-30c0-409b-9066-2549f2da5e5e
|
||||
- WALLET_RIAL_WALLET=af7d967f-30c0-409b-9066-2549f2da5e5e
|
||||
- WALLET_REWARD=e7c9d4d1-4d1f-43b2-96f7-4d4a168f480d
|
||||
- WALLET_REWARD_WALLET=e7c9d4d1-4d1f-43b2-96f7-4d4a168f480d
|
||||
- LOKI_BASE_PUBLIC_URL=https://loki.winsoo.ir:443
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ from rest_framework.decorators import action
|
|||
from rest_framework.permissions import AllowAny, IsAuthenticated
|
||||
from rest_framework.response import Response
|
||||
|
||||
from apps.gooyal_oauth2.rest_framework import IsAuthenticatedOrTokenMatchesOASRequirements
|
||||
|
||||
from apps.core.permissions import IsStoreOwner
|
||||
from apps.stores.models import Store
|
||||
|
||||
|
|
@ -60,8 +62,13 @@ class SellerProductViewSet(viewsets.ModelViewSet):
|
|||
"""Seller's own product management (S06 list, S07 add, S08 inventory)."""
|
||||
|
||||
schema_tags = ['Seller · Products']
|
||||
permission_classes = [IsAuthenticated, IsStoreOwner]
|
||||
serializer_class = SellerProductSerializer
|
||||
# permission_classes = [IsAuthenticated, IsStoreOwner]
|
||||
# TODO: IsStoreOwner?
|
||||
permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
|
||||
required_alternate_scopes = {
|
||||
"POST": [[]],
|
||||
}
|
||||
|
||||
def get_queryset(self):
|
||||
if getattr(self, 'swagger_fake_view', False):
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
from rest_framework import mixins, viewsets
|
||||
from rest_framework.permissions import AllowAny, IsAuthenticated
|
||||
|
||||
from apps.gooyal_oauth2.rest_framework import IsAuthenticatedOrTokenMatchesOASRequirements
|
||||
|
||||
from .models import Address, City, Neighborhood
|
||||
from .serializers import AddressSerializer, CitySerializer, NeighborhoodSerializer
|
||||
|
||||
|
|
@ -28,8 +30,11 @@ class NeighborhoodViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, view
|
|||
|
||||
class AddressViewSet(viewsets.ModelViewSet):
|
||||
schema_tags = ['Addresses']
|
||||
permission_classes = [IsAuthenticated]
|
||||
serializer_class = AddressSerializer
|
||||
permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
|
||||
required_alternate_scopes = {
|
||||
"POST": [[]],
|
||||
}
|
||||
|
||||
def get_queryset(self):
|
||||
if getattr(self, 'swagger_fake_view', False):
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ from rest_framework.permissions import IsAuthenticated
|
|||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from apps.gooyal_oauth2.rest_framework import IsAuthenticatedOrTokenMatchesOASRequirements
|
||||
|
||||
from apps.core.permissions import IsStoreOwner
|
||||
|
||||
from . import services
|
||||
|
|
@ -27,8 +29,11 @@ class CartView(APIView):
|
|||
"""The authenticated user's cart, grouped by store (C07)."""
|
||||
|
||||
schema_tags = ['Cart']
|
||||
permission_classes = [IsAuthenticated]
|
||||
serializer_class = CartSerializer
|
||||
permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
|
||||
required_alternate_scopes = {
|
||||
"POST": [[]],
|
||||
}
|
||||
|
||||
def get(self, request):
|
||||
cart, _ = Cart.objects.get_or_create(user=request.user)
|
||||
|
|
@ -45,8 +50,11 @@ class CartItemView(APIView):
|
|||
"""Add/update/remove a single product line in the authenticated user's cart."""
|
||||
|
||||
schema_tags = ['Cart']
|
||||
permission_classes = [IsAuthenticated]
|
||||
serializer_class = CartItemWriteSerializer
|
||||
permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
|
||||
required_alternate_scopes = {
|
||||
"POST": [[]],
|
||||
}
|
||||
|
||||
@extend_schema(request=CartItemWriteSerializer, responses=CartItemSerializer)
|
||||
def post(self, request):
|
||||
|
|
@ -86,8 +94,11 @@ class CheckoutView(APIView):
|
|||
"""Splits the authenticated customer's multi-store cart into per-store orders (C08)."""
|
||||
|
||||
schema_tags = ['Checkout']
|
||||
permission_classes = [IsAuthenticated]
|
||||
serializer_class = CheckoutSerializer
|
||||
permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
|
||||
required_alternate_scopes = {
|
||||
"POST": [[]],
|
||||
}
|
||||
|
||||
@extend_schema(request=CheckoutSerializer, responses=OrderGroupSerializer)
|
||||
def post(self, request):
|
||||
|
|
@ -102,8 +113,11 @@ class OrderGroupViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, viewse
|
|||
"""Customer order history — each group may contain orders from several stores."""
|
||||
|
||||
schema_tags = ['Orders']
|
||||
permission_classes = [IsAuthenticated]
|
||||
serializer_class = OrderGroupSerializer
|
||||
permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
|
||||
required_alternate_scopes = {
|
||||
"POST": [[]],
|
||||
}
|
||||
|
||||
def get_queryset(self):
|
||||
if getattr(self, 'swagger_fake_view', False):
|
||||
|
|
@ -115,8 +129,11 @@ class OrderViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
|
|||
"""Customer-facing single-order tracking (C09) + cancel."""
|
||||
|
||||
schema_tags = ['Orders']
|
||||
permission_classes = [IsAuthenticated]
|
||||
serializer_class = OrderSerializer
|
||||
permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
|
||||
required_alternate_scopes = {
|
||||
"POST": [[]],
|
||||
}
|
||||
|
||||
def get_queryset(self):
|
||||
if getattr(self, 'swagger_fake_view', False):
|
||||
|
|
@ -136,8 +153,13 @@ class SellerOrderViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, views
|
|||
"""Seller order management (S09 list w/ status tabs, S10 detail + stepper actions)."""
|
||||
|
||||
schema_tags = ['Seller · Orders']
|
||||
permission_classes = [IsAuthenticated, IsStoreOwner]
|
||||
serializer_class = OrderSerializer
|
||||
# permission_classes = [IsAuthenticated, IsStoreOwner]
|
||||
# TODO: IsStoreOwner
|
||||
permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
|
||||
required_alternate_scopes = {
|
||||
"POST": [[]],
|
||||
}
|
||||
|
||||
def get_queryset(self):
|
||||
if getattr(self, 'swagger_fake_view', False):
|
||||
|
|
@ -184,8 +206,11 @@ class NotificationViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, view
|
|||
"""Shared notification feed (S16 for sellers; same model serves the customer app)."""
|
||||
|
||||
schema_tags = ['Notifications']
|
||||
permission_classes = [IsAuthenticated]
|
||||
serializer_class = NotificationSerializer
|
||||
permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
|
||||
required_alternate_scopes = {
|
||||
"POST": [[]],
|
||||
}
|
||||
|
||||
def get_queryset(self):
|
||||
if getattr(self, 'swagger_fake_view', False):
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from rest_framework.decorators import action
|
|||
from rest_framework.permissions import AllowAny, IsAuthenticated
|
||||
from rest_framework.response import Response
|
||||
|
||||
from apps.gooyal_oauth2.rest_framework import IsAuthenticatedOrTokenMatchesOASRequirements
|
||||
from apps.core.permissions import IsStoreOwner
|
||||
|
||||
from .models import Review
|
||||
|
|
@ -14,10 +15,14 @@ class ReviewViewSet(mixins.ListModelMixin, mixins.CreateModelMixin, viewsets.Gen
|
|||
|
||||
schema_tags = ['Reviews']
|
||||
serializer_class = ReviewSerializer
|
||||
permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
|
||||
required_alternate_scopes = {
|
||||
"POST": [[]],
|
||||
}
|
||||
|
||||
def get_permissions(self):
|
||||
if self.action == 'create':
|
||||
return [IsAuthenticated()]
|
||||
return [IsAuthenticatedOrTokenMatchesOASRequirements]
|
||||
return [AllowAny()]
|
||||
|
||||
def get_queryset(self):
|
||||
|
|
@ -32,8 +37,13 @@ class SellerReviewViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
|
|||
"""Reviews left for the authenticated seller's store, with reply support."""
|
||||
|
||||
schema_tags = ['Seller · Reviews']
|
||||
permission_classes = [IsAuthenticated, IsStoreOwner]
|
||||
serializer_class = ReviewSerializer
|
||||
# permission_classes = [IsAuthenticated, IsStoreOwner]
|
||||
# TODO:
|
||||
permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
|
||||
required_alternate_scopes = {
|
||||
"POST": [[]],
|
||||
}
|
||||
|
||||
def get_queryset(self):
|
||||
if getattr(self, 'swagger_fake_view', False):
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ from rest_framework.permissions import AllowAny, IsAuthenticated
|
|||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from apps.gooyal_oauth2.rest_framework import IsAuthenticatedOrTokenMatchesOASRequirements
|
||||
|
||||
from apps.core.permissions import IsStoreOwner
|
||||
|
||||
from .models import Store, StoreCategory, StoreWorkingHours
|
||||
|
|
@ -70,8 +72,11 @@ class SellerStoreView(APIView):
|
|||
"""The authenticated seller's own store — GET/PATCH to manage it, POST to create it."""
|
||||
|
||||
schema_tags = ['Seller · Store']
|
||||
permission_classes = [IsAuthenticated]
|
||||
serializer_class = SellerStoreSerializer
|
||||
permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
|
||||
required_alternate_scopes = {
|
||||
"POST": [[]],
|
||||
}
|
||||
|
||||
def get(self, request):
|
||||
store = get_object_or_404(Store, owner=request.user)
|
||||
|
|
@ -102,8 +107,13 @@ class SellerStoreWorkingHoursView(APIView):
|
|||
"""Bulk get/set the authenticated seller's weekly working hours (S14)."""
|
||||
|
||||
schema_tags = ['Seller · Store']
|
||||
permission_classes = [IsAuthenticated, IsStoreOwner]
|
||||
serializer_class = StoreWorkingHoursSerializer
|
||||
# permission_classes = [IsAuthenticated, IsStoreOwner]
|
||||
# TODO:
|
||||
permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
|
||||
required_alternate_scopes = {
|
||||
"POST": [[]],
|
||||
}
|
||||
|
||||
def get(self, request):
|
||||
hours = StoreWorkingHours.objects.filter(store=request.user.store)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue