mirror of
https://github.com/krislamo/DJ-BaseSite
synced 2025-09-11 21:49:28 +00:00
First Commit
This commit is contained in:
1
myproject/RunServer.bat
Normal file
1
myproject/RunServer.bat
Normal file
@@ -0,0 +1 @@
|
||||
@python manage.py runserver
|
1
myproject/SyncDB.bat
Normal file
1
myproject/SyncDB.bat
Normal file
@@ -0,0 +1 @@
|
||||
@python manage.py syncdb
|
0
myproject/accountprofile/__init__.py
Normal file
0
myproject/accountprofile/__init__.py
Normal file
7
myproject/accountprofile/models.py
Normal file
7
myproject/accountprofile/models.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
class UserProfile(models.Model):
|
||||
user = models.ForeignKey(User, unique=True)
|
||||
activated = models.BooleanField()
|
||||
activatekey = models.CharField(max_length=25, blank=True)
|
13
myproject/backends/AuthOverride.py
Normal file
13
myproject/backends/AuthOverride.py
Normal file
@@ -0,0 +1,13 @@
|
||||
from django.contrib.auth.backends import ModelBackend
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
class CaseInsensitiveModelBackend(ModelBackend):
|
||||
def authenticate(self, username=None, password=None):
|
||||
try:
|
||||
user = User.objects.get(username__iexact=username)
|
||||
if user.check_password(password):
|
||||
return user
|
||||
else:
|
||||
return None
|
||||
except User.DoesNotExist:
|
||||
return None
|
0
myproject/backends/__init__.py
Normal file
0
myproject/backends/__init__.py
Normal file
10
myproject/manage.py
Normal file
10
myproject/manage.py
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "<%myproject%>.settings")
|
||||
|
||||
from django.core.management import execute_from_command_line
|
||||
|
||||
execute_from_command_line(sys.argv)
|
0
myproject/myproject/__init__.py
Normal file
0
myproject/myproject/__init__.py
Normal file
7
myproject/myproject/activation_email.html
Normal file
7
myproject/myproject/activation_email.html
Normal file
@@ -0,0 +1,7 @@
|
||||
Hello <$user>,
|
||||
Welcome to the website. Please activate your account "<$user>"
|
||||
Activation link: <$activatelink>
|
||||
|
||||
If this is not you, I apologize for any inconveniences and you can disable the account and users will not be able to create another one.
|
||||
|
||||
Disable link: <$disablelink>
|
94
myproject/myproject/captcha.py
Normal file
94
myproject/myproject/captcha.py
Normal file
@@ -0,0 +1,94 @@
|
||||
import urllib2, urllib
|
||||
|
||||
API_SSL_SERVER="https://www.google.com/recaptcha/api"
|
||||
API_SERVER="http://www.google.com/recaptcha/api"
|
||||
VERIFY_SERVER="www.google.com"
|
||||
|
||||
class RecaptchaResponse(object):
|
||||
def __init__(self, is_valid, error_code=None):
|
||||
self.is_valid = is_valid
|
||||
self.error_code = error_code
|
||||
|
||||
def displayhtml (public_key,
|
||||
use_ssl = False,
|
||||
error = None):
|
||||
"""Gets the HTML to display for reCAPTCHA
|
||||
|
||||
public_key -- The public api key
|
||||
use_ssl -- Should the request be sent over ssl?
|
||||
error -- An error message to display (from RecaptchaResponse.error_code)"""
|
||||
|
||||
error_param = ''
|
||||
if error:
|
||||
error_param = '&error=%s' % error
|
||||
|
||||
if use_ssl:
|
||||
server = API_SSL_SERVER
|
||||
else:
|
||||
server = API_SERVER
|
||||
|
||||
return """<script type="text/javascript" src="%(ApiServer)s/challenge?k=%(PublicKey)s%(ErrorParam)s"></script>
|
||||
|
||||
<noscript>
|
||||
<iframe src="%(ApiServer)s/noscript?k=%(PublicKey)s%(ErrorParam)s" height="300" width="500" frameborder="0"></iframe><br />
|
||||
<textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
|
||||
<input type='hidden' name='recaptcha_response_field' value='manual_challenge' />
|
||||
</noscript>
|
||||
""" % {
|
||||
'ApiServer' : server,
|
||||
'PublicKey' : public_key,
|
||||
'ErrorParam' : error_param,
|
||||
}
|
||||
|
||||
|
||||
def submit (recaptcha_challenge_field,
|
||||
recaptcha_response_field,
|
||||
private_key,
|
||||
remoteip):
|
||||
"""
|
||||
Submits a reCAPTCHA request for verification. Returns RecaptchaResponse
|
||||
for the request
|
||||
|
||||
recaptcha_challenge_field -- The value of recaptcha_challenge_field from the form
|
||||
recaptcha_response_field -- The value of recaptcha_response_field from the form
|
||||
private_key -- your reCAPTCHA private key
|
||||
remoteip -- the user's ip address
|
||||
"""
|
||||
|
||||
if not (recaptcha_response_field and recaptcha_challenge_field and
|
||||
len (recaptcha_response_field) and len (recaptcha_challenge_field)):
|
||||
return RecaptchaResponse (is_valid = False, error_code = 'incorrect-captcha-sol')
|
||||
|
||||
|
||||
def encode_if_necessary(s):
|
||||
if isinstance(s, unicode):
|
||||
return s.encode('utf-8')
|
||||
return s
|
||||
|
||||
params = urllib.urlencode ({
|
||||
'privatekey': encode_if_necessary(private_key),
|
||||
'remoteip' : encode_if_necessary(remoteip),
|
||||
'challenge': encode_if_necessary(recaptcha_challenge_field),
|
||||
'response' : encode_if_necessary(recaptcha_response_field),
|
||||
})
|
||||
|
||||
request = urllib2.Request (
|
||||
url = "http://%s/recaptcha/api/verify" % VERIFY_SERVER,
|
||||
data = params,
|
||||
headers = {
|
||||
"Content-type": "application/x-www-form-urlencoded",
|
||||
"User-agent": "reCAPTCHA Python"
|
||||
}
|
||||
)
|
||||
|
||||
httpresp = urllib2.urlopen (request)
|
||||
|
||||
return_values = httpresp.read ().splitlines ();
|
||||
httpresp.close();
|
||||
|
||||
return_code = return_values [0]
|
||||
|
||||
if (return_code == "true"):
|
||||
return RecaptchaResponse (is_valid=True)
|
||||
else:
|
||||
return RecaptchaResponse (is_valid=False, error_code = return_values [1])
|
169
myproject/myproject/settings.py
Normal file
169
myproject/myproject/settings.py
Normal file
@@ -0,0 +1,169 @@
|
||||
'''
|
||||
|
||||
Copyright (c) 2012, Kris Lamoureux
|
||||
All rights reserved.
|
||||
|
||||
DJ-BaseSite is released under the New BSD Liscense.
|
||||
Please take a momemt to read the short 3 Clause LICENSE file.
|
||||
|
||||
'''
|
||||
|
||||
# Django settings for the "<%myproject%>" project.
|
||||
import os
|
||||
ROOTDIR = os.getcwd().replace('\\','/')
|
||||
|
||||
DEBUG = True
|
||||
TEMPLATE_DEBUG = DEBUG
|
||||
|
||||
baseurl = "<%baseurl%>" # "example.com"
|
||||
|
||||
'''
|
||||
You need to sign up at http://recaptcha.net/ for a public/private key to use their CAPTCHA service.
|
||||
'''
|
||||
|
||||
captcha_publickey = "<%captcha_publickey%>"
|
||||
captcha_privatekey = "<%captcha_privatekey%>"
|
||||
|
||||
EMAIL_USE_TLS = True
|
||||
EMAIL_HOST = "<%HOSTsmtp%>"
|
||||
EMAIL_HOST_USER = "<%HOSTemail%>"
|
||||
EMAIL_HOST_PASSWORD = "<%HOSTpass%>"
|
||||
EMAIL_PORT = 587
|
||||
|
||||
EMAIL_MESSAGE = ROOTDIR + "/<%myproject%>/activation_email.html"
|
||||
|
||||
ADMINS = (
|
||||
("<%admin_name%>", "<%admin_email%>"),
|
||||
)
|
||||
|
||||
|
||||
MANAGERS = ADMINS
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
|
||||
'NAME': ROOTDIR + '/data.db',
|
||||
}
|
||||
}
|
||||
|
||||
# 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-us'
|
||||
|
||||
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: "/home/media/media.lawrence.com/media/"
|
||||
MEDIA_ROOT = ''
|
||||
|
||||
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
|
||||
# trailing slash.
|
||||
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
|
||||
MEDIA_URL = ''
|
||||
|
||||
# URL prefix for static files.
|
||||
# Example: "http://media.lawrence.com/static/"
|
||||
STATIC_URL = '/static/'
|
||||
|
||||
# Additional locations of static files
|
||||
STATICFILES_DIRS = (
|
||||
ROOTDIR + "/<%myproject%>/static/",
|
||||
)
|
||||
|
||||
# List of finder classes that know how to find static files in
|
||||
# various locations.
|
||||
STATICFILES_FINDERS = (
|
||||
'django.contrib.staticfiles.finders.FileSystemFinder',
|
||||
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
|
||||
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
|
||||
)
|
||||
|
||||
# Make this unique, and don't share it with anybody.
|
||||
SECRET_KEY = "<%secret_key%>"
|
||||
|
||||
# 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.middleware.common.CommonMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
# Uncomment the next line for simple clickjacking protection:
|
||||
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
)
|
||||
|
||||
ROOT_URLCONF = '<%myproject%>.urls'
|
||||
|
||||
# Python dotted path to the WSGI application used by Django's runserver.
|
||||
WSGI_APPLICATION = '<%myproject%>.wsgi.application'
|
||||
|
||||
TEMPLATE_DIRS = (
|
||||
ROOTDIR + "/<%myproject%>/templates/",
|
||||
)
|
||||
|
||||
INSTALLED_APPS = (
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.sites',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'django.contrib.admin',
|
||||
'accountprofile'
|
||||
)
|
||||
|
||||
AUTH_PROFILE_MODULE = "accountprofile.UserProfile"
|
||||
|
||||
# A sample logging configuration. The only tangible logging
|
||||
# performed by this configuration is to send an email to
|
||||
# the site admins on every HTTP 500 error when DEBUG=False.
|
||||
# See http://docs.djangoproject.com/en/dev/topics/logging for
|
||||
# more details on how to customize your logging configuration.
|
||||
LOGGING = {
|
||||
'version': 1,
|
||||
'disable_existing_loggers': False,
|
||||
'filters': {
|
||||
'require_debug_false': {
|
||||
'()': 'django.utils.log.RequireDebugFalse'
|
||||
}
|
||||
},
|
||||
'handlers': {
|
||||
'mail_admins': {
|
||||
'level': 'ERROR',
|
||||
'filters': ['require_debug_false'],
|
||||
'class': 'django.utils.log.AdminEmailHandler'
|
||||
}
|
||||
},
|
||||
'loggers': {
|
||||
'django.request': {
|
||||
'handlers': ['mail_admins'],
|
||||
'level': 'ERROR',
|
||||
'propagate': True,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
AUTHENTICATION_BACKENDS = ('backends.AuthOverride.CaseInsensitiveModelBackend',)
|
113
myproject/myproject/static/css/default.css
Normal file
113
myproject/myproject/static/css/default.css
Normal file
@@ -0,0 +1,113 @@
|
||||
/* APPLYS TO ALL TEMPLATES */
|
||||
body {
|
||||
font-family:"Comic Sans MS", cursive, sans-serif;
|
||||
background-color: #FFFFFF;
|
||||
color: #000000;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.usernav a:link {color:#FFFFFF;} /* unvisited link */
|
||||
.usernav a:visited {color:#FFFFFF;} /* visited link */
|
||||
.usernav a:hover {color:#FFFFFF;} /* mouse over link */
|
||||
.usernav a:active {color:#FFFFFF;} /* selected link */
|
||||
|
||||
.globalnav a:link {color:#000000;} /* unvisited link */
|
||||
.globalnav a:visited {color:#000000;} /* visited link */
|
||||
.globalnav a:hover {color:#000000;} /* mouse over link */
|
||||
.globalnav a:active {color:#000000;} /* selected link */
|
||||
|
||||
.usernav {
|
||||
text-align: right;
|
||||
padding: 10px;
|
||||
background-color: #000000;
|
||||
}
|
||||
|
||||
.globalnav {
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.humantest {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* HOME PAGE CSS */
|
||||
|
||||
|
||||
|
||||
/* LOGIN CSS */
|
||||
.loginform {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table.loginform td {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.loginout {
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
.returnlink a:link {color:#000000;} /* unvisited link */
|
||||
.returnlink a:visited {color:#000000;} /* visited link */
|
||||
.returnlink a:hover {color:#000000;} /* mouse over link */
|
||||
.returnlink a:active {color:#000000;} /* selected link */
|
||||
|
||||
/* REGISTER CSS */
|
||||
.register_form {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table.register_form td {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.asterisk {
|
||||
color: #FF0000;
|
||||
font-size: 17px;
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
.tagpsnrequire {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.newaccount {
|
||||
font-size: 25px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
/* ERROR RELATED CSS */
|
||||
|
||||
.error {
|
||||
color: #FF0000;
|
||||
font-size: 25px;
|
||||
padding: 12px;
|
||||
text-align: center;
|
||||
background-color: #000000;
|
||||
font-family:"Lucida Console", Monaco, monospace
|
||||
}
|
||||
|
||||
.register_error {
|
||||
color: #FF0000;
|
||||
font-size: 18px;
|
||||
padding: 6px;
|
||||
text-align: center;
|
||||
background-color: #000000;
|
||||
font-family:"Lucida Console", Monaco, monospace
|
||||
}
|
||||
|
||||
.login_error {
|
||||
color: #FF0000;
|
||||
font-size: 18px;
|
||||
padding: 6px;
|
||||
text-align: center;
|
||||
background-color: #000000;
|
||||
font-family:"Lucida Console", Monaco, monospace
|
||||
}
|
10
myproject/myproject/templates/admin/base_site.html
Normal file
10
myproject/myproject/templates/admin/base_site.html
Normal file
@@ -0,0 +1,10 @@
|
||||
{% extends "admin/base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{{ title }} | {% trans 'Admin Site' %}{% endblock %}
|
||||
|
||||
{% block branding %}
|
||||
<h1 id="site-name">{% trans 'Administration' %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block nav-global %}{% endblock %}
|
8
myproject/myproject/templates/auth/activated.html
Normal file
8
myproject/myproject/templates/auth/activated.html
Normal file
@@ -0,0 +1,8 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="activated">
|
||||
Your account "{{user_name}}" has been activated.
|
||||
<div class="activated_login"><a href="/login/">Login</a></div>
|
||||
</div>
|
||||
{% endblock %}
|
5
myproject/myproject/templates/auth/disabled.html
Normal file
5
myproject/myproject/templates/auth/disabled.html
Normal file
@@ -0,0 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div>Your account has been disabled.</div>
|
||||
{% endblock %}
|
6
myproject/myproject/templates/auth/logged_in.html
Normal file
6
myproject/myproject/templates/auth/logged_in.html
Normal file
@@ -0,0 +1,6 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="loginout">You have been logged in.</div>
|
||||
<div class="returnlink"><a href="/">Return to the Main Page</a></div>
|
||||
{% endblock %}
|
6
myproject/myproject/templates/auth/logged_out.html
Normal file
6
myproject/myproject/templates/auth/logged_out.html
Normal file
@@ -0,0 +1,6 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="loginout">You have been logged out.</div>
|
||||
<div class="returnlink"><a href="/">Return to the Main Page</a></div>
|
||||
{% endblock %}
|
30
myproject/myproject/templates/auth/login.html
Normal file
30
myproject/myproject/templates/auth/login.html
Normal file
@@ -0,0 +1,30 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{{LOGIN_ERROR|safe}}
|
||||
|
||||
{% if login_errors %}
|
||||
<div class="login_error">
|
||||
Username and password did not match.
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<h1>Login</h1>
|
||||
<form action="/login/" method="post">
|
||||
{% csrf_token %}
|
||||
<table class="loginform" align="center">
|
||||
<tr>
|
||||
<td>User</td>
|
||||
<td><input type="text" name="username" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Pass</td>
|
||||
<td><input type="password" name="password" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><input type="submit" value="Login"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
{% endblock %}
|
7
myproject/myproject/templates/auth/newaccount.html
Normal file
7
myproject/myproject/templates/auth/newaccount.html
Normal file
@@ -0,0 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="newaccount">
|
||||
Account "{{accountname}}" successfully created. Check your email to activate it so you can start using the features on the site.
|
||||
</div>
|
||||
{% endblock %}
|
47
myproject/myproject/templates/auth/registration.html
Normal file
47
myproject/myproject/templates/auth/registration.html
Normal file
@@ -0,0 +1,47 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% if registration_errors %}
|
||||
<div class="register_error">
|
||||
<ul>
|
||||
{% for an_error in registration_errors %}
|
||||
<li>{{ an_error }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<h1>Registration</h1>
|
||||
<form action="/register/" method="post">
|
||||
{% csrf_token %}
|
||||
<table class="register_form" align="center">
|
||||
<tr>
|
||||
<td>User<span class="asterisk">*</span></td>
|
||||
<td><input type="text" name="usern" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Pass<span class="asterisk">*</span></td>
|
||||
<td><input type="password" name="passw" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Pass (again)<span class="asterisk">*</span></td>
|
||||
<td><input type="password" name="repassw" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Email<span class="asterisk">*</span></td>
|
||||
<td><input type="text" name="email" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" class="humantest">
|
||||
{{captcha_test|safe}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><input type="submit" value="Register"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="required">Fields with the asterick '<span class="asterisk">*</span>' are required</div>
|
||||
</form>
|
||||
{% endblock %}
|
21
myproject/myproject/templates/base.html
Normal file
21
myproject/myproject/templates/base.html
Normal file
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>{{title}}</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/default.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="usernav">
|
||||
{{user_navigation|safe}}
|
||||
</div>
|
||||
<div class="globalnav">
|
||||
{{global_navigation|safe}}
|
||||
</div>
|
||||
<div class="content">
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
5
myproject/myproject/templates/error.html
Normal file
5
myproject/myproject/templates/error.html
Normal file
@@ -0,0 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div class="error">{{error}}</div>
|
||||
<div class="returnlink"><a href="/">Return to the Main Page</a></div>
|
||||
{% endblock %}
|
5
myproject/myproject/templates/index.html
Normal file
5
myproject/myproject/templates/index.html
Normal file
@@ -0,0 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Index Page, no content yet.</h1>
|
||||
{% endblock %}
|
31
myproject/myproject/urls.py
Normal file
31
myproject/myproject/urls.py
Normal file
@@ -0,0 +1,31 @@
|
||||
'''
|
||||
|
||||
Copyright (c) 2012, Kris Lamoureux
|
||||
All rights reserved.
|
||||
|
||||
DJ-BaseSite is released under the New BSD Liscense.
|
||||
Please take a momemt to read the short 3 Clause LICENSE file.
|
||||
|
||||
'''
|
||||
|
||||
|
||||
from django.conf.urls import patterns, include, url
|
||||
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
||||
|
||||
# Uncomment the next two lines to enable the admin:
|
||||
from django.contrib import admin
|
||||
admin.autodiscover()
|
||||
|
||||
urlpatterns = patterns('<%myproject%>.views',
|
||||
|
||||
# Uncomment the next line to enable the admin:
|
||||
url(r'^admin/', include(admin.site.urls)),
|
||||
url(r'^$', 'index'),
|
||||
url(r'^login/$', 'login_user'),
|
||||
url(r'^logout/$', 'logout_user'),
|
||||
url(r'^register/$', 'register_user'),
|
||||
url(r'^activate/$', 'activate_user'),
|
||||
#url(r'^deactivate/$', 'activate_user'), Deactivate needs to be written.
|
||||
)
|
||||
|
||||
urlpatterns += staticfiles_urlpatterns()
|
72
myproject/myproject/validation.py
Normal file
72
myproject/myproject/validation.py
Normal file
@@ -0,0 +1,72 @@
|
||||
from re import match
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
'''
|
||||
Return Meanings
|
||||
None (no data to check)
|
||||
-1 (data too long/short)
|
||||
-2 (user exists)
|
||||
False (no match)
|
||||
data (matched, data is valid)
|
||||
'''
|
||||
|
||||
def clean_username(data,length=30):
|
||||
if data == "":
|
||||
return None
|
||||
if len(data) <= length:
|
||||
if match("^[\w\d_]+$", data):
|
||||
try:
|
||||
user = User.objects.get(username__iexact=data)
|
||||
return -2
|
||||
except User.DoesNotExist:
|
||||
return data
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return -1
|
||||
|
||||
def clean_email(data,length=254):
|
||||
if data == "":
|
||||
return None
|
||||
if len(data) <= length:
|
||||
if match("^[\w\d._%-+]+@[\w\d._%-]+.[\w]{2,6}$", data):
|
||||
try:
|
||||
user = User.objects.get(email=data)
|
||||
return -2
|
||||
except User.DoesNotExist:
|
||||
return data
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return -1
|
||||
|
||||
|
||||
def clean_password(data,length_min=5):
|
||||
if data == "":
|
||||
return None
|
||||
if len(data) >= length_min:
|
||||
return data
|
||||
else:
|
||||
return -1
|
||||
|
||||
|
||||
def clean_key(data, length=25):
|
||||
if data == "":
|
||||
return None
|
||||
if len(data) == 25:
|
||||
if match("^[a-zABCDEFG0-9]+$", data):
|
||||
return data
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return -1
|
||||
|
||||
|
||||
def clean_usernameRE(data):
|
||||
if match("^[\w\d_]+$", data):
|
||||
return data
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
|
359
myproject/myproject/views.py
Normal file
359
myproject/myproject/views.py
Normal file
@@ -0,0 +1,359 @@
|
||||
'''
|
||||
|
||||
Copyright (c) 2012, Kris Lamoureux
|
||||
All rights reserved.
|
||||
|
||||
DJ-BaseSite is released under the New BSD Liscense.
|
||||
Please take a momemt to read the short 3 Clause LICENSE file.
|
||||
|
||||
'''
|
||||
|
||||
|
||||
# Built in imports
|
||||
import random
|
||||
import hashlib
|
||||
|
||||
# Responce imports
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.shortcuts import render_to_response, RequestContext
|
||||
|
||||
# Authentication/Session/Validation imports
|
||||
from django.contrib.auth import authenticate, login, logout
|
||||
from django.contrib.sessions.models import Session
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
# Below expected to be in same directory
|
||||
import validation as v
|
||||
import captcha
|
||||
|
||||
# Email imports
|
||||
from django.core.mail import EmailMessage
|
||||
from django.core import mail
|
||||
|
||||
# Variables from Settings.py
|
||||
from settings import EMAIL_HOST_USER, baseurl, EMAIL_MESSAGE
|
||||
|
||||
# User Profile model
|
||||
from accountprofile.models import UserProfile
|
||||
|
||||
# Website base title
|
||||
base_title = "Base Site - "
|
||||
|
||||
# Global Site Navigation
|
||||
def global_nav():
|
||||
return '<a href="/">Home</a>'
|
||||
|
||||
# User Site Navigation
|
||||
def user_nav(user):
|
||||
if not user:
|
||||
return '<a href="/login/">Login</a> | <a href="/register/">Register</a>'
|
||||
else:
|
||||
return '<a href="/account/">'+user+'</a> | <a href="/logout/">Logout</a>'
|
||||
|
||||
def get_or_create_profile(user):
|
||||
try:
|
||||
profile = user.get_profile()
|
||||
except ObjectDoesNotExist:
|
||||
profile = UserProfile(activated=True, user=user)
|
||||
profile.save()
|
||||
return profile
|
||||
|
||||
def get_ip(request):
|
||||
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
|
||||
if x_forwarded_for:
|
||||
ip = x_forwarded_for.split(',')[0]
|
||||
else:
|
||||
ip = request.META.get('REMOTE_ADDR')
|
||||
return ip
|
||||
|
||||
def UserActivationKey():
|
||||
random.seed()
|
||||
choices = "abcdefghijklmnopqrstuvwxyzABCDEFG0123456789"
|
||||
|
||||
word = ""
|
||||
for i in range(25):
|
||||
x = random.randrange(0,len(choices))
|
||||
word = word + choices[x]
|
||||
return word
|
||||
|
||||
|
||||
''' PAGE REQUESTS '''
|
||||
def index(request):
|
||||
global base_title
|
||||
global global_nav, user_nav
|
||||
|
||||
# Load Global Navigation and title.
|
||||
title = base_title + "Home"
|
||||
global_navigation=global_nav()
|
||||
|
||||
# Load user navigation based on the session
|
||||
if request.user.is_authenticated():
|
||||
user_navigation = user_nav(request.user.username)
|
||||
else:
|
||||
user_navigation = user_nav(False)
|
||||
|
||||
responce = render_to_response('index.html', locals())
|
||||
return responce
|
||||
|
||||
def logout_user(request):
|
||||
logout(request)
|
||||
return render_to_response('auth/logged_out.html', locals())
|
||||
|
||||
def login_user(request):
|
||||
global base_title
|
||||
global global_nav, user_nav
|
||||
|
||||
title = base_title + "Login"
|
||||
global_navigation=global_nav()
|
||||
|
||||
# If user is not logged on
|
||||
if not request.user.is_authenticated():
|
||||
|
||||
# Return user navigation for an anonymous session
|
||||
user_navigation = user_nav(False)
|
||||
|
||||
# If user has sent POST data
|
||||
if request.method == 'POST':
|
||||
|
||||
# Collect user data and return user object
|
||||
usern = request.POST['username']
|
||||
passw = request.POST['password']
|
||||
|
||||
''' CLEAN '''
|
||||
|
||||
user = authenticate(username=usern, password=passw)
|
||||
|
||||
if user is not None:
|
||||
# If user object exists it means the user is authenticated
|
||||
# but you still need to check if the user.is_active
|
||||
|
||||
if user.is_active:
|
||||
# Account is active and not disabled.
|
||||
# ... but is it activated?
|
||||
user_profile = get_or_create_profile(user)
|
||||
if user_profile.activated:
|
||||
# User account is activated (via email)
|
||||
login(request, user)
|
||||
user_name = user.username
|
||||
responce = render_to_response('auth/logged_in.html', locals())
|
||||
else:
|
||||
# The account is not activated via email
|
||||
error = "Please activate your account through email."
|
||||
responce = render_to_response('error.html', locals())
|
||||
else:
|
||||
# The account is disabled. No login.
|
||||
message = "Your account has been disabled."
|
||||
responce = render_to_response('auth/disabled.html', locals())
|
||||
|
||||
else:
|
||||
# No object so the username and password are invalid.
|
||||
login_errors = True
|
||||
responce = render_to_response(
|
||||
'auth/login.html',
|
||||
locals(),
|
||||
context_instance=RequestContext(request)
|
||||
)
|
||||
|
||||
else:
|
||||
# User isn't online and hasn't sent any POST data, give them a login form.
|
||||
responce = render_to_response(
|
||||
'auth/login.html',
|
||||
locals(),
|
||||
context_instance=RequestContext(request)
|
||||
)
|
||||
|
||||
else:
|
||||
# User is logged on, don't let them login until he's logged out.
|
||||
user_navigation = user_nav(request.user.username)
|
||||
error = "You're already logged on."
|
||||
responce = render_to_response(
|
||||
'error.html',
|
||||
locals()
|
||||
)
|
||||
return responce
|
||||
|
||||
def register_user(request):
|
||||
global base_title
|
||||
global global_nav, user_nav
|
||||
|
||||
title = base_title + "Register"
|
||||
global_navigation=global_nav()
|
||||
|
||||
|
||||
# If user is not logged on
|
||||
if not request.user.is_authenticated():
|
||||
|
||||
# Return user navigation for an anonymous session
|
||||
user_navigation = user_nav(False)
|
||||
|
||||
# Set up captcha html.
|
||||
from settings import captcha_publickey, captcha_privatekey
|
||||
captcha_test = captcha.displayhtml(captcha_publickey)
|
||||
|
||||
# If user has sent POST data (not logged in)
|
||||
if request.method == 'POST':
|
||||
registration_errors = [] # Error list
|
||||
|
||||
''' Check and validate data '''
|
||||
|
||||
# Is human?
|
||||
HumanTestResult = captcha.submit(
|
||||
request.POST["recaptcha_challenge_field"],
|
||||
request.POST["recaptcha_response_field"],
|
||||
captcha_privatekey,
|
||||
get_ip(request)
|
||||
)
|
||||
|
||||
# If not human: display errors
|
||||
if HumanTestResult.is_valid:
|
||||
# Matching passwords?
|
||||
password = v.clean_password(request.POST["passw"])
|
||||
if not request.POST["passw"] == request.POST["repassw"]:
|
||||
registration_errors.append("Passwords don't match.")
|
||||
if password == None:
|
||||
registration_errors.append("No password entered.")
|
||||
elif password == -1:
|
||||
registration_errors.append("Passwords have to be at least 5 characters.")
|
||||
|
||||
# Username related errors
|
||||
username = v.clean_username(request.POST["usern"])
|
||||
if username == None:
|
||||
registration_errors.append("No username entered.")
|
||||
elif username == -2:
|
||||
registration_errors.append("This username isn't available.")
|
||||
elif username == -1:
|
||||
registration_errors.append("Username's can only be 30 characters.")
|
||||
elif username == False:
|
||||
registration_errors.append("Username wasn't just characters numbers ")
|
||||
|
||||
# Email related errors
|
||||
email = v.clean_email(request.POST["email"])
|
||||
if email == None:
|
||||
registration_errors.append("No email entered.")
|
||||
elif email == -2:
|
||||
registration_errors.append("This email already has an account.")
|
||||
elif email == -1:
|
||||
registration_errors.append("Emails can only be 245 characters.")
|
||||
elif email == False:
|
||||
registration_errors.append("Invalid email.")
|
||||
|
||||
# Invalid CAPTCHA, display only that error giving no more information to the bot
|
||||
else:
|
||||
registration_errors.append("Invalid human verification code.")
|
||||
captcha_test = captcha.displayhtml(
|
||||
captcha_publickey,
|
||||
False,
|
||||
HumanTestResult.error_code)
|
||||
|
||||
# If no errors: create user.
|
||||
if len(registration_errors) == 0:
|
||||
new_user = User.objects.create_user(
|
||||
username,
|
||||
email,
|
||||
request.POST["repassw"]
|
||||
)
|
||||
new_user.is_active = True
|
||||
new_user.save()
|
||||
|
||||
# Create activation key and user profile
|
||||
activation_key = UserActivationKey()
|
||||
profile = UserProfile(
|
||||
activatekey=activation_key,
|
||||
activated=False,
|
||||
user=new_user)
|
||||
profile.save()
|
||||
|
||||
# User is created and saved. Send an activation link via email
|
||||
connection = mail.get_connection()
|
||||
connection.open()
|
||||
|
||||
message_activateurl = baseurl+"/activate/?key="+str(activation_key)+"&user="+str(new_user.username)
|
||||
message_deactivateurl = baseurl+"/deactivate/?key="+str(activation_key)+"&user="+str(new_user.username)
|
||||
|
||||
f = open(EMAIL_MESSAGE, 'r')
|
||||
message = f.read()
|
||||
|
||||
message = message.replace("<$user>", str(new_user.username))
|
||||
message = message.replace("<$activatelink>", message_activateurl)
|
||||
message = message.replace("<$disablelink>", message_deactivateurl)
|
||||
|
||||
email = EmailMessage(
|
||||
"Account Activation",
|
||||
message,
|
||||
EMAIL_HOST_USER,
|
||||
[new_user.email])
|
||||
email.send()
|
||||
connection.close()
|
||||
|
||||
# Return new account page
|
||||
accountname = new_user.username
|
||||
responce = render_to_response(
|
||||
'auth/newaccount.html',
|
||||
locals(),
|
||||
context_instance=RequestContext(request)
|
||||
)
|
||||
else:
|
||||
# Return registration form with errors in registration_errors
|
||||
responce = render_to_response(
|
||||
'auth/registration.html',
|
||||
locals(),
|
||||
context_instance=RequestContext(request)
|
||||
)
|
||||
|
||||
# If user hasn't sent POST data (not logged on)
|
||||
else:
|
||||
responce = render_to_response(
|
||||
'auth/registration.html',
|
||||
locals(),
|
||||
context_instance=RequestContext(request)
|
||||
)
|
||||
# User is logged on
|
||||
else:
|
||||
user_navigation = user_nav(request.user.username)
|
||||
error = "You cannot register while logged in."
|
||||
responce = render_to_response(
|
||||
'error.html',
|
||||
locals()
|
||||
)
|
||||
return responce
|
||||
|
||||
def activate_user(request):
|
||||
if request.method == 'GET':
|
||||
# Check if data could be valid through regex
|
||||
key = v.clean_key(request.GET["key"])
|
||||
u_name = v.clean_usernameRE(request.GET["user"])
|
||||
|
||||
# If key and username are valid
|
||||
if request.GET["key"] == key and u_name:
|
||||
try:
|
||||
# Check profile for key and compare.
|
||||
user = User.objects.get(username=u_name)
|
||||
user_profile = get_or_create_profile(user)
|
||||
|
||||
if user_profile.activatekey == key:
|
||||
# Activate user
|
||||
user_profile.activated = True
|
||||
user_profile.save()
|
||||
key_correct = True
|
||||
else:
|
||||
key_correct = False
|
||||
|
||||
except ObjectDoesNotExist:
|
||||
key_correct = False
|
||||
else:
|
||||
key_correct = False
|
||||
|
||||
if key_correct:
|
||||
user_name = user.username
|
||||
responce = render_to_response(
|
||||
'auth/activated.html',
|
||||
locals()
|
||||
)
|
||||
else:
|
||||
error = "Activation failed."
|
||||
responce = render_to_response(
|
||||
'error.html',
|
||||
locals()
|
||||
)
|
||||
|
||||
return responce
|
28
myproject/myproject/wsgi.py
Normal file
28
myproject/myproject/wsgi.py
Normal file
@@ -0,0 +1,28 @@
|
||||
"""
|
||||
WSGI config for <%myproject%> project.
|
||||
|
||||
This module contains the WSGI application used by Django's development server
|
||||
and any production WSGI deployments. It should expose a module-level variable
|
||||
named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover
|
||||
this application via the ``WSGI_APPLICATION`` setting.
|
||||
|
||||
Usually you will have the standard Django WSGI application here, but it also
|
||||
might make sense to replace the whole Django WSGI application with a custom one
|
||||
that later delegates to the Django one. For example, you could introduce WSGI
|
||||
middleware here, or combine a Django application with an application of another
|
||||
framework.
|
||||
|
||||
"""
|
||||
import os
|
||||
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "<%myproject%>.settings")
|
||||
|
||||
# This application object is used by any WSGI server configured to use this
|
||||
# file. This includes Django's development server, if the WSGI_APPLICATION
|
||||
# setting points here.
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
application = get_wsgi_application()
|
||||
|
||||
# Apply WSGI middleware here.
|
||||
# from helloworld.wsgi import HelloWorldApplication
|
||||
# application = HelloWorldApplication(application)
|
Reference in New Issue
Block a user