forked from enviPath/enviPy
feature/enforce_login (#32)
Co-authored-by: Tim Lorsbach <tim@lorsba.ch> Reviewed-on: enviPath/enviPy#32
This commit is contained in:
@ -62,6 +62,9 @@ MIDDLEWARE = [
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
]
|
||||
|
||||
if os.environ.get('REGISTRATION_MANDATORY', False) == 'True':
|
||||
MIDDLEWARE.append('epdb.middleware.login_required_middleware.LoginRequiredMiddleware')
|
||||
|
||||
ROOT_URLCONF = 'envipath.urls'
|
||||
|
||||
TEMPLATES = [
|
||||
@ -147,7 +150,7 @@ ADMIN_APPROVAL_REQUIRED = os.environ.get('ADMIN_APPROVAL_REQUIRED', 'False') ==
|
||||
# SESAME_MAX_AGE = 300
|
||||
# # TODO set to "home"
|
||||
# LOGIN_REDIRECT_URL = "/"
|
||||
# LOGIN_URL = '/login/'
|
||||
LOGIN_URL = '/login/'
|
||||
|
||||
SERVER_URL = os.environ.get('SERVER_URL', 'http://localhost:8000')
|
||||
|
||||
|
||||
0
epdb/middleware/__init__.py
Normal file
0
epdb/middleware/__init__.py
Normal file
21
epdb/middleware/login_required_middleware.py
Normal file
21
epdb/middleware/login_required_middleware.py
Normal file
@ -0,0 +1,21 @@
|
||||
from django.conf import settings
|
||||
from django.shortcuts import redirect
|
||||
from django.urls import reverse
|
||||
|
||||
|
||||
class LoginRequiredMiddleware:
|
||||
def __init__(self, get_response):
|
||||
self.get_response = get_response
|
||||
self.exempt_urls = [
|
||||
reverse('login'),
|
||||
reverse('logout'),
|
||||
reverse('admin:login'),
|
||||
reverse('admin:index'),
|
||||
] + getattr(settings, 'LOGIN_EXEMPT_URLS', [])
|
||||
|
||||
def __call__(self, request):
|
||||
if not request.user.is_authenticated:
|
||||
path = request.path_info
|
||||
if not any(path.startswith(url) for url in self.exempt_urls):
|
||||
return redirect(settings.LOGIN_URL)
|
||||
return self.get_response(request)
|
||||
@ -13,7 +13,8 @@ urlpatterns = [
|
||||
# Home
|
||||
re_path(r'^$', v.index, name='index'),
|
||||
|
||||
# re_path(r'^login', v.login, name='login'),
|
||||
re_path(r'^login', v.login, name='login'),
|
||||
re_path(r'^logout', v.logout, name='logout'),
|
||||
|
||||
# Top level urls
|
||||
re_path(r'^package$', v.packages, name='packages'),
|
||||
|
||||
154
epdb/views.py
154
epdb/views.py
@ -8,7 +8,6 @@ from django.contrib.auth import get_user_model
|
||||
from django.http import JsonResponse, HttpResponse, HttpResponseNotAllowed, HttpResponseBadRequest
|
||||
from django.shortcuts import render, redirect
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.contrib.auth.decorators import login_required
|
||||
|
||||
from utilities.chem import FormatConverter, IndigoUtils
|
||||
from .logic import GroupManager, PackageManager, UserManager, SettingManager, SearchManager
|
||||
@ -18,12 +17,81 @@ from .models import Package, GroupPackagePermission, Group, CompoundStructure, C
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def log_post_params(request):
|
||||
if s.DEBUG:
|
||||
for k, v in request.POST.items():
|
||||
logger.debug(f"{k}\t{v}")
|
||||
|
||||
|
||||
def login(request):
|
||||
current_user = _anonymous_or_real(request)
|
||||
context = get_base_context(request)
|
||||
|
||||
if request.method == 'GET':
|
||||
context['title'] = 'enviPath'
|
||||
return render(request, 'login.html', context)
|
||||
|
||||
elif request.method == 'POST':
|
||||
is_login = bool(request.POST.get('login', False))
|
||||
is_register = bool(request.POST.get('register', False))
|
||||
|
||||
if is_login:
|
||||
from django.contrib.auth import authenticate
|
||||
from django.contrib.auth import login
|
||||
|
||||
username = request.POST.get('username')
|
||||
password = request.POST.get('password')
|
||||
|
||||
# Get email for username and check if account is active
|
||||
try:
|
||||
temp_user = get_user_model().objects.get(username=username)
|
||||
|
||||
if not temp_user.is_active:
|
||||
context['message'] = "User account is not activated yet!"
|
||||
return render(request, 'login.html', context)
|
||||
|
||||
email = temp_user.email
|
||||
except get_user_model().DoesNotExist:
|
||||
context['message'] = "Login failed!"
|
||||
return render(request, 'login.html', context)
|
||||
|
||||
user = authenticate(username=email, password=password)
|
||||
|
||||
if user is not None:
|
||||
login(request, user)
|
||||
return redirect(s.SERVER_URL)
|
||||
else:
|
||||
context['message'] = "Login failed!"
|
||||
return render(request, 'login.html', context)
|
||||
|
||||
elif is_register:
|
||||
username = request.POST.get('username')
|
||||
email = request.POST.get('email')
|
||||
password = request.POST.get('password')
|
||||
rpassword = request.POST.get('rpassword')
|
||||
|
||||
if password != rpassword:
|
||||
pass
|
||||
|
||||
u = UserManager.create_user(username, email, password)
|
||||
|
||||
context['message'] = "Your account has been created! An admin will activate it soon!"
|
||||
return render(request, 'login.html', context)
|
||||
|
||||
|
||||
def logout(request):
|
||||
if request.method == 'POST':
|
||||
is_logout = bool(request.POST.get('logout', False))
|
||||
|
||||
if is_logout:
|
||||
from django.contrib.auth import logout
|
||||
logout(request)
|
||||
return redirect(s.SERVER_URL)
|
||||
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
|
||||
def catch_exceptions(view_func):
|
||||
@wraps(view_func)
|
||||
def _wrapped_view(request, *args, **kwargs):
|
||||
@ -38,6 +106,7 @@ def catch_exceptions(view_func):
|
||||
)
|
||||
else:
|
||||
return render(request, 'errors/error.html', get_base_context(request))
|
||||
|
||||
return _wrapped_view
|
||||
|
||||
|
||||
@ -60,7 +129,6 @@ def editable(request, user):
|
||||
return False
|
||||
|
||||
|
||||
|
||||
def get_base_context(request) -> Dict[str, Any]:
|
||||
current_user = _anonymous_or_real(request)
|
||||
|
||||
@ -121,16 +189,6 @@ def index(request):
|
||||
return render(request, 'index/index.html', context)
|
||||
|
||||
|
||||
# def login(request):
|
||||
# current_user = _anonymous_or_real(request)
|
||||
# if request.method == 'GET':
|
||||
# context = get_base_context(request)
|
||||
# context['title'] = 'enviPath'
|
||||
# return render(request, 'login.html', context)
|
||||
# else:
|
||||
# return HttpResponseBadRequest()
|
||||
#
|
||||
# @login_required(login_url='/login')
|
||||
def packages(request):
|
||||
current_user = _anonymous_or_real(request)
|
||||
|
||||
@ -688,6 +746,7 @@ def package(request, package_uuid):
|
||||
else:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
|
||||
# https://envipath.org/package/<id>/compound
|
||||
def package_compounds(request, package_uuid):
|
||||
current_user = _anonymous_or_real(request)
|
||||
@ -814,6 +873,7 @@ def package_compound_structures(request, package_uuid, compound_uuid):
|
||||
else:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
|
||||
# https://envipath.org/package/<id>/compound/<id>/structure/<id>
|
||||
def package_compound_structure(request, package_uuid, compound_uuid, structure_uuid):
|
||||
current_user = _anonymous_or_real(request)
|
||||
@ -893,12 +953,14 @@ def package_rules(request, package_uuid):
|
||||
else:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
r = Rule.create(rule_type=rule_type, package=current_package, name=rule_name, description=rule_description, **params)
|
||||
r = Rule.create(rule_type=rule_type, package=current_package, name=rule_name, description=rule_description,
|
||||
**params)
|
||||
return redirect(r.url)
|
||||
|
||||
else:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
|
||||
# https://envipath.org/package/<id>/rule/<id>
|
||||
def package_rule(request, package_uuid, rule_uuid):
|
||||
current_user = _anonymous_or_real(request)
|
||||
@ -945,6 +1007,7 @@ def package_rule(request, package_uuid, rule_uuid):
|
||||
else:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
|
||||
# https://envipath.org/package/<id>/reaction
|
||||
def package_reactions(request, package_uuid):
|
||||
current_user = _anonymous_or_real(request)
|
||||
@ -995,6 +1058,7 @@ def package_reactions(request, package_uuid):
|
||||
else:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
|
||||
# https://envipath.org/package/<id>/reaction/<id>
|
||||
def package_reaction(request, package_uuid, reaction_uuid):
|
||||
current_user = _anonymous_or_real(request)
|
||||
@ -1039,6 +1103,7 @@ def package_reaction(request, package_uuid, reaction_uuid):
|
||||
else:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
|
||||
# https://envipath.org/package/<id>/pathway
|
||||
def package_pathways(request, package_uuid):
|
||||
current_user = _anonymous_or_real(request)
|
||||
@ -1115,6 +1180,7 @@ def package_pathways(request, package_uuid):
|
||||
else:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
|
||||
# https://envipath.org/package/<id>/pathway/<id>
|
||||
def package_pathway(request, package_uuid, pathway_uuid):
|
||||
current_user: User = _anonymous_or_real(request)
|
||||
@ -1186,6 +1252,7 @@ def package_pathway(request, package_uuid, pathway_uuid):
|
||||
else:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
|
||||
# https://envipath.org/package/<id>/pathway/<id>/node
|
||||
def package_pathway_nodes(request, package_uuid, pathway_uuid):
|
||||
current_user = _anonymous_or_real(request)
|
||||
@ -1452,49 +1519,6 @@ def users(request):
|
||||
|
||||
return render(request, 'collections/objects_list.html', context)
|
||||
|
||||
if request.method == 'POST':
|
||||
is_login = bool(request.POST.get('login', False))
|
||||
is_register = bool(request.POST.get('register', False))
|
||||
|
||||
if is_login:
|
||||
from django.contrib.auth import authenticate
|
||||
from django.contrib.auth import login
|
||||
|
||||
username = request.POST.get('username')
|
||||
password = request.POST.get('password')
|
||||
|
||||
# Get email for username and check if account is active
|
||||
try:
|
||||
temp_user = get_user_model().objects.get(username=username)
|
||||
|
||||
if not temp_user.is_active:
|
||||
return render(request, 'errors/user_account_inactive.html', status=403)
|
||||
|
||||
email = temp_user.email
|
||||
except get_user_model().DoesNotExist:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
user = authenticate(username=email, password=password)
|
||||
|
||||
if user is not None:
|
||||
login(request, user)
|
||||
return redirect(s.SERVER_URL)
|
||||
else:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
elif is_register:
|
||||
username = request.POST.get('username')
|
||||
email = request.POST.get('email')
|
||||
password = request.POST.get('password')
|
||||
rpassword = request.POST.get('rpassword')
|
||||
|
||||
if password != rpassword:
|
||||
pass
|
||||
|
||||
u = UserManager.create_user(username, email, password)
|
||||
|
||||
return redirect(s.SERVER_URL)
|
||||
|
||||
|
||||
def user(request, user_uuid):
|
||||
current_user = _anonymous_or_real(request)
|
||||
@ -1551,14 +1575,6 @@ def user(request, user_uuid):
|
||||
|
||||
return HttpResponse("success")
|
||||
|
||||
|
||||
is_logout = bool(request.POST.get('logout', False))
|
||||
|
||||
if is_logout:
|
||||
from django.contrib.auth import logout
|
||||
logout(request)
|
||||
return redirect(s.SERVER_URL)
|
||||
|
||||
default_package = request.POST.get('default-package')
|
||||
default_group = request.POST.get('default-group')
|
||||
default_prediction_setting = request.POST.get('default-prediction-setting')
|
||||
@ -1652,7 +1668,8 @@ def group(request, group_uuid):
|
||||
context['users'] = get_user_model().objects.exclude(id__in=current_group.user_member.all())
|
||||
context['groups'] = Group.objects.exclude(id__in=current_group.group_member.all()).exclude(id=current_group.pk)
|
||||
|
||||
context['packages'] = Package.objects.filter(id__in=GroupPackagePermission.objects.filter(group=current_group).values('package').distinct())
|
||||
context['packages'] = Package.objects.filter(
|
||||
id__in=GroupPackagePermission.objects.filter(group=current_group).values('package').distinct())
|
||||
|
||||
return render(request, 'objects/group.html', context)
|
||||
|
||||
@ -1682,6 +1699,7 @@ def group(request, group_uuid):
|
||||
|
||||
return redirect(current_group.url)
|
||||
|
||||
|
||||
def settings(request):
|
||||
current_user = _anonymous_or_real(request)
|
||||
context = get_base_context(request)
|
||||
@ -1705,8 +1723,10 @@ def settings(request):
|
||||
description = request.POST.get('prediction-setting-description')
|
||||
new_default = request.POST.get('prediction-setting-new-default', 'off') == 'on'
|
||||
|
||||
max_nodes = min(max(int(request.POST.get('prediction-setting-max-nodes', 1)), s.DEFAULT_MAX_NUMBER_OF_NODES), s.DEFAULT_MAX_NUMBER_OF_NODES)
|
||||
max_depth = min(max(int(request.POST.get('prediction-setting-max-depth', 1)), s.DEFAULT_MAX_DEPTH), s.DEFAULT_MAX_DEPTH)
|
||||
max_nodes = min(max(int(request.POST.get('prediction-setting-max-nodes', 1)), s.DEFAULT_MAX_NUMBER_OF_NODES),
|
||||
s.DEFAULT_MAX_NUMBER_OF_NODES)
|
||||
max_depth = min(max(int(request.POST.get('prediction-setting-max-depth', 1)), s.DEFAULT_MAX_DEPTH),
|
||||
s.DEFAULT_MAX_DEPTH)
|
||||
|
||||
tp_gen_method = request.POST.get('tp-generation-method')
|
||||
|
||||
|
||||
@ -152,7 +152,7 @@
|
||||
</li>
|
||||
<li class="divider"></li>
|
||||
<form class="navbar-form navbar-left navbar-left-framework" role="logout"
|
||||
action="{{ meta.user.url }}" method="post">
|
||||
action="{% url 'logout' %}" method="post">
|
||||
{% csrf_token %}
|
||||
<div class="form-group">
|
||||
<input type="hidden" name="logout" value="true">
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Login Modal with Blur</title>
|
||||
<title>enviPath - Login</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<!-- Bootstrap 3.3.7 CSS -->
|
||||
@ -55,6 +55,12 @@
|
||||
<div class="bg-blur"></div>
|
||||
<div class="bg-dim"></div>
|
||||
|
||||
{% if message %}
|
||||
<div class="alert alert-danger" role="alert">
|
||||
{{ message }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Trigger Button -->
|
||||
<div class="center-button">
|
||||
<button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#signupmodal">Login / Sign Up</button>
|
||||
@ -83,7 +89,7 @@
|
||||
<div class="modal-body">
|
||||
<div id="myTabContent" class="tab-content">
|
||||
<div class="tab-pane fade active in" id="signin">
|
||||
<form class="form-horizontal" method="post" action="{{ meta.server_url }}/user">
|
||||
<form class="form-horizontal" method="post" action="{% url 'login' %}">
|
||||
{% csrf_token %}
|
||||
<fieldset>
|
||||
<input type="hidden" name="login" id="login" value="true"/>
|
||||
@ -140,8 +146,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<form id="signup-action" class="form-horizontal" action="{{ meta.server_url }}/user"
|
||||
method="post">
|
||||
<form id="signup-action" class="form-horizontal" action="{% url 'login' %}" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="register" id="register" value="true"/>
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
<div class="modal-body">
|
||||
<div id="myTabContent" class="tab-content">
|
||||
<div class="tab-pane fade active in" id="signin">
|
||||
<form class="form-horizontal" method="post" action="{{ meta.server_url }}/user">
|
||||
<form class="form-horizontal" method="post" action="{% url 'login' %}">
|
||||
{% csrf_token %}
|
||||
<fieldset>
|
||||
<input type="hidden" name="login" id="login" value="true"/>
|
||||
@ -73,7 +73,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<form id="signup-action" class="form-horizontal" action="{{ meta.server_url }}/user" method="post">
|
||||
<form id="signup-action" class="form-horizontal" action="{% url 'login' %}" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="register" id="register" value="true"/>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user