django_debug_toolbar and Docker - django

So I got docker and Django to work locally, first by building an image from a Dockerfile, then using Fig to get postgres image, link it to the base image, and run the localserver. Everything works just fine, except for django_debug_toolbar. For some reason it just won't show up. Have the dockerhost ip as well in the internal_ips.
Can anyone help me out with it? Docker is running on mac via boot2docker.
Thanks!
My settings:
init.py
import os
if 'DEBUG' not in os.environ or not os.environ['DEBUG']:
from .local import *
else:
pass
base.py
""" common and global settings """
from sys import path
from os import environ
from os.path import abspath, basename, dirname, join, normpath
from django.core.exceptions import ImproperlyConfigured
import dj_database_url
def get_env_variable(var_name):
try:
return environ[var_name]
except KeyError:
error_msg = "Set the environment variable" % var_name
raise ImproperlyConfigured(error_msg)
# Paths
DJANGO_ROOT = dirname(dirname(abspath(__file__)))
SITE_ROOT = dirname(DJANGO_ROOT)
SITE_NAME = basename(DJANGO_ROOT)
# End Paths
# URLs
MEDIA_ROOT = normpath(join(SITE_ROOT, 'media'))
MEDIA_URL = "/media/"
STATIC_ROOT = normpath(join(SITE_ROOT, 'assets'))
STATIC_URL = "/static/"
STATICFILES_DIRS = (
normpath(join(SITE_ROOT, 'static')),
)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
ROOT_URLCONF = '%s.urls' % SITE_NAME
path.insert(0, join(DJANGO_ROOT, 'apps')) # add apps folder to system path
# End URLs
# Database
# example: postgres://joris:luna#localhost/bitbybit
DATABASES = {'default': dj_database_url.config(
default='postgres://postgres#db:5432/postgres')}
# End Database
# Templates
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'django.core.context_processors.static',
'django.core.context_processors.tz',
'django.contrib.messages.context_processors.messages',
'django.core.context_processors.request',
)
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
TEMPLATE_DIRS = (
normpath(join(SITE_ROOT, 'templates')),
)
# End Templates
# SECURITY WARNING: keep the secret key used in production secret!
# make it unique and store it as an environment variable
SECRET_KEY = r"d%g7_h6cz=xbhs*5-i+e$c7mns*s)^_+#^8n#^-2dno#uie-z9"
# Application
DJANGO_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
)
LOCAL_APPS = (
'home',
)
INSTALLED_APPS = DJANGO_APPS + LOCAL_APPS
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'debug_toolbar.middleware.DebugToolbarMiddleware',
)
WSGI_APPLICATION = '%s.wsgi.application' % SITE_NAME
# End Application
# Internationalization
LANGAUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# End Internationalization
Local.py
from .base import *
# Debug config
DEBUG = True
TEMPLATE_DEBUG = DEBUG
# End Debug config
# Hosts
ALLOWED_HOSTS = ['127.0.0.1', 'localhost']
# End Hosts
# Django Debug Toolbar config
INSTALLED_APPS += (
'debug_toolbar', )
INTERNAL_IPS = ('127.0.0.1', 'localhost')
# End Django Debug Toolbar config

Using the configuration SHOW_TOOLBAR_CALLBACK woked for me
def show_toolbar(request):
return True
DEBUG_TOOLBAR_CONFIG = {
'SHOW_TOOLBAR_CALLBACK': show_toolbar,
}
I hope that helped :)

If you would like to do this programatically and not copy/pasting your container IP, I'd suggest you do like the django-cookiecutter folks. In your local settings file:
INTERNAL_IPS = ['127.0.0.1', ]
import socket
# tricks to have debug toolbar when developing with docker
ip = socket.gethostbyname(socket.gethostname())
INTERNAL_IPS += [ip[:-1] + '1']
For reference, this is the link to the django-cookiecutter local.py settings file.

