крупное обновление, завез вход и выход
This commit is contained in:
		@@ -1,3 +0,0 @@
 | 
				
			|||||||
from django.test import TestCase
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Create your tests here.
 | 
					 | 
				
			||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
import os
 | 
					import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django.http import HttpResponse, HttpResponseRedirect
 | 
					from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden
 | 
				
			||||||
from django.shortcuts import render
 | 
					from django.shortcuts import render
 | 
				
			||||||
# from django.db.models import Manager
 | 
					# from django.db.models import Manager
 | 
				
			||||||
from django.contrib.auth import authenticate, login
 | 
					from django.contrib.auth import authenticate, login
 | 
				
			||||||
@@ -12,41 +12,30 @@ TEST_BASE_FETCH = "https://test.wawaa.ru/dev-fetch.php"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def view_index(request):
 | 
					def view_index(request):
 | 
				
			||||||
    return render(request, 'index.html')
 | 
					    if request.user.is_authenticated:
 | 
				
			||||||
    # if request.user.is_authenticated:
 | 
					        return render(request, 'index.html')
 | 
				
			||||||
    #     return render(request, 'index.html')
 | 
					    else:
 | 
				
			||||||
    # else:
 | 
					        return HttpResponseRedirect('/account/login')
 | 
				
			||||||
    #     return HttpResponseRedirect()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def view_stats(request):
 | 
					def view_stats(request):
 | 
				
			||||||
    # только для тестирования!
 | 
					    if request.user.is_authenticated:
 | 
				
			||||||
    res = requests.get(TEST_BASE_FETCH + "?stats", headers={'Authorization': os.getenv("TEST_AUTH")})
 | 
					        # только для тестирования!
 | 
				
			||||||
    response = HttpResponse(res.content)
 | 
					        res = requests.get(TEST_BASE_FETCH + "?stats", headers={'Authorization': os.getenv("TEST_AUTH")})
 | 
				
			||||||
    response.headers["Content-type"] = response.headers["Content-type"]
 | 
					        response = HttpResponse(res.content)
 | 
				
			||||||
    return response
 | 
					        response.headers["Content-type"] = response.headers["Content-type"]
 | 
				
			||||||
 | 
					        return response
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        return HttpResponseForbidden()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def view_tank_chart(request):
 | 
					def view_tank_chart(request):
 | 
				
			||||||
    # только для тестирования!
 | 
					    if request.user.is_authenticated:
 | 
				
			||||||
    days = request.GET.get('days', '7')
 | 
					        # только для тестирования!
 | 
				
			||||||
    res = requests.get(TEST_BASE_FETCH + "?tank_chart=" + days, headers={'Authorization': os.getenv("TEST_AUTH")})
 | 
					        days = request.GET.get('days', '7')
 | 
				
			||||||
    response = HttpResponse(res.content)
 | 
					        res = requests.get(TEST_BASE_FETCH + "?tank_chart=" + days, headers={'Authorization': os.getenv("TEST_AUTH")})
 | 
				
			||||||
    response.headers["Content-type"] = response.headers["Content-type"]
 | 
					        response = HttpResponse(res.content)
 | 
				
			||||||
    return response
 | 
					        response.headers["Content-type"] = response.headers["Content-type"]
 | 
				
			||||||
 | 
					        return response
 | 
				
			||||||
 | 
					 | 
				
			||||||
# вход
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def view_login(request):
 | 
					 | 
				
			||||||
    username = request.POST["username"]
 | 
					 | 
				
			||||||
    password = request.POST["password"]
 | 
					 | 
				
			||||||
    user = authenticate(request, username=username, password=password)
 | 
					 | 
				
			||||||
    if user is not None:
 | 
					 | 
				
			||||||
        login(request, user)
 | 
					 | 
				
			||||||
        return HttpResponseRedirect('/')
 | 
					 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        # Return an 'invalid login' error message.
 | 
					        return HttpResponseForbidden()
 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,7 +29,7 @@ PROJECT_ROOT = os.path.dirname(__file__)
 | 
				
			|||||||
