Move pay views under /user/username/{bill, address, order, ...}

This commit is contained in:
fnux 2020-04-19 14:54:28 +02:00
commit caf7f7a2c2
7 changed files with 118 additions and 52 deletions

View file

@ -0,0 +1,24 @@
from rest_framework import permissions
from django.contrib.auth import get_user_model
class IsOwnerOrAdmin(permissions.BasePermission):
"""
Object-level permission to only allow owner or admin to edit an object.
Assumes the model instance has an `owner` attribute.
"""
def has_permission(self, request, view):
if request.user.is_staff:
return True
try:
target_user = get_user_model().objects.get(
username=view.kwargs['user_pk'])
return target_user == request.user
except:
return False
def has_object_permission(self, request, view, obj):
return (obj.owner == request.user) or request.user.is_staff

View file

@ -1,6 +1,7 @@
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.core.validators import MinValueValidator
from rest_framework.reverse import reverse
from uncloud import AMOUNT_DECIMALS, AMOUNT_MAX_DIGITS

View file

@ -1,16 +1,49 @@
from django.contrib.auth import get_user_model
from rest_framework import serializers
from rest_framework_nested.relations import NestedHyperlinkedRelatedField
from uncloud import AMOUNT_DECIMALS, AMOUNT_MAX_DIGITS
class UserSerializer(serializers.ModelSerializer):
class UserSerializer(serializers.HyperlinkedModelSerializer):
balance = serializers.DecimalField(max_digits=AMOUNT_MAX_DIGITS,
decimal_places=AMOUNT_DECIMALS)
bill_endpoint = serializers.HyperlinkedIdentityField(
view_name='user-bill-list',
lookup_field='username',
lookup_url_kwarg='user_pk'
)
order_endpoint = serializers.HyperlinkedIdentityField(
view_name='user-order-list',
lookup_field='username',
lookup_url_kwarg='user_pk'
)
address_endpoint = serializers.HyperlinkedIdentityField(
view_name='user-address-list',
lookup_field='username',
lookup_url_kwarg='user_pk'
)
payment_method_endpoint = serializers.HyperlinkedIdentityField(
view_name='user-payment-method-list',
lookup_field='username',
lookup_url_kwarg='user_pk'
)
payment_endpoint = serializers.HyperlinkedIdentityField(
view_name='user-payment-list',
lookup_field='username',
lookup_url_kwarg='user_pk'
)
class Meta:
model = get_user_model()
fields = ['username', 'email', 'balance', 'maximum_credit' ]
fields = ['username', 'email', 'balance', 'maximum_credit',
'bill_endpoint', 'order_endpoint', 'address_endpoint',
'payment_method_endpoint', 'payment_endpoint']
class ImportUserSerializer(serializers.Serializer):
username = serializers.CharField()

View file

@ -3,9 +3,11 @@ from .serializers import *
from django_auth_ldap.backend import LDAPBackend
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.generics import get_object_or_404
from rest_framework import mixins
from .models import *
class UserViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
class SelfViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
permission_classes = [permissions.IsAuthenticated]
serializer_class = UserSerializer
@ -18,9 +20,8 @@ class UserViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
serializer = self.get_serializer(user, context = {'request': request})
return Response(serializer.data)
class AdminUserViewSet(viewsets.ReadOnlyModelViewSet):
# FIXME: make this admin
permission_classes = [permissions.IsAuthenticated]
class UserViewSet(viewsets.ReadOnlyModelViewSet):
permission_classes = [permissions.IsAdminUser]
def get_serializer_class(self):
if self.action == 'import_from_ldap':
@ -29,7 +30,15 @@ class AdminUserViewSet(viewsets.ReadOnlyModelViewSet):
return UserSerializer
def get_queryset(self):
return get_user_model().objects.all()
return User.objects.all()
# Override default implementation to search by username instead of ID.
def retrieve(self, request, pk):
queryset = self.filter_queryset(self.get_queryset())
instance = get_object_or_404(queryset, username=pk)
serializer = self.get_serializer(instance)
return Response(serializer.data)
@action(detail=False, methods=['post'], url_path='import_from_ldap')
def import_from_ldap(self, request, pk=None):