You could just make INTERNAL_IPS an object which contains everything. This is what I do:
if DEBUG:
# `debug` is only True in templates if the vistor IP is in INTERNAL_IPS.
INTERNAL_IPS = type(str('c'), (), {'__contains__': lambda *a: True})()
Of course you should never do this on a production host!
Explanation:
The type function (three arguments variant: https://docs.python.org/3/library/functions.html#type) creates a new class which in this case only has a __contains__ method (https://docs.python.org/3/reference/datamodel.html#object.contains) -- contains is used to implement membership tests, meaning that this method is called when running e.g. "if ip in INTERNAL_IPS". The contains method itself would probably be clearer if written as "def __contains__(self):\n return True". The newly created class is immediately instantiated (the final "()") and assigned to INTERNAL_IPS

An IP address that allowed me to display Django Debug Toolbar was, the Gateway IP of my docker container (container that runs Django app).
To obtain IP address of the gateway run this command.
# replace django_container_name with your container name!
docker inspect django_container_name | grep -e '"Gateway"'
# "Gateway": "172.18.0.1",
Next, add this Getway IP to settings.py -so your configuration might look like the one below.
INSTALLED_APPS = (
...
'debug_toolbar',
...
)
MIDDLEWARE = [
...
'debug_toolbar.middleware.DebugToolbarMiddleware',
...
]
INTERNAL_IPS = ['172.18.0.1']
And of course add __debug__ to urls.py
import debug_toolbar
from django.conf import settings
from django.urls import include, path
urlpatterns = [
...
path('__debug__/', include(debug_toolbar.urls)),
]
Just follow djdt installation guide!

Using the accepted answer at https://unix.stackexchange.com/questions/87468/is-there-an-easy-way-to-programmatically-extract-ip-address I was able to get this to work by passing the address of the host's Docker bridge to the docker run command as an environment variable:
-e "DOCKER_HOST=$(ip -4 addr show docker0 | grep -Po 'inet \K[\d.]+')"
With that set, the following two lines in settings.py detected it and allowed the host to see the toolbar:
if "DOCKER_HOST" in os.environ:
INTERNAL_IPS = [os.environ["DOCKER_HOST"]]

Solved. Checked the value for REMOTE_ADDR in request headers and added that to INTERNAL_IPS.

As people have mentioned, you can use a callback to determine if the debug toolbar should appear or not. I use this together with an environment variable passed in via docker-compose.
settings.py
def show_toolbar_callback(*args, **kwargs):
if os.getenv("LOCAL_DEV"):
return True
return False
DEBUG_TOOLBAR_CONFIG = {"SHOW_TOOLBAR_CALLBACK": show_toolbar_callback}
docker-compose.yaml
services:
django:
container_name: "django"
build: "./"
ports:
- "8000:8000"
volumes:
- ".:/opt/service"
environment:
LOCAL_DEV: "true"
depends_on:
- "db"

Here's a hacky way that doesn't require injecting the address into the container. I'm not sure how it would work if your container is connected to multiple networks and could break if docker changed the way they assign addresses (though that doesn't seem likely).
import subprocess
route = subprocess.Popen(('ip', 'route'), stdout=subprocess.PIPE)
network = subprocess.check_output(
('grep', '-Po', 'src \K[\d.]+\.'), stdin=route.stdout).decode().rstrip()
route.wait()
network_gateway = network + '1'
INTERNAL_IPS = [network_gateway]

1- run this command in the directory docker-compose or Dockerfile and get NETWORK ID:
sudo docker network list
and view list all network
NETWORK ID NAME DRIVER SCOPE
556e2e7123er admin_default bridge local
aq3033sc09c1 bridge bridge local
1983cf1x2cb9 cockroach bridge local
0cc1be23b543 flask bridge local
2- run this command:
ip addr
.
.
8: br-556e2e7123er: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether **:**:**:**:**:** brd ff:ff:ff:ff:ff:ff
inet 162.21.0.1/16 brd 172.22.255.255 scope global br-556e2e7123er
valid_lft forever preferred_lft forever
.
.
3- get your IP
NETWORK ID : 556e2e7123er == 8: br-556e2e7123er => ip 162.21.0.1
4- add ip to INTERNAL_IPS = [..., 162.21.0.1, ...]
‍‍‍‍‍‍‍‍‍‍

The trick is to use gethostbyname_ex instead of gethostbyname method
INTERNAL_IPS = ['127.0.0.1', ]
if DEBUG:
import socket
hostname, _, ips =socket.gethostbyname_ex(socket.gethostname())
INTERNAL_IPS += [ip[:-1] + '1' for ip in ips]

Related

"Django_celery_beat" executes task only once

