django: "'str' object has no attribute 'regex' - python

I'm building a little web server using django but I keep getting 'str' object has no attribute 'regex' in my template where it says {% url 'signup' %} and {% url 'login' %}. I guess this will be something to do with URL binding, or probably me not having imported the right module that is needed to refer to a URL by its name attribute. But I can't figure a way around this. Thanks in advance.
Template
{% include "header.html" %}
<div class="container">
<div class="page-header"><h3>로그인</h3></div>
<form method="post" action="{% url 'login' %}" role="login">
{% csrf_token %}
<div class="form-group">
<label>아이디</label>
<input type="text" name="username" placeholder="아이디를 입력하세요" class="form-control" />
</div>
<div class="form-group">
<label>비밀번호</label>
<input type="password" name="password" placeholder=" 암호를 입력하세요" class="form-control" />
<input type="hidden" name="next" value="/" />
</div>
<div class="form-group">
<div class="btn-group pull-right">
<input type="submit" value="로그인" class="btn btn-primary"/>
가입하기
</div>
</div>
</form>
</div>
{% include "footer.html" %}
Views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib.auth import logout
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from docx import Document
from exam.models import *
def login(request):
return render(request, 'login.html')
def signup(request):
try:
if request.session["error"]:
error_message = request.session["error"]
del request.session["error"]
except KeyError:
error_message = None
context = {
"error_message" : error_message
}
return render(request, "signup.html", context)
def signup_submit(request):
try:
username = request.POST["username"].strip()
password = request.POST["password"].strip()
password_confirm = request.POST["password_confirm"].strip()
full_name = request.POST["full_name"].strip()
student_num = request.POST["student_num"].strip()
if username and password and password_confirm and full_name and student_num:
user = User(username=username, full_name=full_name, student_num=student_num)
user.set_password(password)
user.save()
return redirect("index")
except KeyError:
request.session["error"] = "올바른 요청이 아닙니다."
return redirect("signup")
else:
request.session["error"] = "입력한 정보가 올바르지 않습니다."
return redirect("signup")
URLS.py
from django.conf.urls import include, url, patterns
from django.contrib import admin
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^$', 'django.contrib.auth.views.login', {'template_name': 'login.html'}, name='login'),
url(r'^signup/$', 'exam.views.signup', name='signup'),
url(r'^signup/submit/$', 'exam.views.signup_submit', name='signup_submit'),
Error Traceback:
AttributeError at /
'str' object has no attribute 'regex'
Request Method: GET
Request URL: http://192.168.56.101:8000/
Django Version: 1.7.6
Exception Type: AttributeError
Exception Value:
'str' object has no attribute 'regex'
Exception Location: /home/web/venv/lib/python3.4/site-packages/django/core/urlresolvers.py in _populate, line 282
Python Executable: /home/web/venv/bin/python

Related

Embedded authentication + LDAP user verification in Django. How to?

