I'm working on a web application that does not work well with Internet Explorer (web socket, json, security issues).
For now, before my application works with IE:
How can I refuse connections coming from Internet Explorer client ?
Thank you
Create a middleware where you're parsing the request.META['HTTP_USER_AGENT']. If you found that the user use IE, give him a nice message (e.g a notification or a little alert box) to says him that your site isn't optimized for his browser :)
Some code example: Django way
middleware.py (see the doc for more information)
class RequestMiddleware():
def process_request(self, request):
if request.META.has_key('HTTP_USER_AGENT'):
user_agent = request.META['HTTP_USER_AGENT'].lower()
if 'trident' in user_agent or 'msie' in user_agent:
request.is_IE = True
else:
request.is_IE = False
# or shortest way:
request.is_IE = ('trident' in user_agent) or ('msie' in user_agent)
your base template:
{% if request.is_IE %}<div class="alert">Watch out! You're using IE, but unfortunately, this website need HTML5 features...</div>{% endif %}
And then add it to your middlewares list.
Optimized: pure HTML way
If you only want to display a message like what I've done, you can use a HTML conditional comment:
<!--[if IE]> <div class="alert">...</div><![endif]-->
There is another way! Just use settings variable DISALLOWED_USER_AGENTS, and make sure that CommonMiddleware is installed on your site.
For example
import re
DISALLOWED_USER_AGENTS = (re.compile(r'msie\s*[2-7]', re.IGNORECASE), )
Cheers!
Related
I recently added clickjacking protection to a Django app with django.middleware.clickjacking.XFrameOptionsMiddleware but found that PDFs no longer load in Firefox. While Chrome, Safari, and Edge embed the PDF as expected, Firefox throws the following console error:
Load denied by X-Frame-Options: <site_base>/<file_path>.pdf does not permit framing.
I found the #xframe_options_exempt decorator that I thought would help, but that just wraps a view whereas these are served directly through Apache. The only fix I've found is to get the "Ignore X-Frame-Options Header" browser plugin which isn't really a customer friendly solution.
I've tried using <embed>, <object>, and <iframe> to embed the PDF and all cause the same browser console error, and if I remove the clickjacking middleware the PDFs load just fine again.
Anyone run into something like this before? Relevant code:
<select id="pdf_graph_selection" onchange="updatePDF()">
{% for pdf_graph in pdf_graphs %}
<option value="{{pdf_graph.url"}}>{{pdf_graph.name}}</option>
{% endfor %}
</select>
<div id="pdf_container"></div>
function updatePDF() {
let new_source = $("#pdf_graph_selection").val();
let new_graph = "'<embed src='" + new_source + "' width='70%' height='900px' class='pdf_embed'></embed>;
$("#pdf_container").html(new_graph);
}
My coworker was able to help figure it out - We had a custom file response handler that must have been doing something Firefox didn't like. By adding the #xframe_options_sameorigin decorator it is now working.
I'm using the Django Framework on Google App Engine.
I have multiple forms on the same view, to submit to different URL.
Trouble is after I get a form submitted: even if the called method update the datastore and some data, the previous page (where the forms are put in) is not refreshed, showing the updated data.
I could solve this problem using jQuery or some javascrip framework, appending dinamically content returned by the server but, how to avoid it?
Suggestions?
Am I wrong somewhere?
A part of "secure.html" template
<form action="/addMatch" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
Matches:
<br />
{% for m in matches%}
{{m.description}} ---> {{m.reward}}
{% endfor%}
the "/addMatch" URL view:
def addMatch(request):
form = MatchForm(request.POST)
if form.is_valid():
user = User.all().filter('facebookId =', int(request.session["pbusr"]))
m = Match(user=user.get(),description =form.cleaned_data["description"],reward=form.cleaned_data["reward"])
m.save()
return HttpResponseRedirect("/secure/")
else:
logging.info("Not valid")
return HttpResponseRedirect("/secure")
The view method whose seems not working:
#auth_check_is_admin
def secure(request):
model={}
user = User.all().filter('facebookId =', int(request.session["pbusr"]))
u = user.get()
if (u.facebookFanPageId is not None and not u.facebookFanPageId == ""):
model["fanPageName"] = u.facebookFanPageName
model["form"] = MatchForm()
model["matches"] = u.matches
else:
....
return render(request,"secure.html",model)
Francesco
Based on what you posted, it seems like you're redirecting properly and are having database consistency issues. One way to test this would be to look at the network tab in the Google Chrome developer tools:
Click on the menu icon in the upper right
Click on "Tools"
Click on "Developer Tools"
Click on "Network" in the thing that opened up at the bottom of the screen.
Now, there will be a new entry in the network tab for every request that your browser sends and every response it receives. If you click on a request, you can see the data that was sent and received. If you need to see requests across different pages, you might want to check the "Preserve log" box.
With the network tab open, go to your page and submit the form. By looking at the network tab, you should be able to tell whether or not your browser issued a new GET request to the same URL. If there is a new request for the same page but that request has the old content, then you have a datastore consistency issue. If there was NOT a new request that yielded a response with the data for the page, then you have a redirect issue.
If it turns out that you have a datastore consistency issue, then what's happening is the data is being stored, but the next request for that data might still get the old data. To make sure that doesn't happen, you need what's called "strong consistency."
In a normal App Engine project, you get strong consistency by putting entities in the same entity-group and using ancestor queries. I'm not certain of what database/datastore you're using for Django and how the different database layers interact with App Engine's consistency, so this could be wrong, but if you can give your users the right key and then fetch them from that key directly (rather than getting all users and filtering them by key), you might get strong consistency.
I am new to django and I really like its modular construction so I decided to take advantage of it and put all the separated functionalities each in different app.
Now I need a way to switch on and off this apps by both user and admin.
The user options panel would look like this:
[ ] blog
---------------------
[ ] tagging [BUY]
After checking "blog" option user would get the blog in his profile and after buying and checking "tagging" he would get tagging for the blog.
The admin panel would have an ability to show or hide an app from user panel.
I wonder if:
there is an app which would help me switch on and off an app for specyfic user
and if not -
what would be a proper "architecture" for such django app?
Can it be done dynamically in middleware or should it be done during login (check available apps from database, switch them on, redirect to user home page)?
Any advices for such a task?
Thanks,
Robert
I haven't heard of any such app… But I don't expect it would be too hard to build.
If I were doing it, I would put a permissions check in the entry points to each app. For example:
check_app_permission = lambda request: permissions.check_app_permission("blog", request)
def view_blog(request, …):
check_app_permission(request)
…
(it might even be possible to do some magic and inject this check at the urls.py level…)
Additionally, I would create a has_app_permission template tag:
<div id="sidebar">
{% if has_app_permission "blog" %}
{% include "blog/sidebar_recent_posts.html" %}
{% endif %}
</div>
Or similar.
Finally, there are approximately a million ways you could implement the permission system… And without more information I wouldn't be able to comment. The simplest, though, would be something like this:
class App(Model):
name = CharField(…)
class AppPermission(object):
app = ForeignKey(App)
user = ForiegnKey(User)
def user_has_permission(user, app_name):
return AppPermission.objects.filter(app__name=app_name, user=user).exists()
I would avoid trying to do this with middleware, because if I understand the problem correctly, I expect you will (or, at least, I expect I would) end up spending a bunch of time building a generic framework which, in the end, would just have checks similar to those above.
Does that help? Is there something I can clarify?
I am creating a django-based site that will serve flash apps that occasionally access data via pyamf. I need to be able to easily test the flash in the context of the django framework, i.e. with all the login cookies and everything available, so that when I make a pyamf call, it has all the user context there. And I need to be able to test and release both the swf's and the wrapper html's in a sane way. However:
The html templates in flex are already templates, so if I put template code in there for django, it gets scraped out before the flashapp.html is created.
The html's and swf's automatically get released to the same directory, but I want them to go to different directories because the swf's shouldn't be served by django and the html's should be in an area in control of django.
This leads me to believe, at first glance, that I need:
A way of having the html and swf files be released to different locations. (I don't know how to do this.)
A way of releasing the html's as stubs (no html/body tag) so that I can include them from another location in django. (I guess just strip what I don't want from the index.template.html?)
Then I can point flex to go to the django site that in turn includes the generated flashapp.html that in turn references the swf, and it should all work. (By feeding that alternate html to the run/debug settings, I assume.)
So my question comes down to:
Is the above the best way of doing this, or is this even the right direction?
If so, how do I release the html and swf to different directories? (For debug and release mode, if there are two different methods.)
If not, what is proper?
And if there are any other general bits of advice for me on this topic, please feel free to share. :-)
Finally figured this out myself. A combination of this and django get-parameters works. The general take-away:
You can put {% tags %} and {{ variables }} in index.template.html without worry, as there is no way to customize the currently-existing macros there like ${title}
If you make a foo.template.html and foo-debug.template.html in the html-template directory of your project, then the former will override index.template.html for release builds, and the latter for debug builds (note that the result will be foo-debug.html instead of foo.html though.)
You can pass the name of the SWF in a parameter to django, and have it fill in the directory for you
foo-debug.template.html
<object ...
<param name="movie" value="{{ bin_debug_url }}/${swf}.swf" ...
djangoflash.html
{% block content %}
{% include flash_template %}
{% endblock %}
views.py
def djangoflashview( request, **kwargs ):
if not kwargs.has_key('extra_context'):
kwargs['extra_context'] = {}
if request.GET.has_key('name'):
debug = "-debug" if request.GET.has_key('debug') else ""
bin_debug_dir = '/dir-to-bin-debug/'
bin_debug_url = 'url-to-bin-debug'
name = bin_debug_dir + request.GET['name'] + debug + '.html'
kwargs['extra_context']['flash_template'] = name
kwargs['extra_context']['bin_debug_url' ] = bin_debug_url
return direct_to_template( request, **kwargs )
urls.py
url( r'^djangoflash/', 'views.djangoflashview',
{ 'template': 'djangoflash.html' }
foo.mxml's run-debug target:
/url-to-django/djangoflash/?name=foo
When you debug foo.mxml, flex:
Adds &debug=true to the url
Brings up a browser to /url-to-djangoflash/djangoflash/?name=foo&debug=true
Which picks djangoflash/ in urls.py
Which passes the request to djangoflashview and {'name':'foo','debug':'true'} to request.GET in views.py
Which figures out the name and location of the foo-debug.html location, passing it to the flash_template context variable
And the url of the swf to the bin_debug_url context variable
And loads up the direct template djangoflash.html
Which, in djangoflash.html, includes the foo-debug.html wrapper for flash using the flash_template context variable
Which, in turn fills in the bin_debug_url context variable to point the foo.swf reference correctly to the thing you just compiled
Whew. :-P
Right now, if I want to check whether the current page is accessed through http:// or https://, I will use the following Javascript in my templates and write html from document.write:
<script type="text/javascript">
var protocol = document.location.protocol;
if (protocol == "http:")
document.write("regular");
else
document.write("secured");
</script>
Is there another way to achieve the above in Django's template without using Javascript?
if you use a RequestContext, you can do the following:
<p>You used: {% if request.is_secure %}HTTPS{% else %}HTTP{% endif %}
See the relevant part of the Django documentation.
Since Django 1.10, you can use:
request.scheme
in a view, or in a template:
{{ request.scheme }}
From the docs
A string representing the scheme of the request (http or https usually).
You need to enable the appropriate request context processor in your setting.py file:
TEMPLATE_CONTEXT_PROCESSORS = ('django.core.context_processors.request',)
The template will now have a variable named request that contains the current HttpRequest. You can use it to find the protocol:
{{ request.is_secure }}
Try using RequestContext and request.is_secure in your template.
One caveat, the process of detecting HTTPS can differ from one server setup to the next so you may have to do a little work to get request.is_secure working. You can get it working either by ensuring that your front end / reverse proxy sets 'HTTP_X_FORWARDED_HOST' or by writing a middleware class that is custom to your setup.
Use the deprecated SetRemoteAddrFromForwardedFor code as a starting point, if you go the custom middleware route.