Postman: Could not get any response - python

My Django Rest API views.py:
# encoding: utf-8
from fileupload.response import JSONResponse, response_mimetype
from fileupload.models import *
from rest_framework.views import *
from rest_framework.parsers import *
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
"""A simple API for file upload."""
class FileUploadView(APIView):
authentication_classes = ()
#method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
return super(FileUploadView, self).dispatch(request, *args, **kwargs)
def put(self, request):
print "xxx:", request
try:
psfile = MyFile.objects.create(file=request.FILES['file'])
psfile.save()
data = {'files': 'testing'}
response = Response(data)
except Exception as e:
print "Exception when put file:", e
data = { 'error' : str(e)}
response = Response(data)
return response
setting.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ()
}
I am doing PUT in Postman with Postman Interceptor enabled.
Tried to put the file in the body as form-data.
But failed with the following error:
Could not get any response
There was an error connecting to https://ip/projectname/api/upload/.
Why this might have happened:
1. The server couldn't send a response:
Ensure that the backend is working properly
2. SSL connections are being blocked:
Fix this by importing SSL certificates in Chrome
3. Cookies not being sent: Use the Postman Interceptor extension
4. Request timeout:
Change request timeout in Settings > General
Any ideas? Thanks in advance.
UPDATE
https://github.com/postmanlabs/postman-app-support/issues/506
http://blog.getpostman.com/2014/01/28/using-self-signed-certificates-with-postman/

Related

Django - How to add access token to Client.post in Django test?

So I have some code below. Every endpoint has an authentication process, which is below as well. I want to be able to attach an access token, which is in cls.user to the Client.post so that I can test all the endpoints and ensure they are authenticating properly as well. How can I do this? So ideally I'd be attaching <bearer> <access token> to request.Meta['HTTP_AUTHORIZATION']
test.py
import json
from cheers.models import *
from warrant import Cognito
from django.urls import reverse
from django.test import TestCase
from rest_framework import status
from cheers.models import GoalCategory, Post
from dummy_factory.Factories import UserFactory, GoalFactory
class PostTest(TestCase):
#classmethod
# Generates Test DB data to persist throughout all tests
def setUpTestData(cls) -> None:
cls.goal_category = 'health'
GoalCategory.objects.create(category=cls.goal_category, emoji_url='url')
cls.user = UserFactory()
cls.goal = GoalFactory()
user_obj = User.objects.get(pk=cls.user.phone_number)
goal_obj = Goal.objects.get(pk=cls.goal.uuid)
Post.objects.create(creator_id=user_obj, goal_id=goal_obj, body='Some text')
cls.user = Cognito(<Some login credentials>)
cls.user.authenticate(password=<password>)
def test_create(self):
response = self.client.post(reverse('post'),
data=json.dumps({'creator_id': str(self.user.uuid),
'goal_id': str(self.goal.uuid),
'body': 'Some text #Test'}),
content_type='application/json')
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
Test authenticator function
def cognito_authenticator(view_func):
def wrapped_view(request, *args, **kwargs):
# Check the cognito token from the request.
token = request.META['HTTP_AUTHORIZATION'].split(' ')[1]
try:
jwt.decode_cognito_jwt(token)
except Exception:
# Fail if invalid
return Response("Invalid JWT", status=status.HTTP_401_UNAUTHORIZED) # Or HttpResponseForbidden()
else:
# Proceed with the view if valid
return view_func(request, *args, **kwargs)
return wrapped_view
You can set the header like this:
token = 'sometoken'
response = self.client.post(
reverse('post'),
data=json.dumps({
'creator_id': str(self.user.uuid),
'goal_id': str(self.goal.uuid),
'body': 'Some text #Test'
}),
content_type='application/json',
**{'HTTP_AUTHORIZATION': f'Bearer {token}'}
)
And then access the header using:
request.META['HTTP_AUTHORIZATION']

Django to return a view with TokenAuthentication for WebView

