middleware is not work expected - python

I have some problem related to that I am trying to implement a middleware which detects the whether the authenticated user is inactive for 5 seconds. I have wrote below Python module to do this job but It seems it is not works well. I found two reason ;
One of them is ; I can not redirect the user to the home page correctly
; Middleware is not change session key correctly
I have not found that how I can solve this problems. I will show what I have done to the below as two part.
First part ; middleware.py
class TimeOut:
#csrf_exempt
def process_request(self, request):
try :
if request.session['isA'] == False:
return #redirect(reverse("homePage_view"))
except KeyError:
request.session['isA'] = False
return
try :
passT = datetime.now() - request.session['Time']
if passT > timedelta( 0, settings.SESSION_COOKIE, 0):
request.session['isA'] = False
del request.session['Time']
return
except KeyError:
pass
request.session['Time'] = datetime.now()
Second part ; settings.py
SESSION_COOKIE = 5
MIDDLEWARE_CLASSES = (
'home.middleware.TimeOut',
)
EDIT: I have mistakenly wrote other class. I have changed the name as TimeOut

Is this the one you are talking:
class AutoLogout:
def process_request(self, request):
if not request.user.is_authenticated() :
return HttpResponseRedirect(reverse('app_name:url_name'))
try:
if datetime.now() - request.session['last_touch'] > timedelta( 0, settings.AUTO_LOGOUT_DELAY * 60, 0):
auth.logout(request)
del request.session['last_touch']
return HttpResponseRedirect(reverse('app_name:url_name'))
except KeyError:
pass
request.session['last_touch'] = datetime.now()
decorators.py
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
def login_check(view_func):
def _wrapped_view_func(request, *args, **kwargs):
if not request.user.is_authenticated:
//return to home page url
return HttpResponseRedirect(reverse('app_name:url_name'))
return view_func(request, *args, **kwargs)
return _wrapped_view_func
After you create decorators.py, update your view like this:
from app_name.decorators import login_check
#login_check
def view_name(request):
.........
The user will not be allow to go to that page if not authenticated.

Related

Why isn't the User information appending the mysql database using django?