Intro
Django version: 1.10
Python version: 3.5.2
I'm trying to implement an authentication based on a LDAP condition and I can't get my head around on how to achieve this.
My project already uses Django's built-in authentication system, which works great and looks like this:
# urls.py
from django.conf.urls import include, url
from django.contrib import admin
from django.contrib.auth import views
from coffee_app.forms import LoginForm
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'', include('coffee_app.urls')),
url(r'^login/$', views.login, {'template_name': 'login.html', 'authentication_form': LoginForm}, name='login'),
url(r'^logout/$', views.logout, {'next_page': '/login'}, name='logout'),
]
# forms.py
from django.contrib.auth.forms import AuthenticationForm
from django import forms
class LoginForm(AuthenticationForm):
username = forms.CharField(label="Username", max_length=32,
widget=forms.TextInput(attrs={
'class': 'form-control',
'name': 'username'
}))
password = forms.CharField(label="Password", max_length=20,
widget=forms.PasswordInput(attrs={
'class': 'form-control',
'name': 'password'
}))
<!--login.html (relevant part)-->
<form class="form-horizontal" action="{% url 'login' %}" method="post" id="contact_form">
{% csrf_token %}
<fieldset>
<div class="form-group">
<label class="col-md-4 control-label">{{ form.username.label_tag }}</label>
<div class="col-md-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
{{ form.username }}
</div>
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label" >{{ form.password.label_tag }}</label>
<div class="col-md-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
{{ form.password }}
</div>
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label"></label>
<div class="col-md-4 text-center">
<br>
<button value="login" type="submit" class="btn btn-warning" >
LOG IN
<span class="glyphicon glyphicon-send"></span>
</button>
</div>
</div>
</fieldset>
<input type="hidden" name="next" value="{{ next }}"/>
</form>
Problem
Now, what I'm trying to do, is to verify whether a user exists in LDAP or not, before getting to the initial Django auth:
from ldap3 import Server, Connection, ALL, NTLM
server = Server('server here', get_info=ALL, use_ssl=True)
conn = Connection(server,
user='DOMAIN\\username',
password='password',
authentication=NTLM)
print(conn.bind())
If conn.bind() returns True, I'd like to go further to Django's built-in authentication system and authenticate the user. Unfortunately, I don't know where / how to add this step in order to achieve this.
Some views look like this:
from django.shortcuts import render
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
#login_required(login_url="login/")
def home(request):
return render(request, "home.html")
#login_required(login_url="login/")
def activity_report_page(request):
return render(request, "activity_report.html")
...
And their urls:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'report$', views.activity_report_page, name='activity_report')
]
Could someone please point out where should I add the LDAP piece of code so that I can first verify if a user exist there?
PS: I didn't consider using django-auth-ldap because I don't really need a pure LDAP authentication-based system. Just a simple verification.
You want to customize authentication in Django, where you more specifically want to write an authentication backend. I assume that your project is called 'coffee_site', and you have the app 'coffee_app'. You first want to change coffee_site/settings.py, and append AUTHENTICATION_BACKENDS = ['coffee_site.auth.LDAP'] to it. After this, you want to make and edit coffee_site/auth.py. As you said in the question you want to use the default authentication, and so you should inherit from django.contrib.auth.backends.ModelBackend, you then want to make it so that if conn.bind() is not True, then you don't use the default authentication, and so you should return None. This can be implemented with:
from django.contrib.auth.backends import ModelBackend
from ldap3 import Server, Connection, ALL, NTLM
server = Server('server here', get_info=ALL, use_ssl=True)
class LDAP(ModelBackend):
def authenticate(self, *args, **kwargs):
username = kwargs.get('username')
password = kwargs.get('password')
if username is None or password is None:
return None
conn = Connection(server,
user='DOMAIN\\{}'.format(username),
password=password,
authentication=NTLM)
if not conn.bind():
return None
return super().authenticate(*args, **kwargs)
Note: I checked this works on Django's side, but I made no effort to check that the LDAP code works.

CSRF verification failed. Request aborted. Python 1.8

