I am trying to create a CustomUserViewset, and add a login_user api to it. The problem is that although I set the permission_classes
to AllowAny
, still when calling the login_user api, it says: {"detail":"Please login to perform this action"}
.
Here is my API:
class CustomUserViewset(AutoPermissionViewSetMixin, viewsets.ModelViewSet):
queryset = User.objects.none()
serializer_class = CustomUserSerializer
permission_type_map = {
"create": "add",
"destroy": "delete",
"partial_update": "change",
"retrieve": "view",
"update": "change",
"register": "view",
"login_user": "view",
"logout": "change",
}
@decorators.action(methods=["POST"], detail=False, permission_classes=[permissions.AllowAny])
def login_user(self, request):
serializer = LoginSerializer(data=request.data)
if not serializer.is_valid():
raise exceptions.ValidationError({"detail": "Invalid username or password"})
username = serializer.validated_data["username"]
password = serializer.validated_data["password"]
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return Response(CustomUserSerializer(user).data, status=status.HTTP_200_OK)
else:
raise exceptions.AuthenticationFailed({"detail": "Invalid username or password"})
As you see, I have permission_classes=[permissions.AllowAny]
in the api action.
Also, giving this permission class in the action was the last thing I tried, before that, I tried to adjust the permission in rules.py:
import typing
import rules
if typing.TYPE_CHECKING:
from .models import User
rules.add_perm("accounts.login_user", rules.predicates.always_allow)
None of the above methods has worked, and I still get the same message that I need to log in to perform this action.
**** UPDATE ON THE ANSWER ****
I solved this problem with first adding a few permissions to
permission_type_map
, then adjusting the rules.py:And in the rules.py:
Now with these new permissions and rules, all three APIs work as expected.