I am having issues with a django-ajax project in which whenever I try to register a user, it does not append the user information to the mysql database and instead I get this in the terminal when I run the server:
Not Found: /sign-up/ajax-sign-up
[Time of request] " POST /sign-up/ajax-sign-up HTTP/1.1" 404 2430
Furthermore, I get this error that does not go away on VScode regarding the User class on the forms.py:
Class 'User' has no 'objects' member
I have added the pylint add-on to remove the error assuming is the Class 'User' error is the issue and I have rewriting the views.py but nothing has worked.
Here is my forms.py script:
from django import forms
from django.contrib.auth import authenticate
from django.db.models import F
from project.models import User
from django.contrib.auth.hashers import make_password, check_password
from urllib.request import urlopen
from random import randint
import json, re
class Ajax(forms.Form):
args = []
user = []
def __init__(self, *args, **kwargs):
self.args = args
if len(args) > 1:
self.user = args[1]
if self.user.id == None:
self.user = "NL"
def error(self, message):
return json.dumps({ "Status": "Error", "Message": message }, ensure_ascii=False)
def success(self, message):
return json.dumps({ "Status": "Success", "Message": message }, ensure_ascii=False)
def items(self, json):
return json
def output(self):
return self.validate()
class AjaxSignUp(Ajax):
def validate(self):
try:
self.username = self.args[0]["username"]
self.password = self.args[0]["password"]
self.email = self.args[0]["email"]
except Exception as e:
return self.error("Malformed request, did not process.")
if not re.match('^[a-zA-Z0-9_]+$', self.username):
return self.error("Invalid username, must be fit [a-zA-Z0-9_]")
if not re.match('^[a-zA-Z0-9_.+-]+#[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$', self.email):
return self.error("Invalid email syntax.")
if len(self.username) < 4 or len(self.username) > 20:
return self.error("Username must be between 3 and 20 characters long.")
if len(self.password) < 6 or len(self.password) > 32:
return self.error("Password must be between 6 and 32 characters long.")
if len(self.email) < 6 or len(self.email) > 140:
return self.error("Email must be between 6 and 32 characters long.")
if User.objects.filter(username=self.username).exists():
return self.error("Username already in use.")
if User.objects.filter(email=self.email).exists():
return self.error("Email address already in use.")
u = User(username=self.username, password=make_password(self.password), email=self.email)
u.save()
return self.success("Account Created!")
class AjaxLogin(Ajax):
def validate(self):
try:
self.password = self.args[0]["password"]
self.email = self.args[0]["email"]
except Exception as e:
return None, self.error("Malformed request, did not process.")
if not re.match('^[a-zA-Z0-9_.+-]+#[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$', self.email):
return None, self.error("Invalid email syntax.")
if len(self.password) < 6 or len(self.password) > 32:
return None, self.error("Password must be between 6 and 32 characters long.")
if len(self.email) < 6 or len(self.email) > 140:
return None, self.error("Email must be between 6 and 32 characters long.")
if not User.objects.filter(email=self.email).exists():
return None, self.error("Email or password is incorrect.")
if not check_password(self.password, User.objects.filter(email=self.email)[0].password):
return None, self.error("Email or password is incorrect.")
u = User.objects.filter(email=self.email)[0]
return u, self.success("User logged in!")
views.py script:
from django.shortcuts import render, redirect
from .models import User
from .forms import *
from django.contrib.auth import authenticate, login, logout as dlogout
def ajaxsignup(request):
ajax = AjaxSignUp(request.POST)
context = {'ajax_output': ajax.output() }
return render(request, 'ajax.html', context)
def ajaxlogin(request):
ajax = AjaxLogin(request.POST)
logged_in_user, output = ajax.validate()
if logged_in_user != None:
login(request, logged_in_user)
context = {'ajax_output': output}
return render(request, 'ajax.html', context)
def signup(request):
context = {}
return render(request, 'sign-up.html', context)
def index(request):
context = {}
return render(request, 'index.html', context)
and urls.py:
from django.contrib import admin
from django.urls import path
from . import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.index),
path('sign-up/', views.signup),
path('ajax-sign-up', views.ajaxsignup),
path('ajax-login', views.ajaxlogin),
]
No matter what I try, I continue to get these errors:
Not Found: /sign-up/ajax-sign-up
[Time of request] " POST /sign-up/ajax-sign-up HTTP/1.1" 404 2430
and User information is not appended to the database. The user information should be updated and I am sure that the I am calling the classes correctly.
I greatly appreciate your time and consideration.
I can't understand what you are doing in that Ajax class, but that class doesn't seem to be used anyway; you have AjaxSignup and AjaxLogin instead, which you haven't shown.
But nevertheless, your error doesn't even come from any of this code. As the message clearly says, you are requesting a URL that doesn't exist. You are requesting "/sign-up/ajax-sign-up", but your signup URL is just "/ajax-sign-up".
(And the warning from pylint is just that, a warning; you should ignore it. But, again, you aren't even using User anywhere in the code you have shown.)

How to prevent brute force attack in Django Rest + Using Django Rest Throttling

Block particular user for some specific time to using Django REST Throttling.
I have seen Django REST Throttling.
I don't want to use third-party packages.
Thanks in advance
I have found the solution after customized Django REST Throttling,
Its Blocking particular user after 3 login attempts (Block user_id that presents in my application).
Block IP address after 6 login attempts for anonymous user.
prevent.py:-
#!/usr/bin/python
from collections import Counter
from rest_framework.throttling import SimpleRateThrottle
from django.contrib.auth.models import User
class UserLoginRateThrottle(SimpleRateThrottle):
scope = 'loginAttempts'
def get_cache_key(self, request, view):
user = User.objects.filter(username=request.data.get('username'))
ident = user[0].pk if user else self.get_ident(request)
return self.cache_format % {
'scope': self.scope,
'ident': ident
}
def allow_request(self, request, view):
"""
Implement the check to see if the request should be throttled.
On success calls `throttle_success`.
On failure calls `throttle_failure`.
"""
if self.rate is None:
return True
self.key = self.get_cache_key(request, view)
if self.key is None:
return True
self.history = self.cache.get(self.key, [])
self.now = self.timer()
while self.history and self.history[-1] <= self.now - self.duration:
self.history.pop()
if len(self.history) >= self.num_requests:
return self.throttle_failure()
if len(self.history) >= 3:
data = Counter(self.history)
for key, value in data.items():
if value == 2:
return self.throttle_failure()
return self.throttle_success(request)
def throttle_success(self, request):
"""
Inserts the current request's timestamp along with the key
into the cache.
"""
user = User.objects.filter(username=request.data.get('username'))
if user:
self.history.insert(0, user[0].id)
self.history.insert(0, self.now)
self.cache.set(self.key, self.history, self.duration)
return True
view.py:-
from .prevent import UserLoginRateThrottle
....
....
....
class ObtainAuthToken(auth_views.ObtainAuthToken):
throttle_classes = (UserLoginRateThrottle,)/use this method here your login view
def post(self, request, *args, **kwargs):
....
....
Add some parameters in setting file
settings.py:-
# Django-rest-framework
REST_FRAMEWORK = {
...
...
...
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.UserRateThrottle',
),
'DEFAULT_THROTTLE_RATES': {
'loginAttempts': '6/hr',
'user': '1000/min',
}
}