SECRET_KEY = os.getenv('DJANGO_SECRET')
 | 
					SECRET_KEY = os.getenv('DJANGO_SECRET')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ALLOWED_HOSTS = ['10.8.0.2', '10.8.0.6', 'ospaz.wawaa.ru', 'dev.ospaz.wawaa.ru']
 | 
					ALLOWED_HOSTS = ['10.8.0.2', '10.8.0.6', 'ospaz.wawaa.ru', 'dev.ospaz.wawaa.ru']
 | 
				
			||||||
# CSRF_TRUSTED_ORIGINS = ['https://ospaz.wawaa.ru']
 | 
					CSRF_TRUSTED_ORIGINS = ['http://10.8.0.2', 'http://10.8.0.6', 'https://ospaz.wawaa.ru', 'https://dev.ospaz.wawaa.ru']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# HTTPS settings https://docs.djangoproject.com/en/5.0/topics/security/
 | 
					# HTTPS settings https://docs.djangoproject.com/en/5.0/topics/security/
 | 
				
			||||||
#CSRF_COOKIE_SECURE = True
 | 
					#CSRF_COOKIE_SECURE = True
 | 
				
			||||||
@@ -37,8 +37,7 @@ ALLOWED_HOSTS = ['10.8.0.2', '10.8.0.6', 'ospaz.wawaa.ru', 'dev.ospaz.wawaa.ru']
 | 
				
			|||||||
#DEBUG = False
 | 
					#DEBUG = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# HTTP settings
 | 
					# HTTP settings
 | 
				
			||||||