I am trying to integrate django_celery_beat in project.
When I setup task using django admin panel, entries in database are reflected correctly and when I start project task gets executed successfully. however on every successive attempt of sending task after first execution is rather failed or either message is not sent to broker.
My setup :
django_celery_beat : 1.0.1
celery: 4.0.1
Setting in celeryconfig:
CELERY_ENABLE_UTC = True
BROKER_URL = 'amqp://guest:guest#localhost:5672//'
CELERYBEAT_SCHEDULER = 'django_celery_beat.schedulers.DatabaseScheduler'
settings.py
# -*- coding: utf-8 -*-
import os
import tempfile
import time
from buy import constants as buy_constants
PROJECT_ROOT = os.path.realpath(os.path.dirname(__file__))
# CSRF_COOKIE_SECURE = True
# SESSION_COOKIE_SECURE = True
ADMIN_SITE_ENABLED = False
WAIT_BETWEEN_RATING = 7 # In days
WAIT_BETWEEN_EMAIL_VERIFY = 30 # In minutes
WAIT_BETWEEN_RECOMMENDATIONS = 1 # In minutes
WAIT_BETWEEN_CONNECTION_UPDATE = 60*24*5 # In minutes
SITEMAP_CACHE = 86400
DEBUG = False
TEMPLATE_DEBUG = DEBUG
ADMINS = (('Pooja Shete', 'pooja.shete#gmail.com'),)
MANAGERS = ADMINS
DATABASES = {}
# Hosts/domain names that are valid for this site; required if DEBUG is False
ALLOWED_HOSTS = ['*']
# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# In a Windows environment this must be set to your system time zone.
TIME_ZONE = 'America/Chicago'
# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en'
SITE_ID = 1
# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True
# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale.
USE_L10N = True
# If you set this to False, Django will not use timezone-aware datetimes.
USE_TZ = True
# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/var/www/example.com/media/"
MEDIA_ROOT = os.path.join(PROJECT_ROOT, 'media')
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://example.com/media/", "http://media.example.com/"
MEDIA_URL = '/media/'
# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/var/www/example.com/static/"
# URL prefix for static files.
# Example: "http://example.com/static/", "http://static.example.com/"
STATIC_URL = '/static/'
# Additional locations of static files
STATICFILES_DIRS = (
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
os.path.join(PROJECT_ROOT, "static"),
)
# List of finder classes that know how to find static files in
# various locations.
STATICFILES_STORAGE = 'require.storage.OptimizedCachedStaticFilesStorage'
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
'pipeline.finders.PipelineFinder',
'pipeline.finders.CachedFileFinder',
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
# Make this unique, and don't share it with anybody.
SECRET_KEY = 'c28yui+jyipz5prse%!o^u_e06$!*_daps8b9+km_aa51f=i%='
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
# 'django.template.loaders.eggs.Loader',
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django_user_agents.middleware.UserAgentMiddleware',
'django.middleware.security.SecurityMiddleware',
'logs.middleware.ContextMiddleware',
'middleware.locale.LocaleMiddleware',
# Uncomment the next line for simple clickjacking protection:
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
DJANGO_CONTEXT_LOGGING_EXTRACTOR = lambda request: {}
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
'PAGINATE_BY': 10
}
# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'app.wsgi.application'
TEMPLATE_DIRS = (
os.path.join(os.path.dirname(__file__), '..', 'templates').replace('\\','/'),
os.path.join(PROJECT_ROOT, 'templates'),
)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.humanize',
'django.contrib.sitemaps',
'django.contrib.admin',
'django.contrib.admindocs',
'billing',
'django_user_agents',
'pipeline',
'celery',
'django_celery_beat',
)
SITE_ID = 1
import django.db.models.options as options
options.DEFAULT_NAMES = options.DEFAULT_NAMES + ('db_name',)
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer'
CELERYBEAT_SCHEDULER = 'django_celery_beat.schedulers.DatabaseScheduler'
TEMPLATE_CONTEXT_PROCESSORS = ('django.core.context_processors.request',"django.contrib.auth.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"django.core.context_processors.static",
"django.core.context_processors.tz",
"django.contrib.messages.context_processors.messages",
"django.core.context_processors.csrf",
)
PIPELINE_DISABLE_WRAPPER = True
PIPELINE_COMPILERS = (
'pipeline.compilers.sass.SASSCompiler',
)
PIPELINE_YUGLIFY_BINARY = '/usr/local/bin/yuglify'
PIPELINE_JS_COMPRESSOR = 'pipeline.compressors.uglifyjs.UglifyJSCompressor'
PIPELINE_CLOSURE_ARGUMENTS = '--compilation_level=WHITESPACE_ONLY'
PIPELINE_CSS_COMPRESSOR = 'pipeline.compressors.yui.YUICompressor'
CACHES = {}
# Change this value in local_config as per requirement to use dummy paypal
DUMMY_PAYPAL = False
# Initialize cached object
##############################
try:
INITIALIZE_FILE_CACHE
except NameError:
try:
from django.core.cache import get_cache
cache = get_cache('redis_cache')
try:
wp = cache.get('word_parser', None)
except:
wp = None
if not wp:
from bin.cron.wordparser import WordParser
wp = WordParser()
cache.set('word_parser', wp, timeout=None)
except ImportError:
pass
gettext = lambda s: s
LANGUAGES = (
('en', gettext('English')),
('fr', gettext('French')),
('es', gettext('Spanish')),
('ja_JP', gettext('Japanese')),
)
PROJECT_PATH = os.path.dirname(os.path.abspath(__file__))
LOCALE_PATHS = (
os.path.join(PROJECT_PATH, '../locale'),
)
Command used to start celerybeat:
celery beat -A app-S django_celery_beat.schedulers.DatabaseScheduler --loglevel=INFO
command used to start workers :
celery worker -A app--loglevel=INFO
When I start celery I do get exception of :
Traceback (most recent call last):
File "/usr/local/lib/python3.4/dist-packages/celery/worker/pidbox.py", line 42, in on_message
self.node.handle_message(body, message)
File "/usr/local/lib/python3.4/dist-packages/kombu/pidbox.py", line 129, in handle_message
return self.dispatch(**body)
File "/usr/local/lib/python3.4/dist-packages/kombu/pidbox.py", line 112, in dispatch
ticket=ticket)
File "/usr/local/lib/python3.4/dist-packages/kombu/pidbox.py", line 135, in reply
serializer=self.mailbox.serializer)
File "/usr/local/lib/python3.4/dist-packages/kombu/pidbox.py", line 265, in _publish_reply
**opts
File "/usr/local/lib/python3.4/dist-packages/kombu/messaging.py", line 181, in publish
exchange_name, declare,
File "/usr/local/lib/python3.4/dist-packages/kombu/messaging.py", line 203, in _publish
mandatory=mandatory, immediate=immediate,
File "/usr/local/lib/python3.4/dist-packages/amqp/channel.py", line 1748, in _basic_publish
(0, exchange, routing_key, mandatory, immediate), msg
File "/usr/local/lib/python3.4/dist-packages/amqp/abstract_channel.py", line 64, in send_method
conn.frame_writer(1, self.channel_id, sig, args, content)
File "/usr/local/lib/python3.4/dist-packages/amqp/method_framing.py", line 174, in write_frame
write(view[:offset])
File "/usr/local/lib/python3.4/dist-packages/amqp/transport.py", line 269, in write
self._write(s)
BrokenPipeError: [Errno 32] Broken pipe
Logs in beat.stderr.log:
[2017-06-12 05:40:00,002: INFO/MainProcess] Scheduler: Sending due task pooja_task (app.tasks.send_test_mail)
[2017-06-12 05:41:00,002: INFO/MainProcess] Scheduler: Sending due task pooja_task (app.tasks.send_test_mail)
[2017-06-12 05:41:00,002: INFO/MainProcess] Scheduler: Sending due task pooja_task (app.tasks.send_test_mail)
However from all above task sent, celery picks only first task and execute whenever I start by server. All other messages are avoided.
Can anyone please help me with this.