Django multiple forms on one view

I have a Django template that has data from a few different model types combining to make it. A dashboard if you will. And each of those has an edit form.
Is it best to process all those forms in one view as they are posted back to the same place and differentiating between them by a unique field like below?
Or if having lots of different dedicated avenues is the way forward? Thanks for any guidance
class ProjectDetail(DetailView):
template_name = 'project/view.html'
def get_object(self):
try:
return Project.objects.filter(brief__slug=self.kwargs['slug']).filter(team=get_user_team(self.request)).first()
# add loop to allow multiple teams to work on the same brief (project)
except Exception as e:
project_error = '%s (%s)' % (e.message, type(e))
messages.error(self.request, 'OH NO! %s' % project_error)
return redirect('home')
def get_context_data(self, **kwargs):
project = self.get_object()
context = dict()
context['project'] = project
context['milestone_form'] = MilestoneForm(initial={'project': project})
context['view'] = self
return context
def post(self, request, *args, **kwargs):
# get the context for the page
context = self.get_context_data()
try:
# switch for each of the form types on the team profile page (shown if member)
if 'milestone_form_submit' in request.POST:
project=self.get_object()
# set date arbitrarily to half way to brief deadline
brief = Brief.objects.get(project=project)
last_milestone = self.milestones().last()
milestone_del_date = last_milestone.del_date + timedelta(days=7)
new_milestone = Milestone(
project=project,
title_text=request.POST.get('title_text'),
del_date=milestone_del_date,
)
try:
new_milestone.save()
messages.success(self.request, "Excellent! New delivery popped on the bottom of the list")
except Exception as e:
# pass the erroring form back in the context if not
form = MilestoneForm(request.POST)
context['milestone_form'] = form
messages.error(self.request, "OH NO! Deadline didn't save. Be a sport and check what you entered")
elif 'milestone-edit-date-form-submit' in request.POST:
# get object from db
milestone = Milestone.objects.get(pk=request.POST['id'])
# update del_date field sent
milestone.del_date = request.POST['del_date']
# save back to db
milestone.save()
messages.success(self.request, "Updated that delivery right there!")
elif ...
except Exception as e:
messages.error(self.request, "OH NO! Deadline didn't save. Be a sport and check what you entered")
return render(request, self.template_name, context)
You can use mixins in order to solve your problem.
Example from the gist https://gist.github.com/michelts/1029336
class MultipleFormsMixin(FormMixin):
"""
A mixin that provides a way to show and handle several forms in a
request.
"""
form_classes = {} # set the form classes as a mapping
def get_form_classes(self):
return self.form_classes
def get_forms(self, form_classes):
return dict([(key, klass(**self.get_form_kwargs())) \
for key, klass in form_classes.items()])
def forms_valid(self, forms):
return super(MultipleFormsMixin, self).form_valid(forms)
def forms_invalid(self, forms):
return self.render_to_response(self.get_context_data(forms=forms))
As you can see, when you inherit from this class, you can handle multiple forms simultaneously. Look at the gist's code and adapt it to your problem.
Look at this answer

custom decorator for class viewsets

I have a view set like this
class NeProjectsViewSet(viewsets.ViewSet):
def list(self, request,org_unique_id):
''' something '''
def create(self, request,org_unique_id):
''' something '''
def retrieve(self):
''' something '''
def update(self, request, pk):
''' something '''
def partial_update(self, request):
''' something '''
def destroy(self, request):
''' something '''
and i've a method like this
def check_session(self,request):
current_datetime = datetime.now()
if ('last_login' in request.session):
last = (current_datetime - datetime.strptime(request.session['last_login'], "%Y-%m-%d %H:%M:%S.%f")).seconds
if last > base.SESSION_IDLE_TIMEOUT:
del request.session['token']
raise ValueError('Session Expired')
else:
request.session['last_login'] = str(current_datetime)
return (request.session['token'] == request.META['HTTP_AUTHORIZATION'])
to validate session for every request, for that i need to call this method before every method in the viewset. I read somewhere writing custom decorator is better way, so how to implement custom decorator for my view set to check session for request
Assuming you are using DRF.
I think you are going in wrong direction. If this is part of your permission layer you should just add custom permission class to your viewset
http://www.django-rest-framework.org/api-guide/permissions/
from rest_framework import permissions
class ValidateSession(permissions.BasePermission):
"""
Validate session expiration
"""
def has_permission(self, request, view):
current_datetime = datetime.now()
if ('last_login' in request.session):
last = (current_datetime - datetime.strptime(request.session['last_login'], "%Y-%m-%d %H:%M:%S.%f")).seconds
if last > base.SESSION_IDLE_TIMEOUT:
del request.session['token']
return False
else:
request.session['last_login'] = str(current_datetime)
return (request.session['token'] == request.META['HTTP_AUTHORIZATION'])
And then add it like this
class NeProjectsViewSet(viewsets.ViewSet):
permission_classes = (ValidateSession,)
...
Assuming you're using plain django
from django.contrib.auth.mixins import AccessMixin
class ValidateSessionMixin(AccessMixin):
"""
Validate session
"""
def has_permission(self):
current_datetime = datetime.now()
request = self.request
if ('last_login' in request.session):
last = (current_datetime - datetime.strptime(request.session['last_login'], "%Y-%m-%d %H:%M:%S.%f")).seconds
if last > base.SESSION_IDLE_TIMEOUT:
del request.session['token']
return True
else:
request.session['last_login'] = str(current_datetime)
return (request.session['token'] == request.META['HTTP_AUTHORIZATION'])
def dispatch(self, request, *args, **kwargs):
if not self.has_permission():
return self.handle_no_permission()
return super(ValidateSessionMixin, self).dispatch(request, *args, **kwargs)
And apply this mixin like this
class NeProjectsViewSet(ValidateSessionMixin, viewsets.ViewSet):
...

Python decorator to check for POST parameters on Django

I have code that read like this to check if POST parameters are included on the request:
def login(request):
required_params = frozenset(('email', 'password'))
if required_params <= frozenset(request.POST):
# 'email' and 'password' are included in the POST request
# continue as normal
pass
else:
return HttpResponseBadRequest()
When the list of required POST parameters is big, this code gets messy. What I would like to do is something like:
#required_POST_params('email', 'password')
def login(request):
# 'email' and 'password' are here always!
pass
Then I'm confident that both 'email' and 'password' POST parameters are included in the request, because if not, the request would automatically return HttpResponseBadRequest().
Is there a way that Django allows me to do this, and if it doesn't, how can I do it by myself with a decorator?
You would need a custom decorator, but you can take require_http_methods as a base example:
def require_post_params(params):
def decorator(func):
#wraps(func, assigned=available_attrs(func))
def inner(request, *args, **kwargs):
if not all(param in request.POST for param in params):
return HttpResponseBadRequest()
return func(request, *args, **kwargs)
return inner
return decorator
Example usage:
#require_post_params(params=['email', 'password'])
def login(request):
# 'email' and 'password' are here always!
pass
FYI, require_http_methods source code.
i'm sharing my solution;
__author__ = 'yagmurs'
from copy import deepcopy
from rest_framework import status
from rest_framework.response import Response
def require_params(*params):
def decorator(fn):
def wrapped_function(request, *args, **kwargs):
"""
Decorator for django rest service to meet both GET and POST request
"""
error = deepcopy(REQUEST_INVALID_400)
is_param_missing = False
for param in params:
if not get_param_from_request(param, request):
error['result_message'] += param + ", "
is_param_missing = True
if is_param_missing:
error['result_message'] = error['result_message'][:-2]
return Response(error, status=status.HTTP_400_BAD_REQUEST)
else:
return fn(request, *args, **kwargs)
return wrapped_function
return decorator
def get_param_from_request(param, request):
if request.method == 'POST':
return request.data.get(param)
else:
return request.query_params.get(param)
Try with this.
Instead of require.POST(), try with require.POST('email', 'password').

Categories

Resources