Good Afternoon,
I am new to django, I am creating a Login Portal, but i get the following error | CSRF verification failed. Request aborted.
I am using Django 1.8 and Python 3.4 please help me, If you need anything else please let me know
here is my views.py:
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import login, authenticate, logout
from django.contrib.auth.decorators import login_required
from django.shortcuts import render_to_response
from django.template import RequestContext
def nuevo_usuario(request):
if request.method == 'POST':
formulario = UserCreationForm(request.POST)
if formulario.is_valid():
formulario.save()
return HttpResponseRedirect('/')
else:
formulario = UserCreationForm()
return render_to_response('registration/nuevo_usuario.html', {'formulario':formulario}, context_instance = RequestContext(request))
def ingresar(request):
if request.method == 'POST':
formulario = AuthenticationForm(request.POST)
if formulario.is_valid():
usuario = request.POST['username']
clave = request.POST['password']
acceso = authenticate(username=usuario, password=clave)
if acceso is not None:
if acceso.is_active:
login(request, acceso)
return HttpResponseRedirect('/privado')
else:
return render_to_response('registration/noactivo.html', context_instance = RequestContext(request))
else:
return render_to_response('registration/nousuario.html', context_instance = RequestContext(request))
else:
formulario = AuthenticationForm()
return render_to_response('registration/ingresar.html', {'formulario':formulario}, context_instance = RequestContext(request))
Este es mi archivo ingresar.html
{% extends 'base.html' %}
{% block titulo %}Ingresa al sistema{% endblock %}
{% block encabezado %}
Ingresa
{% endblock %}
{% block content %}
<div class="main">
<div class="login-form">
<h1> C. Monitoring Center</h1>
<div class="head">
</div>
<form id = 'formulario' method = 'post' action = ''> {% csrf_token %}
<input type="text" class="text" placeholder="Username" required autofocus>
<input type="password" placeholder="Password" required>
<div class="submit">
<input type="submit" onclick="#" value="LOGIN" >
</div>
<p>Forgot Password ?</p>
</form>
</div>
{% endblock %}
Este es mi archivo url.py
"""centinell URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.8/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Add an import: from blog import urls as blog_urls
2. Add a URL to urlpatterns: url(r'^blog/', include(blog_urls))
"""
from django.conf.urls import include, url
from django.contrib import admin
from login.views import *
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^$','login.views.ingresar'),
url(r'^usuario/nuevo$', 'login.views.nuevo_usuario'),
url(r'^ingresar/$', 'login.views.ingresar'),
]
you need a csrf token that django provides ... (necesitas la clave csrf q django tiene incluido)
<form id = 'formulario' method = 'post' action = ''> {% csrf_token %}
<input type="text" class="text" placeholder="Username" required autofocus>
<input type="password" placeholder="Password" required>
<div class="submit">
<input type="submit" onclick="#" value="LOGIN" >
</div>
{% csrf_token %} <!-- THIS!!!!! Aqui !!!-->
<p>Forgot Password ?</p>
</form>
or if you want you can just disable csrf protections (o si quierres se puede apagar los protejos de csrf)
#csrf_exempt # you need to import from django.contrib.auth
def ingresar(request):

What should return when using CSRF tokens with class-based views?

Forbidden (403) CSRF verification failed.
Request aborted. Reason given for failure: CSRF cookie not set.
I get the above error and there are a few solutions out there, but not for class-based views. What should def get_context_data(self, **kwargs): be returning? Below the message, it suggests 4 solutions, and the following suggestion catches my attention. So perhaps I should be returning a RequestContext somehow?
The view function uses RequestContext for the template, instead of Context.
I'm already using {% csrf_token %}, cookies are enabled and I have it included in the middleware. So I think I may be returning the wrong thing but all the other examples around here use function views.
My template snippet:
{% if not user.is_authenticated %}
<form id="login" method="post" action="login">{% csrf_token %}
<input type="text" name="username" value="" placeholder="Email">
<input type="password" name="password" value="" placeholder="Password">
<input type="submit" name="commit" value="Login">
</form>
{% elif user.is_authenticated %}
<p>Welcome, {{ user.get_displayname }}.</p>
{% endif %}
My urls.py:
from django.conf.urls import patterns, include, url
from mainapp.views import Index, LoginResponse
from django.contrib import admin
admin.autodiscover()
from mainapp import views
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^$', Index.as_view()),
url(r'^login$', LoginResponse.as_view()),
)
My LoginResponse class view:
class LoginResponse(TemplateView):
template_name = 'index.html'
def get_context_data(self, **kwargs):
context = super(LoginResponse, self).get_context_data(**kwargs)
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
return context
For CSRF verification there is no difference between function based and class based views. This verification is done at middleware level.
So show your template and urls.py please.