Django-xmpp -Ejabberd Integration

I have created a django-rest project so that a user can register using email and subsequently user can activate the account using email link. The user authentication for rest server is working fine.
However, I want to create a ejabberd server for an instant messaging apps. I want to use external authentication method in ejabberd so that ejabberd can use the django project data.
Hence as per the guide line in Django-xmpp I am trying the following.
I have change the lines in ejabberd.cfg as
{auth_method, external}.
{extauth_program, "/home/...../ejabberd_auth.sh"}.
After that I have created a file name ejabberd_auth.sh which contains the following
#!/bin/bash
cd /home/------/src #(my django-rest project folder/location of manage.py)
python manage.py ejabberd_auth $#
Then I changed the setting.py in my django project. The settings file looks like
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '-------'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
TEMPLATE_DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.staticfiles',
# Rest Framework app
'rest_framework',
'rest_framework.authtoken',
# Internal Apps
'data',
'django_gravatar',
'xmpp',
)
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
'rest_framework.permissions.DjangoModelPermissions'
)
}
ROOT_URLCONF = 'ndMyFirst.urls'
WSGI_APPLICATION = 'ndMyFirst.wsgi.application'
XMPP_DOMAIN = 'localhost'
XMPP_BOSH_SERVICE_URL = 'localhost:5280/http-bind'
# Database
# https://docs.djangoproject.com/en/1.6/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Internationalization
# https://docs.djangoproject.com/en/1.6/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.6/howto/static-files/
STATIC_URL = '/static/'`
Then I started ejabberd server. When I am trying to login in 127.0.0.1:5280/admin unauthorized response received. I have also tried to register a user using ejabberdctl register admin localhost password and not allowed message received.
I do not have any idea the external authentication works.
What should I do so that the external authentication works.

Django Models save() works on localhost, but not on a remote server

I'm working on a very basic Django app in hopes of teaching myself the framework, and I've hit a small snag. The app is intended to take user input, store it in a mysqlite database, and display the contents of the database on receiving a request. I have everything working properly when the app is run locally (manage.py runserver), however it's misbehaving once it's deployed. For some reason, the storage logic is malfunctioning on the live site (Windows Server 2012 via MS Azure).
Here is the code in question:
from django.http import HttpResponse
from django.shortcuts import render
from django.shortcuts import render_to_response
from helloworld.models import Registry
def home(request):
return render_to_response("home.html")
def register(request):
return render_to_response("register.html")
def view(request):
entries = Registry.objects.all()
args = {}
args["entries"] = entries
return render_to_response("registry.html", args)
def submit(request):
nameIn = request.GET.get('name')
ageIn = request.GET.get('age')
monthIn = request.GET.get('month')
try:
Registry(name=nameIn, age=ageIn, month=monthIn).save()
except:
pass
return view(request)
I've done a fair amount of debugging, and tried several approaches to storing the data. I've checked that the method is receiving valid values. I can't, for the life of me, figure out why that call to save() is throwing an error. Hopefully it will be obvious to one of you Django-pros! THanks in advance, any help will be greatly appreciated! P.s. I'm attaching my settings file, as i have a sneaking suspicion that poor configuration is the source of my troubles.
"""
Django settings for cny_solar project.
For more information on this file, see
https://docs.djangoproject.com/en/1.7/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.7/ref/settings/
"""
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 's7xv#m=5h=mjrdg_7-$=7kr8kx4np9$#6qzlg+m4xt&6-#-zi2'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
TEMPLATE_DEBUG = True
ALLOWED_HOSTS=['127.0.0.1','localhost']
# Application definition
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'helloworld',
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
ROOT_URLCONF = 'helloworld.urls'
WSGI_APPLICATION = 'helloworld.wsgi.application'
TEMPLATE_DIRS = (
os.path.join(BASE_DIR, 'templates'),
)
# Database
# https://docs.djangoproject.com/en/1.7/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Internationalization
# https://docs.djangoproject.com/en/1.7/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.7/howto/static-files/
STATIC_ROOT = BASE_DIR
STATIC_URL = '/static/'
STATICFILES_DIRS = (
('assets', os.path.join(BASE_DIR, 'static')),
)

How to achieve LDAP authentication in Django, How to access User object in View?

I want to build a site using Django wherein to enter it, the users have to authenticate themselves through LDAP server.
I have read the python-ldap configuration and configured settings.py accordingly. I'm able to authenticate a user from local database, but when I try to do it through LDAP, it doesn't work.
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
TEMPLATE_DIRS = [os.path.join(BASE_DIR,'templates')]
import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfNamesType
# Baseline configuration.
AUTH_LDAP_SERVER_URI = "ldap://10.1.10.10"
AUTH_LDAP_CONNECTION_OPTIONS = {
ldap.OPT_REFERRALS: 0
}
AUTH_LDAP_BIND_DN = "cn=myname,dc=example,dc=com"
AUTH_LDAP_BIND_PASSWORD = "dontevenask"
AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=users,dc=example,dc=com",
ldap.SCOPE_SUBTREE, "(uid=%(user)s)")
#AUTH_LDAP_USER_DN_TEMPLATE = "uid=%(user)s,ou=users,dc=example,dc=com"
AUTH_LDAP_USER_ATTR_MAP = {
"first_name": "givenName",
"last_name": "sn",
"email": "mail"
}
AUTH_LDAP_ALWAYS_UPDATE_USER = True
AUTH_LDAP_FIND_GROUP_PERMS = True
AUTHENTICATION_BACKENDS = (
'django_auth_ldap.backend.LDAPBackend',
'django.contrib.auth.backends.ModelBackend',
)
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '^eh5xdkui7vw!^x&l%q44ak6+yglnx5q(tqwd8l+w!sxml7q!&'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
TEMPLATE_DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'my_app',
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
ROOT_URLCONF = 'users.urls'
WSGI_APPLICATION = 'users.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.7/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'OPTIONS':{
'read_default_file':'/home/user/config.cnf',
},
}
}
# Internationalization
# https://docs.djangoproject.com/en/1.7/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.7/howto/static-files/
STATIC_URL = '/static/'
Here is my views.py file
def loggedin(request):
uid = request.user.username
return render_to_response('loggedin.html',
{'full_name':uid})
And the loggedin.html file
{% block content %}
<h2> Hi {{full_name}} Logged in! </h2>
<p> Click here to logout </p>
{% endblock %}
I did refer to other posts but didn't find the solution.
What am I missing?
There are several issues that might cause the LDAP authentication not to work.
I am assuming you are running linux host. Have you verified that the LDAP settings you have entered works properly? Use command line tool 'ldapsearch' verify that the server works and responses as you might expect.
After you have successfully authenticated with ldapsearch and the authentication is still not working in Django i suggest you put logging on on and paste the logs somewhere.
Without futher info its hard to say what part of your setup is incorrect.
So, here goes the answer!
I changed "(uid=%(user)s)") to "(samaccountname=%(user)s)") which did the trick.
Having the logger helped locate what the problem was - was it even talking to LDAP or just trying to authenticate with the local database.

Not able to log in to the django admin page with a valid username and password

EDITED :
I have hosted a website on amazon AWS with domain say ( www.abc.com ) .
First : I tried to login to the django admin site , but its redirecting again to same page without showing any error (Note : username and password are correct)
Second : After successful signup, try to login to django internal page with a username and password:
Its redirecting to same login page by adding next keyword between url.
http://www.abc.com/login/?next=/employee/jcbdfvdhdfhvhdfsvsdhfhb-super-admin/home/dashboard/
Found one thing after investigating servers:
I have stoped all application like wsgi , suprervisorctl , ngnix etc.
and then run following command on ec2 aws console(Terminal)
python manage.py xxx.xx.xx.xx:8000
NOTE : xxx.xx.xx.xx is my domain(www.abc.com) IP
It successfully able to login at django-admin-site as well as project internal page.
Is there anything , I am missing in djano-settings?
I am stuck with this problem for long time . Any answer will be appreciable.
Please ask me if you need code from my project.
Checked all options from here : Unable log in to the django admin page with a valid username and password
EDITED settings.py file :
import sys, os
from os.path import abspath, basename, dirname, join, normpath
### from 2 scoops of django
# Normally you should not import
# ANYTHING from Django directly into
# your abc_settings, but
# ImproperlyConfigured is an
# exception.
from django.core.exceptions \
import ImproperlyConfigured
msg_get ="Set the %s environment variable"
msg_unset ="The %s environment variable not defined"
def get_env_variable(var_name):
try:
return os.environ[var_name]
except KeyError:
error_msg = msg_get % var_name
raise ImproperlyConfigured(error_msg)
def set_env_variable(var_name, value_str):
os.environ[var_name] = value_str
def unset_env_variable(var_name):
try:
del os.environ[var_name]
except KeyError:
error_msg = msg_unset % var_name
raise ImproperlyConfigured(error_msg)
### end snippet
ATOMIC_REQUESTS = True
########## PATH CONFIGURATION
# Absolute filesystem path to this Django project directory.
DJANGO_ROOT = dirname(dirname(dirname(abspath(__file__))))
CONFIG_ROOT = dirname(dirname(abspath(__file__)))
import sys
sys.path.append(normpath(join(DJANGO_ROOT, 'apps')))
# Site name.
SITE_NAME = basename(DJANGO_ROOT)
SITE_ID = 1
# Absolute filesystem path to the top-level project folder.
SITE_ROOT = dirname(DJANGO_ROOT)
# Add all necessary filesystem paths to our system path so that we can use
# python import statements.
sys.path.append(SITE_ROOT)
#sys.path.append(normpath(join(DJANGO_ROOT, 'apps')))
#sys.path.append(normpath(join(DJANGO_ROOT, 'libs')))
#########/# END PATH CONFIGURATION
########## SECURITY CONFIGS
def set_secret_key_env():
# Generating a SECRET_KEY. Will be auto-generated the first time this file is interpreted.
try:
os.environ['SECRET_KEY']
except KeyError:
import random
os.environ['SECRET_KEY'] = \
''.join([random.SystemRandom().choice('abcdefghijklmnopqrstuvwxyz0123456789!##$%^&*(-_=+)') for i in range(50)])
#tocheck - is it ok to uncomment this or should we use this to generate a secret key and set it normally,
#tocheck - in production on heroku for ex?
set_secret_key_env()
SECRET_KEY = get_env_variable('SECRET_KEY')
BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = "redis://"
CELERY_TRACK_STARTED = True
########## END CELERY CONFIGURATION
########## DJANGO-TEMPLATED-EMAIL CONFIGURATION
TEMPLATED_EMAIL_BACKEND = 'templated_email.backends.vanilla_django.TemplateBackend'
TEMPLATED_EMAIL_TEMPLATE_DIR = 'communication/email/' #use '' for top level template dir, ensure there is a trailing slash
TEMPLATED_EMAIL_FILE_EXTENSION = 'email'
########## END DJANGO-TEMPLATED-EMAIL CONFIGURATION
########## MANAGER CONFIGURATION
# Admin and managers for this project. These people receive private site
# alerts.
#tothink - should this be different for different environments
ADMINS = (
('Nirmal', 'nighggngh#abc.com'),
('Harsha', 'jjjjjjjgarkkwal#abc.com'),
)
########## URL CONFIGURATION
ROOT_URLCONF = '%s.urls' %SITE_NAME
########## END URL CONFIGURATION
MANAGERS = ADMINS
########## END MANAGER CONFIGURATION
########## GENERAL CONFIGURATION
# Hosts/domain names that are valid for this site; required if DEBUG is False
# See https://docs.djangoproject.com/en/1.5/ref/abc_settings/#allowed-hosts
ALLOWED_HOSTS = ['www.abc.com']
TIME_ZONE = 'Asia/Kolkata'
WSGI_APPLICATION = 'abc.wsgi.application'
# If you set this to False, Django will not use timezone-aware datetimes.
USE_TZ = False
# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html.
LANGUAGE_CODE = 'en-us'
USE_I18N = False
# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale.
USE_L10N = True
########## END GENERAL CONFIGURATION
########## EMAIL CONFIGURATION
#todo - should probably go into environment variables
#todo - get actual domain email etc
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.abc.com'
EMAIL_PORT = 587
#change this to proper email with hems domain
EMAIL_HOST_USER = 'abc#abc.com'
EMAIL_HOST_PASSWORD ='websupport2307'
EMAIL_USE_TLS = True
DEFAULT_FROM_EMAIL = 'abc#abc.com'
#EMAIL_USE_TLS = True
# ########## END EMAIL CONFIGURATION
########## MEDIA CONFIGURATION
# Absolute filesystem path to the directory that will hold user-uploaded files.
MEDIA_ROOT = normpath(join(DJANGO_ROOT, 'media')).replace('\\','/')
# URL that handles the media served from MEDIA_ROOT.
MEDIA_URL = '/media/'
########## END MEDIA CONFIGURATION
AUTHENTICATION_BACKENDS = ('custom.backends.EmailOrUsernameModelBackend','django.contrib.auth.backends.ModelBackend')
STATIC_ROOT = normpath(join(DJANGO_ROOT, 'final_static'))
# URL prefix for assets files.
STATIC_URL = '/static/'
# URL prefix for admin assets files -- CSS, JavaScript and images.
ADMIN_MEDIA_PREFIX = '/assets/admin/'
# Additional locations of assets files.
STATICFILES_DIRS = (
normpath(join(DJANGO_ROOT, 'static')),
)
# List of finder classes that know how to find assets files in various
# locations.
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
#'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
TEMPLATE_CONTEXT_PROCESSORS =('django.contrib.messages.context_processors.messages',
'django.contrib.auth.context_processors.auth',
"django.core.context_processors.request"
)
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
#'django.template.loaders.eggs.Loader',
)
# Directories to search when loading templates.
TEMPLATE_DIRS = (
normpath(join(DJANGO_ROOT, 'templates')),
normpath(join(DJANGO_ROOT, 'templates/Home_Page')),
normpath(join(DJANGO_ROOT, 'templates/Marketplace')),
normpath(join(DJANGO_ROOT, 'templates/Organisation')),
normpath(join(DJANGO_ROOT, 'templates/Organisation_Role')),
normpath(join(DJANGO_ROOT, 'templates/base')),
normpath(join(DJANGO_ROOT, 'templates/external')),
normpath(join(DJANGO_ROOT, 'templates/certificates')),
normpath(join(DJANGO_ROOT, 'templates/password_reset')),
normpath(join(DJANGO_ROOT, 'templates/support_dashboard')),
)
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
# 'django.contrib.sessions.backends.signed_cookies',
'custom.subdomain.SubdomainMiddleware', #middleware for subdomain
)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
# # Admin panel and documentation.
'django.contrib.admin',
# 'django.contrib.admindocs',
# South migration tool.
'south',
# Celery task queue.
'djcelery',
'apps.certificates',
'apps.account_subscription',
'apps.common_ds',
'apps.location',
'apps.communication,
'apps.transanction_history',
'rest_framework',
'apps.external_user',
'gunicorn',
#'notification'
#django extensions (recommended by 2 scoops of django)
)
import djcelery
djcelery.setup_loader()
CELERY_IMPORTS = (
'apps.communication.functionality.email',
'apps.organisation_roles.functionality.parse_employees_from_file',
)
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'INFO',
'class': 'logging.FileHandler',
'filename': '/home/ubuntu/logs/abc/logger.log',
},
},
'loggers': {
'django.request': {
'handlers': ['file'],
'level': 'INFO',
'propagate': True,
},
},
}
AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',)
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
SESSION_SAVE_EVERY_REQUEST = True
SESSION_COOKIE_AGE = 86400 # sec
SESSION_COOKIE_DOMAIN = '.abc.com'
SESSION_COOKIE_NAME = 'DSESSIONID'
SESSION_COOKIE_SECURE = False
DEBUG = True
TEMPLATE_DEBUG = DEBUG
LOGIN_URL = '/login/'
########## END DEBUG CONFIGURATION
########## DATABASE CONFIGURATION
#todo should go into environment variables
import dj_database_url
import os
if not os.environ.has_key('DATABASE_URL'):
os.environ['DATABASE_URL'] = 'postgres://abc:abc#abc-db.us-east-1.rds.amazonaws.com/dev_abc_db'
DATABASES = {
'default': dj_database_url.config(default=os.environ['DATABASE_URL'])
Your settings file seems fine. Are you using Gunicorn with multiple workers, If yes than try with single worker only. Actually sessions won't transfer between multiple workers unless you bring some middle layer storage component to it like memcached or redis. Faced same issue some time back. Hope it solves your problem :)
First try comment out all of the following lines,
and restart your server...
#AUTHENTICATION_BACKENDS = ('custom.backends.EmailOrUsernameModelBackend','django.contrib.auth.backends.ModelBackend')
# 'apps.communication,
#AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',)
#SESSION_EXPIRE_AT_BROWSER_CLOSE = True
#SESSION_SAVE_EVERY_REQUEST = True
#SESSION_COOKIE_AGE = 86400 # sec
#SESSION_COOKIE_DOMAIN = '.abc.com'
#SESSION_COOKIE_NAME = 'DSESSIONID'
#SESSION_COOKIE_SECURE = False
Things I noticed:
1: in INSTALLED_APPS you have a missing apostrophe after 'apps.communication
INSTALLED_APPS = (
'django.contrib.auth',
# -- snip --
'apps.communication,
)
2: you have AUTHENTIOCATION_BACKENDS defined twice. In this case your 2nd tuple is simply stepping on the first.
3: the order of authentication backends is important.
4: you do not need to list the 'django.contrib.auth.backends.ModelBackend' as it will be searched if 'django.contrib.auth' is in your INSTALLED_APPS. ( which you have configured )
This may seem like "low-hanging fruit", but I've experienced problems like this from time-to-time (login to Django Admin only to be returned to the login page for no apparent reason) as well. What has proven to be a solution every time is to clear my browser cache and cookies...ALL of them (rather than just the last hour or so).
Hope this helps.