I am trying to create a flutter app which will use webview to display authenticated data from my Django App.
Steps Involved:
Flutter app sends authentication request
Django validates the user credentials (user id & Password) and returns authtoken
Flutter then sends a request via a webview to a url (which requires login).
I would like to login the user in webapp using this token and return the webview.
If the url does not require authentcation, it works like a charm.
When the url requires authentication, I am redirected to the login page and I want users to bypass that using token authentication which is already aquired in Step 1
here is my Django view.
class QuizTake(FormView):
permission_classes = (IsAuthenticated,)
form_class = QuestionForm
template_name = 'question.html'
result_template_name = 'result.html'
single_complete_template_name = 'single_complete.html'
login_template_name='login.html'
def dispatch(self, request, *args, **kwargs):
self.quiz = get_object_or_404(Quiz, url=self.kwargs['quiz_name'])
print(self.kwargs['quiz_name'])
"""
Authenticate if the request has token authentication
"""
if self.quiz.draft and not request.user.has_perm('quiz.change_quiz'):
raise PermissionDenied
try:
self.logged_in_user = self.request.user.is_authenticated()
except TypeError:
self.logged_in_user = self.request.user.is_authenticated
if self.logged_in_user:
self.sitting = Sitting.objects.user_sitting(request.user,
self.quiz)
else:
self.sitting = self.anon_load_sitting()
if self.sitting is False:
print("sitting false")
if self.logged_in_user:
return render(request, self.single_complete_template_name)
else:
redirecturl = "/login/?next=/quiz/"+self.kwargs['quiz_name']+"/take/"
return redirect(redirecturl)
return super(QuizTake, self).dispatch(request, *args, **kwargs)
Flutter Code
class _QuizLauncherState extends State<QuizLauncher> {
final String url, authtoken;
final int userId;
String quizUrl;
_QuizLauncherState(this.url, this.authtoken,this.userId);
void initState() {
quizUrl = 'https://test.mysite.com/quiz/$url/take';
print(quizUrl);
//for reference https://test.mysite.com/quiz/56df5d90-7f67-45ff-8fe1-7c07728ba9ab/take/
super.initState();
}
Completer<WebViewController> _controller = Completer<WebViewController>();
final Set<String> _favorites = Set<String>();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
// This drop down menu demonstrates that Flutter widgets can be shown over the web view.
actions: <Widget>[
NavigationControls(_controller.future),
Menu(_controller.future, () => _favorites),
],
),
body: WebView(
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
Map<String, String> headers = {"Authorization": "Bearer " + authtoken};
webViewController.loadUrl(quizUrl, headers: headers);
},
),
);
}
}
Is this possible at all? If there are any alternate ways, please tell me. Basically, I am trying to access a url via webview which requires authentication, using authtoken. Please help.
You can use custom authentication classes like this, say if you are using Authorization header:
from rest_framework.authentication import BaseAuthentication
class MyCustomAuth(BaseAuthentication):
def authenticate(self, request):
auth_method, token = request.META['HTTP_AUTHORIZATION'].split(' ', 1)
# Get your user via the token here
if you_got_your_user:
return user, None
return None # or raise AuthFailedException
class QuizTake(FormView):
authentication_classes = (MyCustomAuth, )
This still depends on how your token identifies the user though. For example if you are using JWT, there are existing authentication classes already that handles this for you.
EDIT:
Looked at knox documentation from here. If you used knox, then you should probably use their own TokenAuthentication class. Can you try with below code:
from knox.auth import TokenAuthentication
class QuizTake(FormView):
authentication_classes = (TokenAuthentication, )
You can use authentication from rest framework lib like as below code.
import base64
import binascii
from django.contrib.auth import authenticate, get_user_model
from django.middleware.csrf import CsrfViewMiddleware
from django.utils.translation import gettext_lazy as _
from rest_framework import HTTP_HEADER_ENCODING, exceptions
def get_authorization_header(request):
auth = request.META.get('HTTP_AUTHORIZATION', b'')
if isinstance(auth, str):
auth = auth.encode(HTTP_HEADER_ENCODING)
return auth
class BaseAuthentication:
raise NotImplementedError(".authenticate() must be overridden.")
def authenticate_header(self, request):
pass
class SessionAuthentication(BaseAuthentication):
user = getattr(request._request, 'user', None)
if not user or not user.is_active:
return None
self.enforce_csrf(request)
return (user, None)
def enforce_csrf(self, request):
def dummy_get_response(request):
return None
check = CSRFCheck(dummy_get_response)
check.process_request(request)
reason = check.process_view(request, None, (), {})
if reason:
raise exceptions.PermissionDenied('CSRF Failed: %s' % reason)
class TokenAuthentication(BaseAuthentication):
keyword = 'Token'
model = None
def get_model(self):
if self.model is not None:
return self.model
from rest_framework.authtoken.models import Token
return Token
Or go through the below link for better understanding
[Toke Authorization]

Django Rest Framework custom message for 404 errors

I have a generic class based view:
class ProjectDetails(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
generics.GenericAPIView):
queryset = Project.objects.all()
# Rest of definition
And in my urls.py, I have:
urlpatterns = [
url(r'^(?P<pk>[0-9]+)/$', views.ProjectDetails.as_view())
]
When the API is called with a non-existent id, it returns HTTP 404 response with the content:
{
"detail": "Not found."
}
Is it possible to modify this response?
I need to customize error message for this view only.
This solution affect all views:
Surely you can supply your custom exception handler: Custom exception handling
from rest_framework.views import exception_handler
from rest_framework import status
def custom_exception_handler(exc, context):
# Call REST framework's default exception handler first,
# to get the standard error response.
response = exception_handler(exc, context)
# Now add the HTTP status code to the response.
if response.status_code == status.HTTP_404_NOT_FOUND:
response.data['custom_field'] = 'some_custom_value'
return response
Sure you can skip default rest_framework.views.exception_handler and make it completely raw.
Note: remember to mention your handler in django.conf.settings.REST_FRAMEWORK['EXCEPTION_HANDLER']
Solution for specific view:
from rest_framework.response import Response
# rest of the imports
class ProjectDetails(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
generics.GenericAPIView):
queryset = Project.objects.all()
def handle_exception(self, exc):
if isinstance(exc, Http404):
return Response({'data': 'your custom response'},
status=status.HTTP_404_NOT_FOUND)
return super(ProjectDetails, self).handle_exception(exc)
It's possible by overriding specific methods like update, retrieve as:
from django.http import Http404
from rest_framework.response import Response
class ProjectDetails(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
generics.GenericAPIView):
queryset = Project.objects.all()
def retrieve(self, request, *args, **kwargs):
try:
return super().retrieve(request, *args, **kwargs)
except Http404:
return Response(data={"cusom": "message"})
def update(self, request, *args, **kwargs):
try:
return super().update(request, *args, **kwargs)
except Http404:
return Response(data={"cusom": "message"})

how to get request HTTP headers in soaplib views file?

i have soaplib for webservice as soap [server], all request route and response as xml by url well.but i can't fetch request http headers, How can i get request HTTP headers for rendering view some method of class ?
like this method :
def redirect_http(self,request):
return render(request, 'ask/redirect.html', {
''' 'question': question,
'error_message': "You didn't select a choice.", '''
})
Code Project :
soap.py
'''
documentation in http://soaplib.github.com/soaplib/2_0/
'''
import base64
import soaplib
from soaplib.core import Application
from soaplib.core.model import primitive as soap_types
from soaplib.core.service import DefinitionBase
from soaplib.core.service import rpc as soapmethod
from soaplib.core.server import wsgi
from soaplib.core.model.clazz import ClassModel
from soaplib.core.model.clazz import Array
from django.http import HttpResponse
# the class with actual web methods
# the class which acts as a wrapper between soaplib WSGI functionality and Django
class DjangoSoapApp(wsgi.Application):
def __call__(self, request):
# wrap the soaplib response into a Django response object
django_response = HttpResponse()
def start_response(status, headers):
status, reason = status.split(' ', 1)
django_response.status_code = int(status)
for header, value in headers:
django_response[header] = value
response = super(DjangoSoapApp, self).__call__(request.META, start_response)
django_response.content = '\n'.join(response)
return django_response
class SoapView(DefinitionBase):
#classmethod
def as_view(cls):
soap_application = Application([cls], __name__)
return DjangoSoapApp(soap_application)
# the view to use in urls.py
#my_soap_service = DjangoSoapApp([MySOAPService], __name__)
views.py
from soap import SoapView
from soap import soapmethod
from soap import soap_types, Array
class MySoapService(SoapView):
__tns__ = '[url]http://localhost:8989/api/soap/verify.wsdl[/url]'
#soapmethod(soap_types.String, soap_types.Integer, returns=soap_types.String)
def request_verify(self, q, id, uri):
#Some Code
return 'some return'
my_soap_service = MySoapService.as_view()
urls.py
from django.conf.urls import patterns, include, url
from django.views.generic import RedirectView
import views
# Main URL Patterns
urlpatterns = [
url(r'^verify', views.my_soap_service),
url(r'^verify.wsdl', views.my_soap_service),
]
problem resolved : change method request (for generate html and get http header most Observe protocol HTTP and structure), so to request and response html content should be send http request and get all headers generated

DjangoRestFramework upload file 'CSRF Verification Failed'

I am using DjangoRestFramework to make an API. Currently I have OAuth2 authentication working which means I can generate a valid access token to use the API.
How do I upload a user file? I need to upload a file and relate it to the user who uploaded it.
I am currently trying to do it this way
api/views.py:
class FileUploadView(APIView):
parser_classes = (FileUploadParser,)
def put(self, request, filename, format=None):
file_obj = request.FILES['file']
# do stuff
return Response(status=204)
api/urls.py contains this line:
url(r'^files/', 'api.views.FileUploadView'),
but when I try to upload a file I get an error stating that:
'CSRF verification failed. Request aborted'
'Reason given for failure: CSRF cookie not set'
when I try this curl command:
curl -XPUT http://localhost:8000/files/ -H 'Authorization: Bearer some_access_token' -F filedata=#localfile.txt
Here are my REST_FRAMEWORK defaults:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAdminUser',),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.OAuth2Authentication',
)
}
1) In my original code I was expecting a filename parameter to come into my view but I was not parsing it out of the url in urls.py. It should have looked something like this:
url(r'^uploads/(?P<filename>[\w.]{0,256})/$', views.UploadsView.as_view()),
2) I was also not providing the APIView as a view. If you notice above I am specifically calling the .as_view() method.
With the above fixed and implementing POST instead of PUT my code works as expected. Here is my current APIView:
class UploadsView(APIView):
parser_classes = (FileUploadParser,)
permission_classes = (permissions.IsAuthenticated,)
def post(self, request, format=None):
file_obj = request.FILES['file']
print("FILE OBJ: ", file_obj)
return Response(status=201)
Per the Django REST Framework Documentation, "If you're using SessionAuthentication you'll need to include valid CSRF tokens for any POST, PUT, PATCH or DELETE operations.
In order to make AJAX requests, you need to include CSRF token in the HTTP header, as described in the Django documentation."
Alternatively, you can attempt to make this view CSRF Exempt:
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
class FileUploadView(APIView):
parser_classes = (FileUploadParser,)
#method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
return super(FileUploadView, self).dispatch(request, *args, **kwargs)
def put(self, request, filename, format=None):
file_obj = request.FILES['file']
# do stuff
return Response(status=204)

Categories

Resources