Django Model form don't update database records

I am new in django and I want to create a form to update some database entries.
this is a simple form where I have a simple input text where I write the id of the record that I want to update:
main.html
<form method='post' action='/config/{{ idprov }}' >
<input type="text" class="form-control" name="idprov" id="idprov" value ="{{ idprov }}" />
<input class="btn btn-danger" type="submit" value="Config">
</form>
forms.py
from django import forms
from .models import Proveedor, Estado, Config
class ConfigForm(forms.ModelForm):
class Meta:
model = Config
this is my views.py:
def configView(request,idprov):
prov = Config.objects.get(idproveedor=idprov)
if request.method == 'POST':
form = ConfigForm(request.POST or None, instance=prov)
if form.is_valid():
form.save(commit=false)
return HttpResponseRedirect('/monitor/')
else:
form = ConfigForm( instance=prov)
return render_to_response('config.html',
{'form':form})
my template config.html:
{% extends 'base.html' %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-md-4">
<form method='POST' action='' >
<div class="form-group">{% csrf_token %}
{{ form.as_p }}
</div>
<button type='submit' class="btn btn-primary">Grabar</button>
</form>
</div>
</div>
</div>
{% endblock %}
my urls.py:
from django.conf.urls import patterns, include, url
from prov.views import home
from prov.views import proveedores
from prov.views import estado
from prov.views import monitorViewV2
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Examples:
url(r'^$', 'prov.views.home', name='home'),
url(r'^proveedores/$', 'prov.views.proveedores', name='proveedor'),
url(r'^estado/$', 'prov.views.estado', name='estado'),
url(r'^monitor/$', 'prov.views.monitorView', name='monitor'),
url(r'^monitorv/$', 'prov.views.monitorViewV2', name='monitorv2'),
url(r'^config/(?P<idprov>\d+)/$', 'prov.views.configView',name='config'),
url(r'^admin/', include(admin.site.urls)),
)
But I receive the error Page not found.
I try to follow other snippets and always raise different errors.
I think the error is in the urls.py and in the way I pass the argument from the main.html.
Any advice or snippet will be very appreciated
Thanks in advance
First you have a form.save(commit=false) in your view without saving it later, thats mean the data is never saved into the model.
Second in your template config.html the form action is empty <form method='POST' action=''> change for <form method='POST' action='.'>
I hope that help to you.

Django render_to_response not working as expected

