diff --git a/App/Auth/auth.py b/App/Auth/__init__.py similarity index 74% rename from App/Auth/auth.py rename to App/Auth/__init__.py index d5e3b20..4d4ad1e 100644 --- a/App/Auth/auth.py +++ b/App/Auth/__init__.py @@ -1,9 +1,6 @@ -from flask import request, Blueprint, render_template, session, current_app,redirect, url_for -import os -from .auth_route import route -from Database.sql_provider import SQLProvider +from flask import request, Blueprint, render_template, session, current_app, redirect, url_for +from .auth_model import auth_model -sql_provider = SQLProvider(os.path.join(os.path.dirname(__file__), 'sql')) auth_bp = Blueprint('auth_bp', __name__, template_folder='templates') @auth_bp.route('/', methods=['GET', 'POST']) @@ -13,12 +10,13 @@ def auth(): else: data = request.form.to_dict() data['table'] = 'internal_users' if 'internal' in data else 'external_users' - auth_data = route(current_app.config['db_config'], data, sql_provider, 'auth.sql') + auth_data = auth_model(data) if auth_data.status: session.update({ 'login': auth_data.result[0]['login'], 'role': auth_data.result[0]['user_role'], 'db_config': current_app.config['db_config'], + 'access_user': 'in' if 'internal' in data else 'ext', 'permanent': True }) return redirect(url_for('index')) diff --git a/App/Auth/auth_model.py b/App/Auth/auth_model.py new file mode 100644 index 0000000..294bcbe --- /dev/null +++ b/App/Auth/auth_model.py @@ -0,0 +1,25 @@ +from dataclasses import dataclass +from Database.select import select_list +from Database.sql_provider import SQLProvider +from flask import current_app +import os + +sql_provider = SQLProvider(os.path.join(os.path.dirname(__file__), 'sql')) +@dataclass +class InfoRespronse: + result: tuple + error_message: str + status: bool + +def auth_model(input_data) -> InfoRespronse: + _sql = sql_provider.get('auth.sql', input_data) + result = select_list(current_app.config['db_config'], _sql) + if result is None: + return InfoRespronse(result, + error_message = 'Произошла ошибка на этапе авторизации', + status=False) + elif len(result) == 0: + return InfoRespronse(result, + error_message = 'Пользователь не найден', + status=False) + return InfoRespronse(result, error_message='', status=True) \ No newline at end of file diff --git a/App/Auth/auth_route.py b/App/Auth/auth_route.py deleted file mode 100644 index c65e492..0000000 --- a/App/Auth/auth_route.py +++ /dev/null @@ -1,17 +0,0 @@ -from dataclasses import dataclass -from Database.select import select_list -@dataclass -class InfoRespronse: - result: tuple - error_message: str - status: bool - -def route(db_config, input_data, sql_provider, name) -> InfoRespronse: - _sql = sql_provider.get(name, input_data) - # print("sql = ", _sql) - result = select_list(db_config, _sql) - if result is None: - return InfoRespronse(result, error_message = 'Произошла ошибка на этапе авторизации', status=False) - elif len(result) == 0: - return InfoRespronse(result, error_message = 'Пользователь не найден', status=False) - return InfoRespronse(result, error_message='', status=True) \ No newline at end of file diff --git a/App/Requests/requests.py b/App/Requests/__init__.py similarity index 68% rename from App/Requests/requests.py rename to App/Requests/__init__.py index 03af5ca..ae32219 100644 --- a/App/Requests/requests.py +++ b/App/Requests/__init__.py @@ -1,77 +1,70 @@ -from flask import request, Blueprint, render_template, session +from flask import request, Blueprint, render_template from os import path -from Database.sql_provider import SQLProvider -from checker import check_auth, group_required -from .requests_route import route +from checker import check_auth +from .requests_model import sklad, get_goods, get_sellers, materials_per_seller from datetime import date import json with open(path.join(path.dirname(__file__), 'zapros_menu.json')) as f: requests_list = json.load(f) -sql_provider = SQLProvider(path.join(path.dirname(__file__), 'sql')) requests_bp = Blueprint('requests_bp', __name__, template_folder='templates') @requests_bp.route('/', methods=['GET', 'POST']) @check_auth -@group_required def requests(): if request.method == 'GET': return render_template('zapros_menu.html', options=requests_list) -@requests_bp.route('/req1', methods=['GET', 'POST']) +@requests_bp.route('/sklad', methods=['GET', 'POST']) @check_auth -@group_required def sklad_zapros(): if request.method == 'GET': - zagotovki = route(session['db_config'], {}, sql_provider, 'zagotovki.sql') + zagotovki = get_goods() if zagotovki.status: return render_template('zagotovki.html', materials=zagotovki.result, header='Количество заготовок на складе') else: return render_template('error.html', error_message=zagotovki.error_message) else: material = dict(request.form) - zagotovki = route(session['db_config'], material, sql_provider, 'zapros1.sql') + zagotovki = sklad(material) if zagotovki.status: header = f'Заготовки на складе из материала \'{material["material"]}\'' return render_template('output.html', items=zagotovki.result, object=header) else: return render_template('error.html', error_message=zagotovki.error_message) -@requests_bp.route('/req2', methods=['GET', 'POST']) +# Под вопросом +""" @requests_bp.route('/req2', methods=['GET', 'POST']) @check_auth -@group_required def zagotovki_ship(): if request.method == 'GET': - zagotovki = route(session['db_config'], {}, sql_provider, 'zagotovki.sql') + zagotovki = get_goods() if zagotovki.status: return render_template('zagotovki.html', materials=zagotovki.result, header='Поставки заготовок') else: return render_template('error.html', error_message=zagotovki.error_message) else: material = dict(request.form) - zagotovki = route(session['db_config'], material, sql_provider, 'zapros2.sql') + zagotovki = route(material, 'zapros2.sql') if zagotovki.status: header = f'Поставки заготовок из материала \'{material['material']}\'' return render_template('output.html', items=zagotovki.result, object=header) else: - return render_template('error.html', error_message=zagotovki.error_message) + return render_template('error.html', error_message=zagotovki.error_message) """ -@requests_bp.route('/req3', methods=['GET', 'POST']) +@requests_bp.route('/shipments', methods=['GET', 'POST']) @check_auth -@group_required def sellers_ship(): if request.method == 'GET': - zagotovki = route(session['db_config'], {}, sql_provider, 'sellers.sql') + zagotovki = get_sellers() if zagotovki.status: - min_year = '2000' - max_year = str(date.today().year) - return render_template('sellers_ship.html', sellers=zagotovki.result, year_from=min_year, year_to=max_year) + return render_template('sellers_ship.html', sellers=zagotovki.result, year_from='2000', year_to=str(date.today().year)) else: return render_template('error.html', error_message=zagotovki.error_message) else: seller = dict(request.form) - zagotovki = route(session['db_config'], seller, sql_provider, 'zapros3.sql') + zagotovki = materials_per_seller(seller) if zagotovki.status: header = f'Поставки от поставщика \'{seller['seller']}\'' return render_template('output.html', items=zagotovki.result, object=header) diff --git a/App/Requests/requests_model.py b/App/Requests/requests_model.py new file mode 100644 index 0000000..476fa7f --- /dev/null +++ b/App/Requests/requests_model.py @@ -0,0 +1,49 @@ +from dataclasses import dataclass +from Database.select import select_list +from Database.sql_provider import SQLProvider +from flask import current_app +from os import path + +sql_provider = SQLProvider(path.join(path.dirname(__file__), 'sql')) +@dataclass +class InfoRespronse: + result: tuple + error_message: str + status: bool + +def get_goods() -> InfoRespronse: + _sql = sql_provider.get('zagotovki.sql', {}) + result = select_list(current_app.config['db_config'], _sql) + if result is None: + return InfoRespronse(result, + error_message = 'Ошибка в подключении к базе данных. Свяжитесь с администратором', + status=False) + return InfoRespronse(result, error_message='', status=True) + +def get_sellers() -> InfoRespronse: + _sql = sql_provider.get('sellers.sql', {}) + result = select_list(current_app.config['db_config'], _sql) + if result is None: + return InfoRespronse(result, + error_message = 'Ошибка в подключении к базе данных. Свяжитесь с администратором', + status=False) + return InfoRespronse(result, error_message='', status=True) + +def sklad(input_data) -> InfoRespronse: + _sql = sql_provider.get('zapros1.sql', input_data) + print("sql = ", _sql) + result = select_list(current_app.config['db_config'], _sql) + if result is None: + return InfoRespronse(result, + error_message = 'Ошибка в подключении к базе данных. Свяжитесь с администратором', + status=False) + return InfoRespronse(result, error_message='', status=True) + +def materials_per_seller(input_data) -> InfoRespronse: + _sql = sql_provider.get('zapros3.sql', input_data) + result = select_list(current_app.config['db_config'], _sql) + if result is None: + return InfoRespronse(result, + error_message = 'Ошибка в подключении к базе данных. Свяжитесь с администратором', + status=False) + return InfoRespronse(result, error_message='', status=True) \ No newline at end of file diff --git a/App/Requests/requests_route.py b/App/Requests/requests_route.py deleted file mode 100644 index 513474b..0000000 --- a/App/Requests/requests_route.py +++ /dev/null @@ -1,15 +0,0 @@ -from dataclasses import dataclass -from Database.select import select_list -@dataclass -class InfoRespronse: - result: tuple - error_message: str - status: bool - -def route(db_config, input_data, sql_provider, name) -> InfoRespronse: - _sql = sql_provider.get(name, input_data) - print("sql = ", _sql) - result = select_list(db_config, _sql) - if result is None: - return InfoRespronse(result, error_message = 'Ошибка в подключении к базе данных. Свяжитесь с администратором', status=False) - return InfoRespronse(result, error_message='', status=True) \ No newline at end of file diff --git a/App/Requests/zapros_menu.json b/App/Requests/zapros_menu.json index eacda20..77b9a68 100644 --- a/App/Requests/zapros_menu.json +++ b/App/Requests/zapros_menu.json @@ -1,5 +1,5 @@ [ {"name": "Количество заготовок на складе", "url": "requests_bp.sklad_zapros"}, - {"name": "Поставки заготовок", "url": "requests_bp.zagotovki_ship"}, + {"name": "Поставки поставщиком за год", "url": "requests_bp.sellers_ship"} ] \ No newline at end of file diff --git a/App/app.py b/App/app.py index 8952206..2941e4a 100644 --- a/App/app.py +++ b/App/app.py @@ -1,19 +1,15 @@ from flask import Flask, render_template, session -from Requests.requests import requests_bp -from Auth.auth import auth_bp -from checker import check_auth +from Requests import requests_bp +from Auth import auth_bp import os, json app = Flask(__name__) app.secret_key = 'suplex' -# app.config.from_file(os.path.join(os.path.dirname(__file__), 'data/db_access.json'), load=json.load) -# app.config.from_file(os.path.join(os.path.dirname(__file__), 'data/config.json'), load=json.load) - -with open(os.path.join(os.path.dirname(__file__), 'data/db_access.json')) as f: - app.config['db_access'] = json.load(f) -with open(os.path.join(os.path.dirname(__file__), 'data/config.json')) as f: - app.config['db_config'] = json.load(f) +app.config.update( + db_config=json.load(open(os.path.join(os.path.dirname(__file__), 'data/config.json'))), + db_access=json.load(open(os.path.join(os.path.dirname(__file__), 'data/db_access.json'))) +) app.register_blueprint(requests_bp, url_prefix='/requests') app.register_blueprint(auth_bp, url_prefix='/auth') @@ -23,8 +19,7 @@ def index(): return render_template('main_menu.html', ses=session) @app.route('/logout') -@check_auth def logout(): session.clear() - return render_template('exit.html') + return render_template('main_menu.html', ses=session) app.run(port=5001, debug=True) \ No newline at end of file diff --git a/App/checker.py b/App/checker.py index e7f61d9..343d9b2 100644 --- a/App/checker.py +++ b/App/checker.py @@ -7,12 +7,6 @@ def check_auth(func): def wrapper(*args, **kwargs): if 'login' not in session: return redirect(url_for('auth_bp.auth')) - return func(*args, **kwargs) - return wrapper - -def group_required(func): - @wraps(func) - def wrapper(*args, **kwargs): user_role = session.get('role') user_request = request.endpoint print('request_endpoint=', user_request) @@ -22,5 +16,4 @@ def group_required(func): return func(*args, **kwargs) else: return render_template('error.html', error_message='Недостаточно прав') - return wrapper \ No newline at end of file diff --git a/App/data/db_access.json b/App/data/db_access.json index a45fba0..89e568d 100644 --- a/App/data/db_access.json +++ b/App/data/db_access.json @@ -1,5 +1,5 @@ { "manager": ["auth_bp", "requests_bp"], - "admin": ["auth_bp", "requests_bp"], - "sellers": ["auth_bp", "requests_bp"] + "boss": ["auth_bp", "requests_bp"], + "sellers": ["auth_bp", "requests_bp", "waybill_bp"] } \ No newline at end of file diff --git a/App/templates/exit.html b/App/templates/exit.html deleted file mode 100644 index 0973b70..0000000 --- a/App/templates/exit.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - Успешно - - - -

До свидания!

- - - \ No newline at end of file diff --git a/App/templates/main_menu.html b/App/templates/main_menu.html index 622e6f7..8e0a049 100644 --- a/App/templates/main_menu.html +++ b/App/templates/main_menu.html @@ -11,15 +11,24 @@

Здравствуйте, {{ ses['login'] }}!

+ {% if ses['access_user'] == 'in' %} + + + {% else %} + + {% endif %} {% else %}

Здравствуйте!

+

Для использования системы, пожалуйста, пройдите процедуру авторизации

{% endif %} - - \ No newline at end of file diff --git a/Docs/MVC_auth_1.drawio b/Docs/MVC_auth_1.drawio new file mode 100644 index 0000000..fc25eed --- /dev/null +++ b/Docs/MVC_auth_1.drawio @@ -0,0 +1,694 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Docs/MVC_auth_2.drawio b/Docs/MVC_auth_2.drawio new file mode 100644 index 0000000..9f878fd --- /dev/null +++ b/Docs/MVC_auth_2.drawio @@ -0,0 +1,591 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +