usage of require_POST in django - django

I wanna know is there a usage or security tip to use required-post or require-get decorators in django?
from django.views.decorators.http import require_GET, require_POST

#require_GET [Django-doc], and #require_POST [Django-doc] are special cases of #require_http_methods(…) [Django-doc]. These enforce that you can only call a view with certain HTTP methods.
The HTTP protocol specifies that requests that "safe methods", for example a GET request should not have side effects [rfc-editor.org]:
Request methods are considered "safe" if their defined semantics are essentially read-only; i.e., the client does not request, and does not expect, any state change on the origin server as a result of applying a safe method to a target resource.
(…)
Of the request methods defined by this specification, the GET, HEAD, OPTIONS, and TRACE methods are defined to be safe.
This thus means that you should not create, update, remove, etc. records with a GET request for example. A "search spider" for example will normally assume that a GET request is safe. If you have a view that deletes an item through a GET request, then the spider might accidentally remove an entry.
By using such decorators, you thus require the requests to have a certain HTTP method.

Related

Is it okay to use patch for full update instead of put?

I am using Django and DRF for APIs. Suppose I have an object with three fields (name, password, email). When a user wants to update his name, password and email at the same time, is it okay for me to send a PATCH request instead of a PUT request? What are the downfalls?
I feel this is more convenient than checking if the user is updating all fields, and if he is, using a PUT request, but if he's not, using a PATCH.
Checking if the object exists is already taken care of in the backend, and when creating objects, I use CREATE / POST instead of PUT because it is more convenient for me.
Edit: I am using AngularJS's PATCH: https://docs.angularjs.org/api/ng/service/$http#patch to send content to the backend, which is handled by DRF Viewset (which handles PATCH requests).
It's OK to use PATCH. However, note that it will not check for required fields as opposed to PUT.
It's not OK to use PATCH unless you use a media type that has defined semantics for PATCH. "application/json" does not.
See https://www.rfc-editor.org/errata_search.php?eid=3169:
If the operation does not modify the resource identified by the
Request-URI in a predictable way that's defined by the semantics
of the PATCH media type, POST should be considered instead of
PATCH or PUT.
FWIW, see RFC 6902 and RFC 7386 for types you could use.

fake a request in Django

I have a Django equipped with Tastypie and under REST style it's not easy to combine objectes of different types together, so I'm thinking if it's posible to provide a special view for combining response of several REST urls into a bigger JSON object and return to client. The url may look like,
http:// domain.com /combined_view/?p={rest url 1...}&p={rest url
2...}&p={rest url 3...}
and returned JSON would be,
[ {response of rest url 1...},
{response of rest url 2...},
{response of rest url 3...},
...
]
The question is, inside a normal django view, how can I fake a request object, and process it into a response object? Thx.
Calling your own RESTful API from inside your view is a waste of resources. Directly access the objects using the database ORM instead.
Also unrelated Resources/Objects are supposed to be not combined together. If you think that the models should be combined together then maybe your model needs to take care of it and have a relation combining the two.
And to answer your question directly, you can call your urls using httplib2 and parse the response.
I urge you to reconsider whatever it is that your doing, because whatever answer we give you here is bound to go directly against the resourceful design of REST interfaces.
If you have Foo, Bar and Baz models and you create equivalent resources for them, it's impossible to generate a request that's going to return a mixed collection of Foo, Bar, Baz resources, unless these are nested resources in a joint relationship.
Your either not thinking in a resourceful manner or don't need to, but definitely don't turn RESTful architectures into something they haven't been designed for.

Is this Django Middleware Thread-safe?

I am writing forum app on Django using custom session/auth/users/acl system. One of goals is allowing users to browse and use my app even if they have cookies off. Coming from PHP world, best solution for problem is appending sid= to every link on page. Here is how I plan to do it:
Session middleware checks if user has session cookie or remember me cookie. If he does, this most likely means cookies work for him. If he doesnt, we generate new session ID, open new session (make new entry in sessions table in DB), then send cookie and redirect user to where he is, but with SID appended to url. After redirect middleware will see if session id can be obtained from either cookie or GET. If its cookie, we stop adding sid to urls. If its GET, we keep them.
I plan to insert SID= part into url's by decorating django.core.urlresolvers.reverse and reverse_lazy with my own function that appends ?sid= to them. However this raises some problems because both middlewares urlresolvers and are not thread safe. To overcome this I created something like this:
class SessionMiddleware(object):
using_decorator = False
original_reverse = None
def process_request(self, request):
self.using_decorator = True
self.original_reverse = urlresolvers.reverse
urlresolvers.reverse = session_url_decorator(urlresolvers.reverse, 's87add8ash7d6asdgas7dasdfsadas')
def process_response(self, request, response):
# Turn off decorator if we are using it
if self.using_decorator:
urlresolvers.reverse = self.original_reverse
self.using_decorator = False
return response
If SID has to be passed via links, process_request sets using_decorator to true and stores undecorated urlresolvers.revers in separate method. After page is rendered process_response checks using_decorator to see if it has to perform "garbage collection". If it does, it returns reverse function to original undecorated state.
My question is, is this approach thread-safe? Or will increase in traffic on my forum may result in middleware decorating those functions again and again and again, failing to run "garbage collection"? I also tought about using regex to simply skim generated HTML response for links and providing template filters and variables for manually adding SID to places that are omitted by regex.
Which approach is better? Also is current one thread safe?
First of all: Using SIDs in the URL is quite dangerous, eg if you copy&paste a link for a friend he is signed in as you. Since most users don't know what a SID is they will run into this issue. As such you should never ever use SIDs in the url and since Facebook and friends all require cookies you should be fine too...
Considering that, monkeypatching urlresolvers.reverse luckily doesn't work! Might be doable with a custom URLResolvers subclass, but I recommend against it.
And yes, your middleware is not threadsafe. Middlewares are initialized only once and shared between threads, meaning that storing anything on self is not threadsafe.

Practical rules for Django MiddleWare ordering?

The official documentation is a bit messy: 'before' & 'after' are used for ordering MiddleWare in a tuple, but in some places 'before'&'after' refers to request-response phases. Also, 'should be first/last' are mixed and it's not clear which one to use as 'first'.
I do understand the difference.. however it seems to complicated for a newbie in Django.
Can you suggest some correct ordering for builtin MiddleWare classes (assuming we enable all of them) and — most importantly — explain WHY one goes before/after other ones?
here's the list, with the info from docs I managed to find:
UpdateCacheMiddleware
Before those that modify 'Vary:' SessionMiddleware, GZipMiddleware, LocaleMiddleware
GZipMiddleware
Before any MW that may change or use the response body
After UpdateCacheMiddleware: Modifies 'Vary:'
ConditionalGetMiddleware
Before CommonMiddleware: uses its 'Etag:' header when USE_ETAGS=True
SessionMiddleware
After UpdateCacheMiddleware: Modifies 'Vary:'
Before TransactionMiddleware: we don't need transactions here
LocaleMiddleware, One of the topmost, after SessionMiddleware, CacheMiddleware
After UpdateCacheMiddleware: Modifies 'Vary:'
After SessionMiddleware: uses session data
CommonMiddleware
Before any MW that may change the response (it calculates ETags)
After GZipMiddleware so it won't calculate an E-Tag on gzipped contents
Close to the top: it redirects when APPEND_SLASH or PREPEND_WWW
CsrfViewMiddleware
Before any view middleware that assumes that CSRF attacks have been dealt with
AuthenticationMiddleware
After SessionMiddleware: uses session storage
MessageMiddleware
After SessionMiddleware: can use Session-based storage
XViewMiddleware
TransactionMiddleware
After MWs that use DB: SessionMiddleware (configurable to use DB)
All *CacheMiddleWare is not affected (as an exception: uses own DB cursor)
FetchFromCacheMiddleware
After those those that modify 'Vary:' if uses them to pick a value for cache hash-key
After AuthenticationMiddleware so it's possible to use CACHE_MIDDLEWARE_ANONYMOUS_ONLY
FlatpageFallbackMiddleware
Bottom: last resort
Uses DB, however, is not a problem for TransactionMiddleware (yes?)
RedirectFallbackMiddleware
Bottom: last resort
Uses DB, however, is not a problem for TransactionMiddleware (yes?)
(I will add suggestions to this list to collect all of them in one place)
The most difficult part is that you have to consider both directions at the same time when setting the order. I would say that's a flaw in the design and I personally would opt for a separate request and response middleware order (so you wouldn't need hacks like FetchFromCacheMiddleware and UpdateCacheMiddleware).
But... alas, it's this way right now.
Either way, the idea of it all is that your request passes through the list of middlewares in top-down order for process_request and process_view. And it passes your response through process_response and process_exception in reverse order.
With UpdateCacheMiddleware this means that any middleware that changes the Vary headers in the HTTP request should come before it. If you change the order here than it would be possible for some user to get a cached page for some other user.
How can you find out if the Vary header is changed by a middleware? You can either hope that there are docs available, or simply look at the source. It's usually quite obvious :)
One tip that can save your hair is to put TransactionMiddleware in such place on the list, in which it isn't able to rollback changes commited to the database by other middlewares, which changes should be commited no matter if view raised an exception or not.

How to manipulate the response object in django-piston?

I have some existing python code that uses django-piston which returns a dictionary as its response. For example:
from piston.handler import BaseHandler
class FooHandler(BaseHandler):
allowed_methods = ('GET',)
#classmethod
def create(self, request):
return { 'foo': 'bar' }
This code works fine, and is serialized into JSON with the appropriate HTTP header set (I'm assuming this works by some piston magic involving emitters; for bonus points, feel free to clarify how this behavior works as well, as I'm still getting to know django-piston).
I need to be able to modify the response in arbitrary ways, e.g. setting headers, status codes, etc. without using some pre-baked solution designed for a specific purpose. Is there a convenient way to access the response object in the context of this code and manipulate it, or has the response object not yet been created? In order to get access to a response object, will I have to construct it manually (a la vanilla django), serialize the dictionary, and set the appropriate headers by hand, and thus lose out on some of the useful magic of django-piston?
Every django-piston method returns an HTTPResponse.
When you return that dictionary, django-piston is just serializing it and sticking it in an HTTPResponse that it has crafted of some variety.
Kind of surprised you didn't pick up on that given that those "return rc.CREATED" lines in all the django-piston examples in the wiki are just hyper-simplistic responses with an HTTP code and response body.
Take a look here: https://bitbucket.org/jespern/django-piston/src/c4b2d21db51a/piston/utils.py
at the rc_factory class, which creates a variety of simple HTTPResponse objects for use with Piston.
At the very least you can observe how they do it, and then craft your own.
But the answer to the essence of your question "can I make a custom HTTPResponse" is yes, you can. Of course, that's what web servers do.
It is possible to set a custom response code by returning an HttpResponse object from your handler methods.
return HttpResponse({'foo': 'bar'}, status=404)
Unfortunately, you cannot set headers in the same way. For this, you have to write a custom Emitter that sets the headers you need. Something along these lines might work:
class CustomEmitter(JSONEmitter):
def render(self, request):
content = super(CustomEmitter, self).render(request)
response = HttpResponse(content)
response['Cache-Control'] = 'max-age=60'
Emitter.register('json', CustomEmitter, 'application/json; charset=utf-8')
You are quite right that django-piston uses emitters to serialize/deserialize requests and responses. You can even register your own emitters with piston and have it use those.
There are several ways that you can determine what the format should be.
1. mime-type
2. <format> in your URL
3. .json at the end of your URL
Which particular headers are you wanting to manipulate? There may be other solutions then just hacking away at the response object.