Compare commits
8 Commits
abecc430a9
...
c79cb36f23
Author | SHA1 | Date | |
---|---|---|---|
c79cb36f23 | |||
cba4094e2b | |||
10ccab21eb | |||
53bb7c4d75 | |||
0cfb4eb697 | |||
6e700359ce | |||
8df4347932 | |||
1b8ee3d0f3 |
|
@ -4,7 +4,7 @@ By popular demand, I'm building a better anonkun. It doesn't do much right now t
|
|||
## Requirements
|
||||
Python 3.6+
|
||||
PostgreSQL 10.4+
|
||||
Python packages: `django psycopg2 channels jinja2`
|
||||
Python packages: `django psycopg2 channels jinja2 argon2-cffi`
|
||||
|
||||
## Install
|
||||
```
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
/create_quest app views.
|
||||
"""
|
||||
from django.shortcuts import render
|
||||
from django.contrib.auth.decorators import login_required
|
||||
|
||||
@login_required(login_url='/login/')
|
||||
def index(request):
|
||||
"""
|
||||
The index page for creating new quests.
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
{% block content %}
|
||||
<h1>Quests 'n Shiet</h1>
|
||||
<a href="./quest/1">Unga Bunga Quest</a><br />
|
||||
<a href="./create_quest">Create New Quest</a><br />
|
||||
<a href="./signup">Sign up</a><br />
|
||||
<a href="./login">Login</a><br />
|
||||
<a href="{{ url('create_quest:index') }}">Create New Quest</a><br />
|
||||
<a href="{{ url('signup:index') }}">Sign up</a><br />
|
||||
<a href="{{ url('login:index') }}">Login</a><br />
|
||||
<a href="{{ url('logout:index') }}">Logout</a><br />
|
||||
{% endblock %}
|
||||
|
|
|
@ -36,6 +36,14 @@
|
|||
<ul id="headerHidden" class="header" style="{% if request.session.get("hide_header") == True %}display:initial;{% else %}display:none;{% endif %}">
|
||||
<li><a onclick="toggleHeader();" href="javascript:void(0);">⤓</a></li>
|
||||
</ul>
|
||||
<br /> <!-- TODO: make this more exact. -->
|
||||
<div id="messages">
|
||||
<ul class="messages">
|
||||
{% for message in get_messages(request) %}
|
||||
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
<div id="content">{% block content %}{% endblock %} </div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
0
login/__init__.py
Normal file
0
login/__init__.py
Normal file
3
login/admin.py
Normal file
3
login/admin.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
5
login/apps.py
Normal file
5
login/apps.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class LoginConfig(AppConfig):
|
||||
name = 'login'
|
11
login/jinja2/login/index.html
Normal file
11
login/jinja2/login/index.html
Normal file
|
@ -0,0 +1,11 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}Login{% endblock %}
|
||||
{% block content %}
|
||||
<h1>Login</h1>
|
||||
<form method="post" action="{{ url('login:index') }}">
|
||||
{{ csrf_input }}
|
||||
<input type="text" placeholder="Username" name="username" maxlength="20" required/><br />
|
||||
<input type="password" placeholder="Password" name="password" maxlength="1024" required/><br />
|
||||
<input type="submit" value="Log in" name="submit"/>
|
||||
</form>
|
||||
{% endblock %}
|
0
login/migrations/__init__.py
Normal file
0
login/migrations/__init__.py
Normal file
3
login/models.py
Normal file
3
login/models.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from django.db import models
|
||||
|
||||
# Create your models here.
|
3
login/tests.py
Normal file
3
login/tests.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
12
login/urls.py
Normal file
12
login/urls.py
Normal file
|
@ -0,0 +1,12 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Login app URL configuration.
|
||||
"""
|
||||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
app_name = 'login'
|
||||
urlpatterns = [
|
||||
path('', views.index, name='index'),
|
||||
]
|
25
login/views.py
Normal file
25
login/views.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
/login app views.
|
||||
"""
|
||||
from django.contrib import messages
|
||||
from django.shortcuts import redirect, render
|
||||
from django.contrib.auth import authenticate, login
|
||||
|
||||
def index(request):
|
||||
"""
|
||||
The login page.
|
||||
"""
|
||||
if request.method == "GET":
|
||||
context = {}
|
||||
return render(request, 'login/index.html', context)
|
||||
username = request.POST['username']
|
||||
password = request.POST['password']
|
||||
user = authenticate(request, username=username, password=password)
|
||||
if user is not None:
|
||||
login(request, user)
|
||||
messages.success(request, "Logged in")
|
||||
return redirect('homepage:index')
|
||||
else:
|
||||
messages.error(request, "Invalid credentials")
|
||||
return redirect('login:index')
|
0
logout/__init__.py
Normal file
0
logout/__init__.py
Normal file
3
logout/admin.py
Normal file
3
logout/admin.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
5
logout/apps.py
Normal file
5
logout/apps.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class LogoutConfig(AppConfig):
|
||||
name = 'logout'
|
0
logout/migrations/__init__.py
Normal file
0
logout/migrations/__init__.py
Normal file
3
logout/models.py
Normal file
3
logout/models.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from django.db import models
|
||||
|
||||
# Create your models here.
|
3
logout/tests.py
Normal file
3
logout/tests.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
12
logout/urls.py
Normal file
12
logout/urls.py
Normal file
|
@ -0,0 +1,12 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Logout app URL configuration.
|
||||
"""
|
||||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
app_name = 'logout'
|
||||
urlpatterns = [
|
||||
path('', views.index, name='index'),
|
||||
]
|
15
logout/views.py
Normal file
15
logout/views.py
Normal file
|
@ -0,0 +1,15 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
/logout app views.
|
||||
"""
|
||||
from django.contrib import messages
|
||||
from django.shortcuts import redirect
|
||||
from django.contrib.auth import logout
|
||||
|
||||
def index(request):
|
||||
"""
|
||||
Logs the user out.
|
||||
"""
|
||||
logout(request)
|
||||
messages.success(request, "Logged out")
|
||||
return redirect('homepage:index')
|
0
signup/__init__.py
Normal file
0
signup/__init__.py
Normal file
3
signup/admin.py
Normal file
3
signup/admin.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
5
signup/apps.py
Normal file
5
signup/apps.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class SignupConfig(AppConfig):
|
||||
name = 'signup'
|
24
signup/jinja2/signup/index.html
Normal file
24
signup/jinja2/signup/index.html
Normal file
|
@ -0,0 +1,24 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}Sign up a new account{% endblock %}
|
||||
{% block content %}
|
||||
<h1>Sign up</h1>
|
||||
<div id="namePassRules">
|
||||
<p>Username rules:
|
||||
<ul>
|
||||
<li>Must be between 3 and 20 characters</li>
|
||||
<li>Can only contain ASCII letters (case sensitive) and numbers</li>
|
||||
</ul>
|
||||
<p>Password rules:
|
||||
<ul>
|
||||
<li>Must be between 8 and 1024 characters</li>
|
||||
</ul>
|
||||
</div>
|
||||
<form method="post" action="{{ url('signup:index') }}">
|
||||
{{ csrf_input }}
|
||||
<input type="text" placeholder="Username" name="username" maxlength="20" required/><br />
|
||||
<input type="text" placeholder="Email" name="email" maxlength="20" required/><br />
|
||||
<input type="password" placeholder="Password" name="password" maxlength="1024" required/><br />
|
||||
<input type="password" placeholder="Verify password" name="password_verify" maxlength="1024" required/><br />
|
||||
<input type="submit" value="Sign up" name="submit"/>
|
||||
</form>
|
||||
{% endblock %}
|
0
signup/migrations/__init__.py
Normal file
0
signup/migrations/__init__.py
Normal file
3
signup/models.py
Normal file
3
signup/models.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from django.db import models
|
||||
|
||||
# Create your models here.
|
3
signup/tests.py
Normal file
3
signup/tests.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
12
signup/urls.py
Normal file
12
signup/urls.py
Normal file
|
@ -0,0 +1,12 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
signup app URL configuration.
|
||||
"""
|
||||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
app_name = 'signup'
|
||||
urlpatterns = [
|
||||
path('', views.index, name='index'),
|
||||
]
|
13
signup/views.py
Normal file
13
signup/views.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
/signup app views.
|
||||
"""
|
||||
from django.shortcuts import render
|
||||
|
||||
def index(request):
|
||||
"""
|
||||
The signup page.
|
||||
"""
|
||||
if request.method == "GET":
|
||||
context = {}
|
||||
return render(request, 'signup/index.html', context)
|
|
@ -3,8 +3,9 @@
|
|||
Custom Jinja2 environment.
|
||||
"""
|
||||
import jinja2
|
||||
from django.contrib.staticfiles.storage import staticfiles_storage
|
||||
from django.urls import reverse
|
||||
from django.contrib import messages
|
||||
from django.contrib.staticfiles.storage import staticfiles_storage
|
||||
|
||||
def environment(**options):
|
||||
"""
|
||||
|
@ -12,11 +13,13 @@ def environment(**options):
|
|||
"""
|
||||
env = jinja2.Environment(**options)
|
||||
env.globals.update({
|
||||
'static': staticfiles_storage.url,
|
||||
'url': reverse,
|
||||
'undefined': jinja2.StrictUndefined,
|
||||
'autoescape': True,
|
||||
'trim_blocks': True,
|
||||
'lstrip_blocks': True,
|
||||
|
||||
'url': reverse,
|
||||
'static': staticfiles_storage.url,
|
||||
'get_messages': messages.get_messages,
|
||||
})
|
||||
return env
|
||||
|
|
|
@ -31,9 +31,12 @@ INSTALLED_APPS = [
|
|||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'quest.apps.QuestConfig',
|
||||
'users.apps.UsersConfig',
|
||||
'homepage.apps.HomepageConfig',
|
||||
'create_quest.apps.CreateQuestConfig',
|
||||
'quest.apps.QuestConfig',
|
||||
'login.apps.LoginConfig',
|
||||
'signup.apps.SignupConfig',
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
|
@ -58,6 +61,19 @@ TEMPLATES = [
|
|||
'auto_reload': DEBUG,
|
||||
},
|
||||
},
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
'django.template.context_processors.debug',
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
WSGI_APPLICATION = 'titivillus.wsgi.application'
|
||||
|
@ -87,6 +103,9 @@ AUTH_PASSWORD_VALIDATORS = [
|
|||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||
'OPTIONS': {
|
||||
'min_length': 8,
|
||||
}
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||||
|
@ -119,3 +138,12 @@ STATIC_ROOT = '/usr/local/www/html/static/'
|
|||
STATICFILES_DIRS = [
|
||||
os.path.join(BASE_DIR, 'static'),
|
||||
]
|
||||
|
||||
AUTH_USER_MODEL = 'users.User'
|
||||
|
||||
PASSWORD_HASHERS = [
|
||||
'django.contrib.auth.hashers.Argon2PasswordHasher',
|
||||
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
|
||||
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
|
||||
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
|
||||
]
|
||||
|
|
|
@ -11,4 +11,7 @@ urlpatterns = [
|
|||
path('quest/', include('quest.urls')),
|
||||
path('create_quest/', include('create_quest.urls')),
|
||||
path('set_session/', include('set_session.urls')),
|
||||
path('signup/', include('signup.urls')),
|
||||
path('login/', include('login.urls')),
|
||||
path('logout/', include('logout.urls')),
|
||||
]
|
||||
|
|
0
users/__init__.py
Normal file
0
users/__init__.py
Normal file
3
users/admin.py
Normal file
3
users/admin.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
5
users/apps.py
Normal file
5
users/apps.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class UsersConfig(AppConfig):
|
||||
name = 'users'
|
42
users/migrations/0001_initial.py
Normal file
42
users/migrations/0001_initial.py
Normal file
|
@ -0,0 +1,42 @@
|
|||
# Generated by Django 2.0.7 on 2018-08-10 20:30
|
||||
|
||||
import django.contrib.auth.models
|
||||
import django.contrib.auth.validators
|
||||
from django.db import migrations, models
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('auth', '0009_alter_user_last_name_max_length'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='User',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('password', models.CharField(max_length=128, verbose_name='password')),
|
||||
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
|
||||
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
|
||||
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
|
||||
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
|
||||
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
|
||||
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 20 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=20, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
|
||||
('email', models.EmailField(max_length=254, verbose_name='email address')),
|
||||
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
|
||||
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'user',
|
||||
'verbose_name_plural': 'users',
|
||||
'abstract': False,
|
||||
},
|
||||
managers=[
|
||||
('objects', django.contrib.auth.models.UserManager()),
|
||||
],
|
||||
),
|
||||
]
|
0
users/migrations/__init__.py
Normal file
0
users/migrations/__init__.py
Normal file
32
users/models.py
Normal file
32
users/models.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
A custom user model.
|
||||
"""
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import AbstractUser
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.contrib.auth.validators import UnicodeUsernameValidator
|
||||
|
||||
class User(AbstractUser):
|
||||
"""
|
||||
A custom user model.
|
||||
"""
|
||||
username_validator = UnicodeUsernameValidator()
|
||||
username = models.CharField(
|
||||
_('username'),
|
||||
max_length=20,
|
||||
unique=True,
|
||||
help_text=_("Required. 20 characters or fewer. "
|
||||
+ "Letters, digits and @/./+/-/_ only."),
|
||||
validators=[username_validator],
|
||||
error_messages={
|
||||
'unique': _("A user with that username already exists."),
|
||||
},)
|
||||
first_name = None
|
||||
last_name = None
|
||||
email = models.EmailField(_('email address'))
|
||||
|
||||
def get_full_name(self):
|
||||
return None
|
||||
def get_short_name(self):
|
||||
return None
|
3
users/tests.py
Normal file
3
users/tests.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
3
users/views.py
Normal file
3
users/views.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
Loading…
Reference in New Issue
Block a user