DEBUG = True
 | 
					DEBUG = int(os.getenv('PROJECT_DEBUG', '0')) != 0
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Application definition
 | 
					# Application definition
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,6 +21,7 @@ from django.contrib.staticfiles.views import serve
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
urlpatterns = [
 | 
					urlpatterns = [
 | 
				
			||||||
    path('', include('index.urls')),
 | 
					    path('', include('index.urls')),
 | 
				
			||||||
 | 
					    path('account/', include('users.urls')),
 | 
				
			||||||
    path('admin/', admin.site.urls),
 | 
					    path('admin/', admin.site.urls),
 | 
				
			||||||
    path('favicon.ico', lambda req: serve(req, 'favicon.svg'))
 | 
					    path('favicon.ico', lambda req: serve(req, 'favicon.svg'))
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,6 +10,7 @@ body {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  --bg-color: #FEFEFE;
 | 
					  --bg-color: #FEFEFE;
 | 
				
			||||||
  --bg-selected: #F1F1F1;
 | 
					  --bg-selected: #F1F1F1;
 | 
				
			||||||
 | 
					  --bg-action: #5181fe;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@media (prefers-color-scheme: dark) {
 | 
					@media (prefers-color-scheme: dark) {
 | 
				
			||||||
@@ -25,6 +26,7 @@ body {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    --bg-color: #2d2c33;
 | 
					    --bg-color: #2d2c33;
 | 
				
			||||||
    --bg-selected: #424248;
 | 
					    --bg-selected: #424248;
 | 
				
			||||||
 | 
					    --bg-action: #4a70d5;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -66,7 +66,11 @@ function approximateWithTimestamps(dataset) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
async function makeRequest(url) {
 | 
					async function makeRequest(url) {
 | 
				
			||||||
    let response = await fetch(url)
 | 
					    let response = await fetch(url)
 | 
				
			||||||
    if (response.status !== 200) {
 | 
					    if (response.status === 403) {
 | 
				
			||||||
 | 
					        // http Forbidden, исправляется перезагрузкой страницы и просмотром окошка "Требуется авторизация"
 | 
				
			||||||
 | 
					        window.location.reload()
 | 
				
			||||||
 | 
					        return {}
 | 
				
			||||||
 | 
					    } else if (response.status !== 200) {
 | 
				
			||||||
        console.log('fetch(' + url + ') failed. Status Code: ' + response.status);
 | 
					        console.log('fetch(' + url + ') failed. Status Code: ' + response.status);
 | 
				
			||||||
        return null;
 | 
					        return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										103
									
								
								templates/account/login.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								templates/account/login.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,103 @@
 | 
				
			|||||||
 | 
					{% extends 'base.html' %}
 | 
				
			||||||
 | 
					{% load static %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block styles %}
 | 
				
			||||||
 | 
					<style>
 | 
				
			||||||
 | 
					    #form-wrapper {
 | 
				
			||||||
 | 
					        overflow: hidden;
 | 
				
			||||||
 | 
					        max-width: 27em;
 | 
				
			||||||
 | 
					        margin: 5em auto;
 | 
				
			||||||
 | 
					        height: auto;
 | 
				
			||||||
 | 
					        text-align: center;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .form-row {
 | 
				
			||||||
 | 
					        padding: 4px 0;
 | 
				
			||||||
 | 
					        margin: 1.5em;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .form-row * {
 | 
				
			||||||
 | 
					        font-size: 1em;
 | 
				
			||||||
 | 
					        text-align: left;
 | 
				
			||||||
 | 
					        display: block;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .form-row label {
 | 
				
			||||||
 | 
					        line-height: 2em;
 | 
				
			||||||
 | 
					        font-weight: bolder;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .form-row input {
 | 
				
			||||||
 | 
					        padding: 8px;
 | 
				
			||||||
 | 
					        width: 100%;
 | 
				
			||||||
 | 
					        box-sizing: border-box;
 | 
				
			||||||
 | 
					        border: none;
 | 
				
			||||||
 | 
					        border-bottom: var(--brand-bg) 2px solid;
 | 
				
			||||||
 | 
					        background-color: var(--bg-color);
 | 
				
			||||||
 | 
					        text-overflow: ellipsis;
 | 
				
			||||||
 | 
					        min-height: 2em;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .form-row input:focus {
 | 
				
			||||||
 | 
					        outline: none;
 | 
				
			||||||
 | 
					        border: none;
 | 
				
			||||||
 | 
					        border-bottom: var(--brand-text) 2px solid;
 | 
				
			||||||
 | 
					        background-color: var(--bg-selected);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #submit {
 | 
				
			||||||
 | 
					        border: none;
 | 
				
			||||||
 | 
					        font-weight: bolder;
 | 
				
			||||||
 | 
					        background: var(--bg-action);
 | 
				
			||||||
 | 
					        text-align: center;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
 | 
					{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block header %}
 | 
				
			||||||
 | 
					<h1> Вход </h1>
 | 
				
			||||||
 | 
					{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block content %}
 | 
				
			||||||
 | 
					<div id="form-wrapper">
 | 
				
			||||||
 | 
					    <h1> Войти </h1>
 | 
				
			||||||
 | 
					    <form action="{% url 'login' %}" method="POST" id="login-form">
 | 
				
			||||||
 | 
					        {% csrf_token %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        {% if message %}
 | 
				
			||||||
 | 
					        <div class="form-row error-message">
 | 
				
			||||||
 | 
					            {{ message }}
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        {% endif %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <div class="form-row">
 | 
				
			||||||
 | 
					            <label for="username">Имя пользователя</label>
 | 
				
			||||||
 | 
					            <input type="text" name="username" id="username" required/>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <div class="form-row">
 | 
				
			||||||
 | 
					            <label for="password">Пароль</label>
 | 
				
			||||||
 | 
					            <input type="password" name="password" id="password" required/>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <div class="form-row">
 | 
				
			||||||
 | 
					            <input id="submit" type="submit" value="Войти">
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </form>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					    document.getElementById("username").onkeydown = (e) => {
 | 
				
			||||||
 | 
					        if (e.key === 'Enter') {
 | 
				
			||||||
 | 
					            document.getElementById("password").focus()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    document.getElementById("password").onkeydown = (e) => {
 | 
				
			||||||
 | 
					        if (e.key === 'Enter') {
 | 
				
			||||||
 | 
					            document.getElementById("login-form").submit()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					{% endblock %}
 | 
				
			||||||
@@ -12,7 +12,13 @@
 | 
				
			|||||||
</head>
 | 
					</head>
 | 
				
			||||||
<body>
 | 
					<body>
 | 
				
			||||||
    <header>
 | 
					    <header>
 | 
				
			||||||
        {% block header %} тут должен быть хидер {% endblock %}
 | 
					        {% block header %}
 | 
				
			||||||
 | 
					        <h1> Мониторинг водозаборного узла </h1>
 | 
				
			||||||
 | 
					        <div>
 | 
				
			||||||
 | 
					            <span> {{ user.login }} </span>
 | 
				
			||||||
 | 
					            <a href="/account/logout">Выход</a>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        {% endblock %}
 | 
				
			||||||
    </header>
 | 
					    </header>
 | 
				
			||||||
    <main id="content">
 | 
					    <main id="content">
 | 
				
			||||||
        {% block content %} тут должен быть контент {% endblock %}
 | 
					        {% block content %} тут должен быть контент {% endblock %}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,15 +35,7 @@
 | 
				
			|||||||
</style>
 | 
					</style>
 | 
				
			||||||
{% endblock %}
 | 
					{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% block header %}
 | 
					 | 
				
			||||||
<h1> Мониторинг водозаборного узла </h1>
 | 
					 | 
				
			||||||
{% if user.is_superuser %}
 | 
					 | 
				
			||||||
<a href="/admin">Админка</a>
 | 
					 | 
				
			||||||
{% endif %}
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block content %}
 | 
					{% block content %}
 | 
				
			||||||
 | 
					 | 
				
			||||||
<div>
 | 
					<div>
 | 
				
			||||||
    <div class="content-wrapper">
 | 
					    <div class="content-wrapper">
 | 
				
			||||||
        <div class="content-block">
 | 
					        <div class="content-block">
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										26
									
								
								users/urls.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								users/urls.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					"""users URL Configuration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The `urlpatterns` list routes URLs to views. For more information please see:
 | 
				
			||||||
 | 
					    https://docs.djangoproject.com/en/3.2/topics/http/urls/
 | 
				
			||||||
 | 
					Examples:
 | 
				
			||||||
 | 
					Function views
 | 
				
			||||||
 | 
					    1. Add an import:  from my_app import views
 | 
				
			||||||
 | 
					    2. Add a URL to urlpatterns:  path('', views.home, name='home')
 | 
				
			||||||
 | 
					Class-based views
 | 
				
			||||||
 | 
					    1. Add an import:  from other_app.views import Home
 | 
				
			||||||
 | 
					    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
 | 
				
			||||||
 | 
					Including another URLconf
 | 
				
			||||||
 | 
					    1. Import the include() function: from django.urls import include, path
 | 
				
			||||||
 | 
					    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.urls import path
 | 
				
			||||||
 | 
					from . import views
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					urlpatterns = [
 | 
				
			||||||
 | 
					    path('', views.default_view, name='account'),
 | 
				
			||||||
 | 
					    path('register', views.default_view, name='register'),
 | 
				
			||||||
 | 
					    path('login', views.view_login, name='login'),
 | 
				
			||||||
 | 
					    path('logout', views.default_view, name='logout'),
 | 
				
			||||||
 | 
					    path('change-password', views.default_view, name='change-password'),
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
							
								
								
									
										33
									
								
								users/views.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								users/views.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.http import HttpResponse, HttpResponseRedirect, HttpResponseBadRequest
 | 
				
			||||||
 | 
					from django.shortcuts import render
 | 
				
			||||||
 | 
					# from django.db.models import Manager
 | 
				
			||||||
 | 
					from django.contrib.auth import authenticate, login
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def default_view(request):
 | 
				
			||||||
 | 
					    return HttpResponse('Not implemented!')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def view_login(request):
 | 
				
			||||||
 | 
					    render_context = {
 | 
				
			||||||
 | 
					        'message': None
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if request.method == "POST":
 | 
				
			||||||
 | 
					        username = request.POST["username"]
 | 
				
			||||||
 | 
					        password = request.POST["password"]
 | 
				
			||||||
 | 
					        user = authenticate(request, username=username, password=password)
 | 
				
			||||||
 | 
					        if user is not None:
 | 
				
			||||||
 | 
					            login(request, user)
 | 
				
			||||||
 | 
					            return HttpResponseRedirect('/')
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            render_context['message'] = "Неверный логин или пароль"
 | 
				
			||||||
 | 
					            return render(request, 'account/login.html', render_context)
 | 
				
			||||||
 | 
					    elif request.method == "GET":
 | 
				
			||||||
 | 
					        return render(request, 'account/login.html', render_context)
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        return HttpResponseBadRequest()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Reference in New Issue
	
	Block a user