mirror of
https://github.com/krislamo/DJ-BaseSite
synced 2024-12-15 23:50:35 +00:00
Added the deactivation and account recovery system
Added the deactivation and account recovery systems. The variable EMAIL_MESSAGE was replaced with ACTIVATE_EMAIL, then RECOVERY_EMAIL was added. The response variable was changed in all views to the correct spelling. The validation file has a new function to validate the regular expressions in an email string and not check the database. And finally the function UserActivationKey in views was renamed to KeyGen
This commit is contained in:
parent
8c5b68fd0d
commit
dce89a3acf
49
README
49
README
@ -1,49 +0,0 @@
|
||||
DJ-BaseSite was written in Python 2.7 and Django 1.4
|
||||
|
||||
Description:
|
||||
DJ-BaseSite is a customizable login and register system with required email activation. While most people just use django-registration, I decided to write my own to learn more about Django.
|
||||
|
||||
NOTE TO DEVS:
|
||||
A deactivation system hasn't been added. The login system needs to check attempts and display a CAPTCHA after a certain amount, this isn't included either. It also doesn't have an account recovery option. I plan to implement all of these things in future updates.
|
||||
|
||||
DJ-BaseSite is released under the New BSD License (The BSD 3-Clause License), refer to the LICENSE file.
|
||||
|
||||
|
||||
Instructions
|
||||
1. Install Python 2.7 (python.org) and Django 1.4 (djangoproject.com)
|
||||
2. Open up the config.txt file and change the data under CUSTOM VARIABLES to your information. The configuration variable meanings are below.
|
||||
3. Execute the SetupProject.py script and enter the project name, it will create a project based on your configuration.
|
||||
4. Run the SyncDB script or "python manage.py syncdb" and create a super user.
|
||||
5. Run the RunServer script or "python manage.py runserver" and check out your new website at localhost:8000 or 127.0.0.1:8000 in your browser.
|
||||
|
||||
DJ-BaseSite uses Recaptcha to prevent bots from creating accounts, so you'll need to get private and public keys from the website: http://www.google.com/recaptcha
|
||||
|
||||
Configuration Variable Meanings.
|
||||
===================================
|
||||
-baseurl
|
||||
It is used to create activation and deactivation links [in views.py in register_user()]
|
||||
|
||||
-admin_name/email
|
||||
Adds a name and email to the ADMINS tuple in settings.py
|
||||
http://docs.djangoproject.com/en/dev/ref/settings/#admins
|
||||
|
||||
-secret_key
|
||||
A string used to provide cryptographic signing. (don't use spaces due to the configurtion system)
|
||||
https://docs.djangoproject.com/en/dev/ref/settings/#secret-key
|
||||
http://www.random.org/passwords/?mode=advanced
|
||||
|
||||
-captcha_publickey/privatekey
|
||||
DJ-BaseSite uses Recaptcha to prevent bots from creating accounts, get keys at http://www.google.com/recaptcha
|
||||
|
||||
-HOSTsmpt
|
||||
The SMPT server address with the email used to send activation emails. If your email doesn't support SMPT I highly suggest GMAIL.
|
||||
|
||||
-HOSTemail
|
||||
The email address
|
||||
|
||||
-HOSTpass
|
||||
The email's password
|
||||
===================================
|
||||
|
||||
|
||||
NOTE: It creates a development project, DEBUG is set to True in the settings.py so it is in no condition for deployment.
|
50
README.md
Normal file
50
README.md
Normal file
@ -0,0 +1,50 @@
|
||||
# DJ-BaseSite
|
||||
|
||||
DJ-BaseSite is a base Django **development** website project that adds basic user interaction to the site. Features include: The Django admin site, a login and logout system, a user registration system with required activation (via email), deactivation (an option during activation) and account recovery.
|
||||
|
||||
#### _This project is currently in the Alpha phase. Therefore it is suggested you thoroughly read and test when forking, etc._
|
||||
|
||||
DJ-BaseSite was written with [Python 2.7](http://www.python.org/download/releases/2.7/) and [Django 1.4](https://www.djangoproject.com/download/) on Windows 7 Home Premium 64 bit (Service Pack 1)
|
||||
|
||||
## License
|
||||
DJ-BaseSite is released under the New BSD License, refer to the LICENSE file in the root of the repository before continuing.
|
||||
|
||||
## Change Log
|
||||
|
||||
### `0.7` (Oct 20, 2012)
|
||||
* Added the deactivation and account recovery systems.
|
||||
* Variable `EMAIL_MESSAGE` was replaced with `ACTIVATE_EMAIL` & `RECOVERY_EMAIL` was added.
|
||||
* The `response` variable was changed in all views to the correct spelling. derp.
|
||||
* Function `clean_emailRE()` was added to `validation.py`
|
||||
* The function `UserActivationKey()` in `views.py` was renamed to `KeyGen()`
|
||||
|
||||
### [`0.5`](https://github.com/Kris619/DJ-BaseSite/zipball/80cdb11749afa9d2ecfcbb0a91f3f867f183bfc3) (Oct 13, 2012) SHA: 80cdb11749afa9d2ecfcbb0a91f3f867f183bfc3
|
||||
* login / registration system with Django's default authentication backend
|
||||
* activation system (deactivation system not implemented)
|
||||
* reCAPTCHA support for registration
|
||||
|
||||
## Quick Start
|
||||
1. Open up the `config.txt` file and change the data under `CUSTOM VARIABLES` to your information. The configuration is explained below.
|
||||
2. Execute the `SetupProject.py` script and enter a project name, it will replicate the project out of `/myproject/` to `/yourproject/` with your information.
|
||||
3. Run syncdb via terminal/console in the root of the project: `python manage.py syncdb`
|
||||
* Windows users will need to add the path of their Python 2.7 installation (example: `C:/Python27/`) to the [path variable](http://showmedo.com/videotutorials/video?name=960000&fromSeriesID=96)
|
||||
4. Run the development server: `python manage.py runserver`
|
||||
|
||||
> You should be done at this point. So check out your new website at [http://localhost:8000](http://localhost:8000) or [http://127.0.0.1:8000](http://127.0.0.1:8000) in your browser.
|
||||
|
||||
## Configuration
|
||||
|
||||
* `baseurl`
|
||||
* Used to create activation, deactivation and recovery links
|
||||
* `admin_name/email` `(`[`official documentation`](https://docs.djangoproject.com/en/1.4/ref/settings/#admins)`)`
|
||||
* Adds a name and email to the ADMINS tuple in settings. On an error your website will email you logged errors.
|
||||
* `secret_key` `(`[`official documentation`](https://docs.djangoproject.com/en/1.4/ref/settings/#secret-key)`)`
|
||||
* A secure string used to provide cryptographic signing. It is automatically added to a [default Django project](https://docs.djangoproject.com/en/dev/intro/tutorial01/#creating-a-project) in settings.
|
||||
* `captcha_publickey/privatekey`
|
||||
* DJ-BaseSite uses [reCAPTCHA](http://www.google.com/recaptcha/learnmore) to prevent bots from creating accounts, so you'll need to [get a private and public key from the website](http://www.google.com/recaptcha)
|
||||
* `HOSTsmtp`
|
||||
* The SMTP server
|
||||
* `HOSTemail`
|
||||
* The email address
|
||||
* `HOSTpass`
|
||||
* HOSTemail's password
|
@ -69,6 +69,9 @@ dir templates/admin
|
||||
// Activation Email
|
||||
%here%/myproject/myproject/activation_email.html 2
|
||||
|
||||
// Recovery Email
|
||||
%here%/myproject/myproject/recovery_email.html 2
|
||||
|
||||
// HTML/CSS
|
||||
dir static
|
||||
dir static/css
|
||||
@ -80,12 +83,16 @@ dir static/css
|
||||
// Auth
|
||||
dir templates/auth
|
||||
%here%/myproject/myproject/templates/auth/activated.html 2
|
||||
%here%/myproject/myproject/templates/auth/deactivated.html 2
|
||||
%here%/myproject/myproject/templates/auth/disabled.html 2
|
||||
%here%/myproject/myproject/templates/auth/logged_in.html 2
|
||||
%here%/myproject/myproject/templates/auth/logged_out.html 2
|
||||
%here%/myproject/myproject/templates/auth/login.html 2
|
||||
%here%/myproject/myproject/templates/auth/newaccount.html 2
|
||||
%here%/myproject/myproject/templates/auth/registration.html 2
|
||||
%here%/myproject/myproject/templates/auth/recovery.html 2
|
||||
%here%/myproject/myproject/templates/auth/recoveryattempt.html 2
|
||||
%here%/myproject/myproject/templates/auth/recoverysuccess.html 2
|
||||
|
||||
// Backend Django app
|
||||
dir backends root
|
||||
|
@ -1 +1,2 @@
|
||||
@python manage.py runserver
|
||||
@pause
|
||||
|
@ -1 +1,2 @@
|
||||
@python manage.py syncdb
|
||||
@pause
|
||||
|
@ -4,4 +4,6 @@ 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)
|
||||
activate_key = models.CharField(max_length=25, blank=True)
|
||||
recovery_key = models.CharField(max_length=25, blank=True)
|
||||
recovery_time = models.DateTimeField(blank=True)
|
||||
|
5
myproject/myproject/recovery_email.html
Normal file
5
myproject/myproject/recovery_email.html
Normal file
@ -0,0 +1,5 @@
|
||||
Hello <$user>,
|
||||
Seems you have lost access to your account. The recovery link expires at: <$time> UTC
|
||||
Recovery links last 2 hours.
|
||||
|
||||
Recovery link: <$recoverylink>
|
@ -18,6 +18,9 @@ TEMPLATE_DEBUG = DEBUG
|
||||
baseurl = "<%baseurl%>" # "example.com"
|
||||
base_title = "<%basetitle%>"
|
||||
|
||||
# Time zone support
|
||||
USE_TZ = True
|
||||
|
||||
'''
|
||||
You need to sign up at http://recaptcha.net/ for a public/private key to use their CAPTCHA service.
|
||||
'''
|
||||
@ -31,7 +34,8 @@ EMAIL_HOST_USER = "<%HOSTemail%>"
|
||||
EMAIL_HOST_PASSWORD = "<%HOSTpass%>"
|
||||
EMAIL_PORT = 587
|
||||
|
||||
EMAIL_MESSAGE = ROOTDIR + "/<%myproject%>/activation_email.html"
|
||||
ACTIVATE_EMAIL = ROOTDIR + "/<%myproject%>/activation_email.html"
|
||||
RECOVERY_EMAIL = ROOTDIR + "/<%myproject%>/recovery_email.html"
|
||||
|
||||
ADMINS = (
|
||||
("<%admin_name%>", "<%admin_email%>"),
|
||||
|
@ -59,6 +59,11 @@ table.loginform td {
|
||||
.returnlink a:hover {color:#000000;} /* mouse over link */
|
||||
.returnlink a:active {color:#000000;} /* selected link */
|
||||
|
||||
.cannotlogin {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
/* REGISTER CSS */
|
||||
.register_form {
|
||||
text-align: center;
|
||||
|
8
myproject/myproject/templates/auth/deactivated.html
Normal file
8
myproject/myproject/templates/auth/deactivated.html
Normal file
@ -0,0 +1,8 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="activated">
|
||||
The account "{{user_name}}" has been deactivated. No one with this email can reregister unless you contact the admin.
|
||||
<div class="activated_login"><a href="/login/">Login</a></div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -19,7 +19,7 @@
|
||||
<td><input type="text" name="username" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Pass</td>
|
||||
<td>Password</td>
|
||||
<td><input type="password" name="password" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -27,4 +27,8 @@
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
<div class="cannotlogin">
|
||||
<a href="/recovery/">Forgot password?</a> | <a href="/register/">Need an account?</a>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
28
myproject/myproject/templates/auth/recovery.html
Normal file
28
myproject/myproject/templates/auth/recovery.html
Normal file
@ -0,0 +1,28 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>Account Recovery</h1>
|
||||
<form action="/recovery/" method="post">
|
||||
{% csrf_token %}
|
||||
<table class="recovery_form" align="center">
|
||||
<tr>
|
||||
<td>User</td>
|
||||
<td><input type="text" name="usern" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Email</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="Recover"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</form>
|
||||
{% endblock %}
|
30
myproject/myproject/templates/auth/recoveryattempt.html
Normal file
30
myproject/myproject/templates/auth/recoveryattempt.html
Normal file
@ -0,0 +1,30 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>Account Recovery</h1>
|
||||
<form action="/recover/" method="post">
|
||||
<input type="hidden" value="{{the_key|safe}}" name="key" />
|
||||
<input type="hidden" value="{{the_user|safe}}" name="user" />
|
||||
{% csrf_token %}
|
||||
<table class="recovery_form" align="center">
|
||||
<tr>
|
||||
<td>Password</td>
|
||||
<td><input type="password" name="p1" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Password</td>
|
||||
<td><input type="password" name="p2" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" class="humantest">
|
||||
{{captcha_test|safe}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><input type="submit" value="Recover Account"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</form>
|
||||
{% endblock %}
|
7
myproject/myproject/templates/auth/recoverysuccess.html
Normal file
7
myproject/myproject/templates/auth/recoverysuccess.html
Normal file
@ -0,0 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="recoverysuccess">
|
||||
Password successfully changed. Recovery success. Next time just remember your password ;)
|
||||
</div>
|
||||
{% endblock %}
|
@ -21,11 +21,11 @@
|
||||
<td><input type="text" name="usern" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Pass<span class="asterisk">*</span></td>
|
||||
<td>Password<span class="asterisk">*</span></td>
|
||||
<td><input type="password" name="passw" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Pass (again)<span class="asterisk">*</span></td>
|
||||
<td>Password (again)<span class="asterisk">*</span></td>
|
||||
<td><input type="password" name="repassw" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -25,7 +25,9 @@ urlpatterns = patterns('<%myproject%>.views',
|
||||
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.
|
||||
url(r'^deactivate/$', 'deactivate_user'),
|
||||
url(r'^recovery/$', 'recover_user'),
|
||||
url(r'^recover/$', 'recover_attempt')
|
||||
)
|
||||
|
||||
urlpatterns += staticfiles_urlpatterns()
|
@ -68,5 +68,10 @@ def clean_usernameRE(data):
|
||||
else:
|
||||
return False
|
||||
|
||||
def clean_emailRE(data):
|
||||
if match("^[\w\d._%-+]+@[\w\d._%-]+.[\w]{2,6}$", data):
|
||||
return data
|
||||
else:
|
||||
return False
|
||||
|
||||
|
@ -12,10 +12,11 @@ Please take a momemt to read the short 3 Clause LICENSE file.
|
||||
# Built in imports
|
||||
import random
|
||||
import hashlib
|
||||
import datetime
|
||||
|
||||
# Responce imports
|
||||
from django.http import HttpResponseRedirect
|
||||
# response imports
|
||||
from django.shortcuts import render_to_response, RequestContext
|
||||
from django.http import HttpResponseRedirect
|
||||
|
||||
# Authentication/Session/Validation imports
|
||||
from django.contrib.auth import authenticate, login, logout
|
||||
@ -26,12 +27,16 @@ from django.core.exceptions import ObjectDoesNotExist
|
||||
import validation as v
|
||||
import captcha
|
||||
|
||||
# Time related Django imports
|
||||
from django.utils.timezone import now
|
||||
|
||||
# Email imports
|
||||
from django.core.mail import EmailMessage
|
||||
from django.core import mail
|
||||
|
||||
# Variables from Settings.py
|
||||
from settings import EMAIL_HOST_USER, EMAIL_MESSAGE
|
||||
from settings import EMAIL_HOST_USER, ACTIVATE_EMAIL, RECOVERY_EMAIL
|
||||
from settings import captcha_publickey, captcha_privatekey
|
||||
from settings import baseurl, base_title
|
||||
|
||||
# User Profile model
|
||||
@ -55,7 +60,12 @@ def get_or_create_profile(user):
|
||||
try:
|
||||
profile = user.get_profile()
|
||||
except ObjectDoesNotExist:
|
||||
profile = UserProfile(activated=True, user=user)
|
||||
profile = UserProfile(
|
||||
activated=True,
|
||||
recovery_time=now(),
|
||||
user=user
|
||||
)
|
||||
|
||||
profile.save()
|
||||
return profile
|
||||
|
||||
@ -66,8 +76,9 @@ def get_ip(request):
|
||||
else:
|
||||
ip = request.META.get('REMOTE_ADDR')
|
||||
return ip
|
||||
|
||||
|
||||
def UserActivationKey():
|
||||
def KeyGen():
|
||||
random.seed()
|
||||
choices = "abcdefghijklmnopqrstuvwxyzABCDEFG0123456789"
|
||||
|
||||
@ -93,11 +104,12 @@ def index(request):
|
||||
else:
|
||||
user_navigation = user_nav(False)
|
||||
|
||||
responce = render_to_response('index.html', locals())
|
||||
return responce
|
||||
response = render_to_response('index.html', locals())
|
||||
return response
|
||||
|
||||
def logout_user(request):
|
||||
logout(request)
|
||||
user_navigation = user_nav(False)
|
||||
return render_to_response('auth/logged_out.html', locals())
|
||||
|
||||
def login_user(request):
|
||||
@ -136,20 +148,21 @@ def login_user(request):
|
||||
# User account is activated (via email)
|
||||
login(request, user)
|
||||
user_name = user.username
|
||||
responce = render_to_response('auth/logged_in.html', locals())
|
||||
user_navigation = user_nav(user.username)
|
||||
response = 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())
|
||||
response = 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())
|
||||
response = render_to_response('auth/disabled.html', locals())
|
||||
|
||||
else:
|
||||
# No object so the username and password are invalid.
|
||||
login_errors = True
|
||||
responce = render_to_response(
|
||||
response = render_to_response(
|
||||
'auth/login.html',
|
||||
locals(),
|
||||
context_instance=RequestContext(request)
|
||||
@ -157,7 +170,7 @@ def login_user(request):
|
||||
|
||||
else:
|
||||
# User isn't online and hasn't sent any POST data, give them a login form.
|
||||
responce = render_to_response(
|
||||
response = render_to_response(
|
||||
'auth/login.html',
|
||||
locals(),
|
||||
context_instance=RequestContext(request)
|
||||
@ -167,9 +180,9 @@ def login_user(request):
|
||||
# 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())
|
||||
response = render_to_response('error.html',locals())
|
||||
|
||||
return responce
|
||||
return response
|
||||
|
||||
def register_user(request):
|
||||
global base_title
|
||||
@ -261,11 +274,18 @@ def register_user(request):
|
||||
new_user.save()
|
||||
|
||||
# Create activation key and user profile
|
||||
activation_key = UserActivationKey()
|
||||
activation_key = KeyGen()
|
||||
|
||||
# Add 2 hours so a recovery key can be made instantly after
|
||||
# account creation.
|
||||
thetime = new_user.date_joined + datetime.timedelta(hours=2)
|
||||
|
||||
profile = UserProfile(
|
||||
activatekey=activation_key,
|
||||
activate_key=activation_key,
|
||||
activated=False,
|
||||
recovery_time=thetime,
|
||||
user=new_user)
|
||||
|
||||
profile.save()
|
||||
|
||||
# User is created and saved. Send an activation link via email
|
||||
@ -278,13 +298,15 @@ def register_user(request):
|
||||
message_deactivateurl = baseurl+"/deactivate/?key="+str(activation_key)
|
||||
message_deactivateurl = message_deactivateurl+"&user="+str(new_user.username)
|
||||
|
||||
f = open(EMAIL_MESSAGE, 'r')
|
||||
# Open email and replace data
|
||||
f = open(ACTIVATE_EMAIL, 'r')
|
||||
message = f.read()
|
||||
|
||||
message = message.replace("<$user>", str(new_user.username))
|
||||
message = message.replace("<$activatelink>", message_activateurl)
|
||||
message = message.replace("<$disablelink>", message_deactivateurl)
|
||||
|
||||
# Send email
|
||||
email = EmailMessage(
|
||||
"Account Activation",
|
||||
message,
|
||||
@ -297,7 +319,7 @@ def register_user(request):
|
||||
|
||||
# Return new account page
|
||||
accountname = new_user.username
|
||||
responce = render_to_response(
|
||||
response = render_to_response(
|
||||
'auth/newaccount.html',
|
||||
locals(),
|
||||
context_instance=RequestContext(request)
|
||||
@ -305,7 +327,7 @@ def register_user(request):
|
||||
|
||||
else:
|
||||
# Return registration form with errors in registration_errors
|
||||
responce = render_to_response(
|
||||
response = render_to_response(
|
||||
'auth/registration.html',
|
||||
locals(),
|
||||
context_instance=RequestContext(request)
|
||||
@ -313,7 +335,7 @@ def register_user(request):
|
||||
|
||||
# If user hasn't sent POST data (not logged on)
|
||||
else:
|
||||
responce = render_to_response(
|
||||
response = render_to_response(
|
||||
'auth/registration.html',
|
||||
locals(),
|
||||
context_instance=RequestContext(request)
|
||||
@ -323,14 +345,14 @@ def register_user(request):
|
||||
else:
|
||||
user_navigation = user_nav(request.user.username)
|
||||
error = "You cannot register while logged in."
|
||||
responce = render_to_response(
|
||||
response = render_to_response(
|
||||
'error.html',
|
||||
locals()
|
||||
)
|
||||
return responce
|
||||
return response
|
||||
|
||||
def activate_user(request):
|
||||
if request.method == 'GET':
|
||||
if request.method == 'GET' and not request.user.is_authenticated():
|
||||
# Check if data could be valid through regex
|
||||
key = v.clean_key(request.GET["key"])
|
||||
u_name = v.clean_usernameRE(request.GET["user"])
|
||||
@ -341,8 +363,16 @@ def activate_user(request):
|
||||
# Check profile for key and compare.
|
||||
user = User.objects.get(username=u_name)
|
||||
user_profile = get_or_create_profile(user)
|
||||
|
||||
# You're already activated
|
||||
if user_profile.activated:
|
||||
key_correct = False
|
||||
|
||||
# You're disabled.
|
||||
elif user.is_active == False:
|
||||
key_correct = False
|
||||
|
||||
if user_profile.activatekey == key:
|
||||
elif user_profile.activate_key == key:
|
||||
# Activate user
|
||||
user_profile.activated = True
|
||||
user_profile.save()
|
||||
@ -355,17 +385,295 @@ def activate_user(request):
|
||||
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()
|
||||
)
|
||||
user_navigation = user_nav(False)
|
||||
|
||||
if key_correct:
|
||||
user_name = user.username
|
||||
response = render_to_response(
|
||||
'auth/activated.html',
|
||||
locals()
|
||||
)
|
||||
else:
|
||||
error = "Activation failed."
|
||||
response = render_to_response(
|
||||
'error.html',
|
||||
locals()
|
||||
)
|
||||
|
||||
return responce
|
||||
return response
|
||||
|
||||
# Logged on or didn't give GET data.
|
||||
return HttpResponseRedirect('/')
|
||||
|
||||
def deactivate_user(request):
|
||||
if request.method == 'GET' and not request.user.is_authenticated():
|
||||
# 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 you wish to have your users deactivate with the same
|
||||
# link sent in activation, remove this if statement
|
||||
if user_profile.activated:
|
||||
key_correct = False
|
||||
|
||||
|
||||
elif user_profile.activate_key == key:
|
||||
# Disable account.
|
||||
user_profile.activated = False
|
||||
user_profile.save()
|
||||
|
||||
user.is_active = False
|
||||
user.save()
|
||||
|
||||
key_correct = True
|
||||
else:
|
||||
key_correct = False
|
||||
|
||||
except ObjectDoesNotExist:
|
||||
key_correct = False
|
||||
else:
|
||||
key_correct = False
|
||||
|
||||
if key_correct:
|
||||
user_name = user.username
|
||||
response = render_to_response(
|
||||
'auth/deactivated.html',
|
||||
locals()
|
||||
)
|
||||
else:
|
||||
error = "Deactivation failed."
|
||||
response = render_to_response(
|
||||
'error.html',
|
||||
locals()
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
# Logged on or didn't give GET data.
|
||||
return HttpResponseRedirect('/')
|
||||
|
||||
def recover_user(request):
|
||||
global base_title
|
||||
global global_nav, user_nav
|
||||
|
||||
title = base_title + "Recovery"
|
||||
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.
|
||||
captcha_test = captcha.displayhtml(captcha_publickey)
|
||||
|
||||
# If user has sent POST data (not logged in)
|
||||
if request.method == 'POST':
|
||||
# Check info via regex
|
||||
u_name = v.clean_usernameRE(request.POST["usern"])
|
||||
email = v.clean_emailRE(request.POST["email"])
|
||||
|
||||
|
||||
if email == request.POST["email"] and u_name:
|
||||
try:
|
||||
user = User.objects.get(username__iexact=u_name)
|
||||
user_profile = get_or_create_profile(user)
|
||||
|
||||
# Current time
|
||||
time_now = now()
|
||||
|
||||
# Recovery time
|
||||
recovery_time = user_profile.recovery_time
|
||||
|
||||
if time_now > recovery_time:
|
||||
# Key has been requested too many times in 2 hours.
|
||||
error = "Recovery keys can only be requested once every 2 hours."
|
||||
response = render_to_response(
|
||||
'error.html',
|
||||
locals()
|
||||
)
|
||||
else:
|
||||
# Connect to SMTP server
|
||||
connection = mail.get_connection()
|
||||
connection.open()
|
||||
|
||||
# Create a recovery key
|
||||
user_profile.recovery_key = KeyGen()
|
||||
user_profile.save()
|
||||
|
||||
# Create account recovery link
|
||||
message_recoveryurl = baseurl+"/recover/?key="+str(user_profile.recovery_key)
|
||||
message_recoveryurl = message_recoveryurl+"&user="+str(user.username)
|
||||
|
||||
|
||||
# Open email template
|
||||
f = open(RECOVERY_EMAIL, 'r')
|
||||
message = f.read()
|
||||
print message
|
||||
|
||||
# Replace information
|
||||
message = message.replace("<$user>", str(user.username))
|
||||
message = message.replace("<$recoverylink>", message_recoveryurl)
|
||||
message = message.replace("<$time>", str(user_profile.recovery_time))
|
||||
|
||||
# Send email
|
||||
email = EmailMessage(
|
||||
"Account Recovery",
|
||||
message,
|
||||
EMAIL_HOST_USER,
|
||||
[user.email]
|
||||
)
|
||||
|
||||
email.send()
|
||||
connection.close()
|
||||
|
||||
# Tell user to check their email.
|
||||
error = "Check your email for a recovery link."
|
||||
response = render_to_response(
|
||||
'error.html',
|
||||
locals()
|
||||
)
|
||||
|
||||
except User.DoesNotExist:
|
||||
error = "No user with that email exists."
|
||||
response = render_to_response(
|
||||
'error.html',
|
||||
locals()
|
||||
)
|
||||
else:
|
||||
error = "No user with that email exists."
|
||||
response = render_to_response(
|
||||
'error.html',
|
||||
locals()
|
||||
)
|
||||
else:
|
||||
# Didn't submit, give recovery form.
|
||||
response = render_to_response(
|
||||
'auth/recovery.html',
|
||||
locals(),
|
||||
context_instance=RequestContext(request)
|
||||
)
|
||||
# You're signed in, no recovery for you.
|
||||
else:
|
||||
return HttpResponseRedirect('/')
|
||||
|
||||
return response
|
||||
|
||||
def recover_attempt(request):
|
||||
global base_title
|
||||
global global_nav, user_nav
|
||||
|
||||
title = base_title + "Recovery"
|
||||
global_navigation=global_nav()
|
||||
|
||||
# If user is not logged on
|
||||
if request.method == 'GET' and not request.user.is_authenticated():
|
||||
# Check if data could be valid through regex
|
||||
key = v.clean_key(request.GET["key"])
|
||||
u_name = v.clean_usernameRE(request.GET["user"])
|
||||
|
||||
|
||||
# If valid data
|
||||
if request.GET["key"] == key and u_name:
|
||||
# return new password form
|
||||
the_user = u_name
|
||||
the_key = key
|
||||
response = render_to_response(
|
||||
'auth/recoveryattempt.html',
|
||||
locals(),
|
||||
context_instance=RequestContext(request)
|
||||
)
|
||||
else:
|
||||
error = "User does not exist."
|
||||
response = render_to_response(
|
||||
'error.html',
|
||||
locals()
|
||||
)
|
||||
|
||||
# If user isn't online and is sending post data
|
||||
elif request.method == 'POST' and not request.user.is_authenticated():
|
||||
# Check if data could be valid through regex
|
||||
key = v.clean_key(request.POST["key"])
|
||||
u_name = v.clean_usernameRE(request.POST["user"])
|
||||
|
||||
# If key/username is validated by regex
|
||||
if request.POST["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)
|
||||
|
||||
# Get database key and key time limit
|
||||
key_db = user_profile.recovery_key
|
||||
keylimit_db = user_profile.recovery_time
|
||||
|
||||
# Current time
|
||||
time_now = now()
|
||||
|
||||
# If the key hasn't expired and is correct
|
||||
if now() < keylimit_db and key_db == key:
|
||||
|
||||
password = v.clean_password(request.POST["p1"])
|
||||
|
||||
recover_error = ""
|
||||
if not request.POST["p1"] == request.POST["p2"]:
|
||||
recover_error = "Passwords don't match."
|
||||
elif password == None:
|
||||
recover_error = "No password entered."
|
||||
elif password == -1:
|
||||
recover_error = "Passwords have to be at least 5 characters."
|
||||
|
||||
# If there is an error
|
||||
if recover_error != '':
|
||||
# Set error variable for template
|
||||
error = recover_error
|
||||
|
||||
response = render_to_response(
|
||||
'error.html',
|
||||
locals()
|
||||
)
|
||||
else:
|
||||
# No errors, change password
|
||||
user.set_password(password)
|
||||
user.save()
|
||||
|
||||
# Expire recovery time.
|
||||
user_profile.recovery_time = now()
|
||||
user_profile.save()
|
||||
|
||||
response = render_to_response(
|
||||
'auth/recoverysuccess.html',
|
||||
locals()
|
||||
)
|
||||
else:
|
||||
error = "Invalid key and/or username."
|
||||
response = render_to_response(
|
||||
'error.html',
|
||||
locals()
|
||||
)
|
||||
except User.DoesNotExist:
|
||||
error = "User doesn't exist."
|
||||
response = render_to_response(
|
||||
'error.html',
|
||||
locals()
|
||||
)
|
||||
else:
|
||||
error = "Invalid key and/or username."
|
||||
response = render_to_response(
|
||||
'error.html',
|
||||
locals()
|
||||
)
|
||||
else:
|
||||
# logged on, no recovery.
|
||||
return HttpResponseRedirect('/')
|
||||
|
||||
return response
|
||||
|
Loading…
Reference in New Issue
Block a user