Django 1.5 - django-ldap-auth
Trying to figure out how to properly using request_to_context as it only works on the login.html page itself. (user.is_authenticated etc).
After the user gets logged in, it forwards the user to /reboot. From there I want to use {{ user.is_authenticated }} / {{ user.username }}, but nothing shows up(true or false). It is just blank.
On the login.html page itself they work correctly. If I render to the reboot/index.html it does not render the code that I have the index do. I assumed I would be able to call these commands after a user is authenticated. Hopefully I am just missing a small piece to this puzzle.
I have included all of the necessary code. Let me know if you need something else.
Here is my layout.
reboot/form.py
from django import forms
from django.contrib.auth.models import User
from django.forms import ModelForm
class LoginForm(forms.Form):
username = forms.CharField(label=(u'User Name'))
password = forms.CharField(label=(u'Password'), widget=forms.PasswordInput(render_value=False))
views.py
from django.template import Context, loader, RequestContext
from django.shortcuts import render_to_response
from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User
from django.http import HttpResponse, HttpResponseRedirect
from servers.models import Server
from reboot.forms import LoginForm
import paramiko
import socket
def logout_user(request):
logout(request)
return HttpResponseRedirect('/status/')
def index(request):
t = loader.get_template('reboot/index.html')
servers = Server.objects.all()
c = Context( {
'servers': servers,
})
return HttpResponse(t.render(c))
def test_ssh_liveness(ssh, name):
try:
ssh.connect(name, timeout='1')
return True
except socket.timeout:
# server is down
return False
except socket.gaierror:
# invalid server name
return False
except paramiko.SSHException:
# unknown host key
return True
def server(request, name):
ssh = paramiko.SSHClient()
is_alive = test_ssh_liveness(ssh, name)
return HttpResponse("You selected server "+name+" and it is "+str(is_alive))
# user login
def login_user(request):
if request.user.is_authenticated():
# return HttpResponseRedirect('/reboot/')
pass
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return HttpResponseRedirect('/reboot/')
else:
return render_to_response('login.html', {'form', form}, context_instance=RequestContext(request))
else:
''' user is not submitting the form, show the login form '''
form = LoginForm()
context = {'form': form}
return render_to_response('login.html', context, context_instance=RequestContext(request))
reboot.urls
from django.conf.urls import patterns, url
from reboot import views
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
#(r'^$', views.login_user),
url(r'^server/(?P<name>[^/]+)', views.server, name='server')
)
main url file
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^reboot/', include('reboot.urls')),
# Login for reboot
(r'^login/$', 'reboot.views.login_user'),
(r'^logout/$', 'reboot.views.logout_user'),
url(r'^status/', include('status.urls')),
)
login.html
% extends "base.html" %}
{% block content %}
<p> print {{ user.is_authenticated }}</p>
<div id="login">
<form class="form-horizontal" name="LoginForm" action="/login/" method="post">
{% csrf_token %}
{% if next %}
<input type="hidden" name="next" value="{{ next }}" />
{% endif %}
<div class="control-group">
<label class="control-label" for="username">Username</label>
<div class="controls">
<input type="text" id="username" name="username" placeholder="Username">
</div>
</div>
<div class="control-group">
<label class="control-label" for="password">Password</label>
<div class="controls">
<input type="password" name="password" id="password" placeholder="Password">
</div>
</div>
<div class="control-group">
<div class=controls">
<button type="submit" class="btn">Login</button>
</div>
</div>
</form>
</div>
{% endblock %}
/reboot/index.html
{% extends "base.html" %}
{% block title %}Server{% endblock %}
{% block content %}
<h2>Server Control Panel</h2>
<h4>Welcome, print {{ user.is_authenticated }}.</h4>
{% if user.is_authenticated %}<p>Logout</p>{% else %}Login</p>{% endif %}
<p class="lead">
The servers below correspond to servers that you have access to.
If you believe there are errors, please contact me.
</p>
<div class="container-fluid">
<table class="table table-hover">
<thead>
<tr>
<th><h4>Hostname</h4></th>
<th><h4>Commands</h4></th>
</tr>
</thead>
<tbody>
{% for server in servers %}
<tr>
<td>{{ server.hostname }}</td>
<td>
start
restart
shutdown
</td>
</tr>
{% endfor %}
</tbody>
</table>
</table>
</div>
{% endblock %}
I appreciate all of your help. I have been stuck on this issue for a few days now and have not been able to figure it out.
John
Your view needs a RequestContext instance (docs), like your login view, so it knows which user is logged in (and other stuff). So instead of:
def index(request):
t = loader.get_template('reboot/index.html')
servers = Server.objects.all()
c = Context( {
'servers': servers,
})
return HttpResponse(t.render(c))
just make it:
def index(request):
servers = Server.objects.all()
context = {
'servers': servers,
}
return render_to_response('reboot/index.html', context, context_instance=RequestContext(request))
EDIT
It's not really about the render_to_response. As the import says, that's just a shortcut.
Django's context processors (basically, functions that add variables to your template context) are request-based, and therefor are only called if you specify a RequestContext, and that includes django.contrib.auth.context_processors.auth, the context processor that includes the user variable into your template.
The equivalent of your code would be:
def index(request):
t = loader.get_template('reboot/index.html')
servers = Server.objects.all()
c = RequestContext(request, {
'servers': servers,
})
return HttpResponse(t.render(c))

Categories

Resources