Commit b3266e1593a5cc2d36606e8ef018f0eba7298281
1 parent
9d7bba8b03
Exists in
master
add menu for roleid
Showing 37 changed files with 707 additions and 9 deletions Side-by-side Diff
- .gitignore
- README.md
- __pycache__/main.cpython-310.pyc
- __pycache__/routes.cpython-310.pyc
- components/__pycache__/__init__.cpython-310.pyc
- components/k2adm/.gitignore
- components/k2adm/k2adm/languages/en/LC_MESSAGES/messages.mo
- components/k2adm/k2adm/languages/en/LC_MESSAGES/messages.po
- components/k2adm/k2adm/languages/uk/LC_MESSAGES/messages.mo
- components/k2adm/k2adm/languages/uk/LC_MESSAGES/messages.po
- components/k2adm/k2adm/models.py
- components/k2adm/k2adm/views.py
- components/k2adm/requirements.txt
- components/k2adm/setup.py
- components/k2auth/.gitignore
- components/k2auth/README.md
- components/k2auth/k2auth/models.py
- components/k2auth/k2auth/views.py
- components/k2auth/requirements.txt
- components/k2auth/setup.py
- components/k2test/__pycache__/__init__.cpython-310.pyc
- components/k2test/k2test/__pycache__/__init__.cpython-310.pyc
- components/k2test/k2test/__pycache__/views.cpython-310.pyc
- components/k2test/k2test/languages/en/LC_MESSAGES/messages.mo
- components/k2test/k2test/languages/uk/LC_MESSAGES/messages.mo
- components/k2test/k2test/views.py
- db/database.db
- k2/__pycache__/__init__.cpython-310.pyc
- k2/__pycache__/k2admmenu.cpython-310.pyc
- k2/__pycache__/k2cfg.cpython-310.pyc
- k2/__pycache__/k2comp.cpython-310.pyc
- k2/__pycache__/k2obj.cpython-310.pyc
- k2/__pycache__/k2rout.cpython-310.pyc
- k2/k2admmenu.py
- k2/k2rout.py
- languages/babel_translation_directories.yml
- routes.py
.gitignore
README.md
| 1 | +open http://127.0.0.1:5000/dashboard |
__pycache__/main.cpython-310.pyc
No preview for this file type
__pycache__/routes.cpython-310.pyc
No preview for this file type
components/__pycache__/__init__.cpython-310.pyc
No preview for this file type
components/k2adm/.gitignore
components/k2adm/k2adm/languages/en/LC_MESSAGES/messages.mo
No preview for this file type
components/k2adm/k2adm/languages/en/LC_MESSAGES/messages.po
| 1 | +msgid "title_menu_items" | |
| 2 | +msgstr "Site administration" | |
| 3 | + | |
| 4 | +msgid "menu_items_child_1" | |
| 5 | +msgstr "Password change" | |
| 6 | + | |
| 7 | +msgid "menu_items_child_2" | |
| 8 | +msgstr "New user" | |
| 9 | + | |
| 10 | +msgid "menu_items_child_3" | |
| 11 | +msgstr "Users" | |
| 12 | + | |
| 13 | + | |
| 14 | +msgid "menu_items_child_4" | |
| 15 | +msgstr "Users are clients" | |
| 16 | + | |
| 17 | + | |
| 18 | +msgid "menu_items_child_5" | |
| 19 | +msgstr "Roles" | |
| 20 | + | |
| 21 | + | |
| 22 | +msgid "menu_items_child_6" | |
| 23 | +msgstr "Access to the menu" |
components/k2adm/k2adm/languages/uk/LC_MESSAGES/messages.mo
No preview for this file type
components/k2adm/k2adm/languages/uk/LC_MESSAGES/messages.po
| 1 | +msgid "title_menu_items" | |
| 2 | +msgstr "Адміністрування сайту" | |
| 3 | + | |
| 4 | + | |
| 5 | +msgid "menu_items_child_1" | |
| 6 | +msgstr "Зміна паролю" | |
| 7 | + | |
| 8 | +msgid "menu_items_child_2" | |
| 9 | +msgstr "Новий користувач" | |
| 10 | + | |
| 11 | +msgid "menu_items_child_3" | |
| 12 | +msgstr "Користувачі" | |
| 13 | + | |
| 14 | + | |
| 15 | +msgid "menu_items_child_4" | |
| 16 | +msgstr "Користувачі кліенти" | |
| 17 | + | |
| 18 | + | |
| 19 | +msgid "menu_items_child_5" | |
| 20 | +msgstr "Ролі" | |
| 21 | + | |
| 22 | + | |
| 23 | +msgid "menu_items_child_6" | |
| 24 | +msgstr "Доступ до меню" |
components/k2adm/k2adm/models.py
| 1 | +import uuid | |
| 2 | +from sqlalchemy import Column, Integer, String | |
| 3 | +from sqlalchemy.ext.declarative import declarative_base | |
| 4 | +from flask_jwt_extended import create_access_token | |
| 5 | +from datetime import timedelta | |
| 6 | +import hashlib | |
| 7 | +from flask import current_app as k2 | |
| 8 | + | |
| 9 | +Base = declarative_base() | |
| 10 | + | |
| 11 | + | |
| 12 | +class k2users(Base): | |
| 13 | + __tablename__ = 'k2users' | |
| 14 | + user_id = Column(Integer, primary_key=True) | |
| 15 | + login = Column(String(70), nullable=False) | |
| 16 | + name = Column(String(50), nullable=False) | |
| 17 | + email = Column(String(150), nullable=False) | |
| 18 | + password = Column(String(150), nullable=False) | |
| 19 | + phone = Column(String(20)) | |
| 20 | + roleid = Column(String(150), nullable=False) | |
| 21 | + | |
| 22 | + def __init__(self, **kwargs): | |
| 23 | + self.user_id = hashlib.md5(str(uuid.uuid4()).encode()).hexdigest() | |
| 24 | + self.login = kwargs.get('login') | |
| 25 | + self.password = hashlib.md5(kwargs.get('password').encode()).hexdigest() | |
| 26 | + self.name = kwargs.get('name') | |
| 27 | + self.email = kwargs.get('email') | |
| 28 | + self.phone = kwargs.get('phone') | |
| 29 | + self.roleid = kwargs.get('roleid') | |
| 30 | + | |
| 31 | + def get_token(self, expire_time=24): | |
| 32 | + expires_delta = timedelta(expire_time) | |
| 33 | + token = create_access_token(identity=self.user_id, expires_delta=expires_delta) | |
| 34 | + | |
| 35 | + db = k2.extensions['sqlalchemy'].db | |
| 36 | + connection = db.engine.connect() | |
| 37 | + result = connection.execute( | |
| 38 | + db.text(f"SELECT rolename FROM k2roles where roleid = '{self.roleid}'")).fetchone() | |
| 39 | + rolename = result[0] if result else None | |
| 40 | + | |
| 41 | + userData = { | |
| 42 | + "avatar": "/src/assets/images/avatars/avatar-4.png", | |
| 43 | + "email": self.email, | |
| 44 | + "fullName": self.name, | |
| 45 | + "id": self.user_id, | |
| 46 | + "role": rolename, | |
| 47 | + "username": self.login | |
| 48 | + } | |
| 49 | + | |
| 50 | + userAbilities = [] | |
| 51 | + query = f""" | |
| 52 | + SELECT menus.namemenu, prava.r, prava.w, prava.i, prava.d, prava.c, | |
| 53 | + prava.exp, prava.imp, prava.settable, prava.cutpast, prava.enable, prava.del | |
| 54 | + FROM k2admin_menus menus | |
| 55 | + JOIN k2admin_menus_prava prava ON menus.menuid = prava.menuid | |
| 56 | + WHERE prava.roleid = {self.roleid} | |
| 57 | + """ | |
| 58 | + menus = connection.execute(db.text(query)).fetchall() | |
| 59 | + | |
| 60 | + for menu in menus: | |
| 61 | + abilities_dict = { | |
| 62 | + "subject": menu[0], | |
| 63 | + "read": menu[1], | |
| 64 | + "write": menu[2], | |
| 65 | + "insert": menu[3], | |
| 66 | + "delete": menu[4], | |
| 67 | + "copy": menu[5], | |
| 68 | + "export": menu[6], | |
| 69 | + "import": menu[7], | |
| 70 | + "settable": menu[8], | |
| 71 | + "cutpast": menu[9], | |
| 72 | + "enable": menu[10], | |
| 73 | + "del": menu[11], | |
| 74 | + } | |
| 75 | + | |
| 76 | + abilities_dict_copy = abilities_dict.copy() | |
| 77 | + for key, value in abilities_dict_copy.items(): | |
| 78 | + if value == 0: | |
| 79 | + del abilities_dict[key] | |
| 80 | + userAbilities.append(abilities_dict) | |
| 81 | + | |
| 82 | + return (token, userData, userAbilities) | |
| 83 | + | |
| 84 | + @classmethod | |
| 85 | + def authenticate(cls, login, password): | |
| 86 | + session = k2.extensions['sqlalchemy'].db.session | |
| 87 | + user = '' | |
| 88 | + try: | |
| 89 | + user = session.query(cls).filter(cls.login == login).filter(cls.password == hashlib.md5(password.encode()).hexdigest()).one() | |
| 90 | + except: | |
| 91 | + user = None | |
| 92 | + return user | |
| 93 | + | |
| 94 | + @classmethod | |
| 95 | + def user_by_login(cls, login): | |
| 96 | + session = k2.extensions['sqlalchemy'].db.session | |
| 97 | + user = session.query(cls).filter(cls.login == login).first() | |
| 98 | + return user |
components/k2adm/k2adm/views.py
| 1 | +import hashlib | |
| 2 | +import uuid | |
| 3 | +from flask import Blueprint, request, jsonify | |
| 4 | +from flask import current_app as k2 | |
| 5 | +from flask_jwt_extended import jwt_required, get_jwt_identity | |
| 6 | +from flask_babel import gettext | |
| 7 | + | |
| 8 | +from .models import k2users | |
| 9 | + | |
| 10 | + | |
| 11 | +k2adm = Blueprint('k2adm', __name__) | |
| 12 | + | |
| 13 | + | |
| 14 | +@k2adm.route('/usersclients', methods=["GET"]) | |
| 15 | +@jwt_required() | |
| 16 | +def users_clients(): | |
| 17 | + return jsonify({"data": "user roles"}) | |
| 18 | + | |
| 19 | + | |
| 20 | +@k2adm.route('/users', methods=["GET"]) | |
| 21 | +@jwt_required() | |
| 22 | +def grid_users(): | |
| 23 | + return jsonify({"data": "users"}) | |
| 24 | + | |
| 25 | + | |
| 26 | +@k2adm.route('/roles', methods=["GET"]) | |
| 27 | +@jwt_required() | |
| 28 | +def grid_roles(): | |
| 29 | + return jsonify({"data": "roles"}) | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | +@k2adm.route('/api_get_roles', methods=["GET"]) | |
| 34 | +@jwt_required() | |
| 35 | +def roles(): | |
| 36 | + db = k2.extensions['sqlalchemy'].db | |
| 37 | + connection = db.engine.connect() | |
| 38 | + query = db.text("SELECT roleid, rolename FROM k2roles") | |
| 39 | + result = connection.execute(query).fetchall() | |
| 40 | + roles = [dict(id=res.roleid, role=res.rolename) for res in result] | |
| 41 | + return {'data': roles} | |
| 42 | + | |
| 43 | + | |
| 44 | +@k2adm.route('/newUser', methods=["GET", "POST"]) | |
| 45 | +@jwt_required() | |
| 46 | +def newUser(): | |
| 47 | + session = k2.extensions['sqlalchemy'].db.session | |
| 48 | + exist = k2users.user_by_login(request.json['login']) | |
| 49 | + if not exist: | |
| 50 | + res = k2users( | |
| 51 | + user_id=hashlib.md5(str(uuid.uuid4()).encode()).hexdigest(), | |
| 52 | + login=request.json['login'], | |
| 53 | + name=request.json['name'], | |
| 54 | + email=request.json['email'], | |
| 55 | + password=request.json['password'], | |
| 56 | + phone=request.json['phone'], | |
| 57 | + roleid=request.json['role'] | |
| 58 | + ) | |
| 59 | + | |
| 60 | + if res: | |
| 61 | + session.add(res) | |
| 62 | + session.commit() | |
| 63 | + return jsonify({'status': '200', 'message': 'New user created'}) | |
| 64 | + else: | |
| 65 | + return jsonify({'status': '409', 'message': 'Such user exist'}), 409 | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | +@k2adm.route('/changePassword', methods=["POST"]) | |
| 70 | +@jwt_required() | |
| 71 | +def changePassword(): | |
| 72 | + session = k2.extensions['sqlalchemy'].db.session | |
| 73 | + current_user = get_jwt_identity() | |
| 74 | + user = session.query(k2users).filter_by(user_id=current_user).first() | |
| 75 | + if user.password == hashlib.md5(request.json['old_password'].encode()).hexdigest(): | |
| 76 | + if request.json['new_password'] == request.json['re_new_password']: | |
| 77 | + user.password = hashlib.md5(request.json['new_password'].encode()).hexdigest() | |
| 78 | + session.commit() | |
| 79 | + else: | |
| 80 | + return jsonify({'status': '400', 'message': 'Пароли не совпвдает'}), 400 | |
| 81 | + else: | |
| 82 | + jsonify({'status': '404', 'message': "Пароль не найден в базе"}), 404 | |
| 83 | + return jsonify({'status': 'ok'}) | |
| 84 | + | |
| 85 | + | |
| 86 | +@k2adm.route('/menu-admin-items') | |
| 87 | +def menu_items(): | |
| 88 | + data = [ | |
| 89 | + { | |
| 90 | + # "title": 'Site administration', | |
| 91 | + "title": f"{gettext('title_menu_items')}", | |
| 92 | + "icon": {"icon": 'mdi-account-circle-outline'}, | |
| 93 | + "children": [ | |
| 94 | + {'title': f"{gettext('menu_items_child_1')}", 'to': 'adm-changePassword'}, | |
| 95 | + {'title': f"{gettext('menu_items_child_2')}", 'to': 'adm-newUser'}, | |
| 96 | + {'title': f"{gettext('menu_items_child_3')}", 'to': 'adm-users'}, | |
| 97 | + {'title': f"{gettext('menu_items_child_4')}", 'to': 'adm-usersclients'}, | |
| 98 | + {'title': f"{gettext('menu_items_child_5')}", 'to': 'adm-roles'}, | |
| 99 | + {'title': f"{gettext('menu_items_child_6')}", 'to': 'adm-menuaaccess'}, | |
| 100 | + ], | |
| 101 | + }] | |
| 102 | + return data | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | +# @adm.route('/register', methods=["POST"]) | |
| 110 | +# def register(): | |
| 111 | +# params = request.json | |
| 112 | +# session = k2.extensions['sqlalchemy'].db.session | |
| 113 | +# exist = k2users.user_by_login(request.json['login']) | |
| 114 | +# if not exist: | |
| 115 | +# user = k2users(**params) | |
| 116 | +# session.add(user) | |
| 117 | +# session.commit() | |
| 118 | +# token, userData, userAbilities = user.get_token() | |
| 119 | +# return {'accessToken': token, "userData": userData, "userAbilities": userAbilities} | |
| 120 | +# else: | |
| 121 | +# return jsonify({'error': 'User exist'}), 401 | |
| 122 | + | |
| 123 | + | |
| 124 | +# @adm.route('/login', methods=["POST"]) | |
| 125 | +# def login(): | |
| 126 | +# params = request.json | |
| 127 | +# user = k2users.authenticate(**params) | |
| 128 | +# if user: | |
| 129 | +# token, userData, userAbilities = user.get_token() | |
| 130 | +# return {'accessToken': token, "userData": userData, "userAbilities": userAbilities} | |
| 131 | +# else: | |
| 132 | +# return jsonify({'error': 'Unauthorized'}), 401 | |
| 133 | + | |
| 134 | + | |
| 135 | +# @adm.route('/logout', methods=["GET"]) | |
| 136 | +# @jwt_required() | |
| 137 | +# def logout(): | |
| 138 | +# | |
| 139 | +# response = { | |
| 140 | +# 'message': 'Logged out successfully' | |
| 141 | +# } | |
| 142 | + | |
| 143 | + # return jsonify(response) |
components/k2adm/requirements.txt
| 1 | +alembic==1.11.1 | |
| 2 | +Babel==2.12.1 | |
| 3 | +bcrypt==4.0.1 | |
| 4 | +bidict==0.22.1 | |
| 5 | +blinker==1.6.2 | |
| 6 | +certifi==2023.5.7 | |
| 7 | +charset-normalizer==3.1.0 | |
| 8 | +click==8.1.3 | |
| 9 | +colorama==0.4.6 | |
| 10 | +dnspython==2.3.0 | |
| 11 | +email-validator==2.0.0.post2 | |
| 12 | +Flask==2.3.2 | |
| 13 | +flask-babel==3.1.0 | |
| 14 | +Flask-Bcrypt==1.0.1 | |
| 15 | +Flask-Cors==3.0.10 | |
| 16 | +Flask-JWT-Extended==4.5.2 | |
| 17 | +Flask-Login==0.6.2 | |
| 18 | +Flask-Migrate==4.0.4 | |
| 19 | +Flask-MySQLdb==1.0.1 | |
| 20 | +Flask-SQLAlchemy==3.0.3 | |
| 21 | +flask-staticdirs==1.0.1 | |
| 22 | +Flask-WTF==1.1.1 | |
| 23 | +greenlet==2.0.2 | |
| 24 | +idna==3.4 | |
| 25 | +itsdangerous==2.1.2 | |
| 26 | +Jinja2==3.1.2 | |
| 27 | +jsonify==0.5 | |
| 28 | +Mako==1.2.4 | |
| 29 | +MarkupSafe==2.1.2 | |
| 30 | +mysql==0.0.3 | |
| 31 | +mysql-connector==2.2.9 | |
| 32 | +mysql-connector-python==8.0.33 | |
| 33 | +mysqlclient==2.1.1 | |
| 34 | +peppercorn==0.6 | |
| 35 | +protobuf==3.20.3 | |
| 36 | +PyJWT==2.7.0 | |
| 37 | +python-engineio==4.4.1 | |
| 38 | +python-socketio==5.8.0 | |
| 39 | +pytz==2023.3 | |
| 40 | +PyYAML==6.0 | |
| 41 | +requests==2.31.0 | |
| 42 | +six==1.16.0 | |
| 43 | +SQLAlchemy==2.0.15 | |
| 44 | +typing_extensions==4.6.2 | |
| 45 | +urllib3==2.0.2 | |
| 46 | +Werkzeug==2.3.4 | |
| 47 | +WTForms==3.0.1 |
components/k2adm/setup.py
| 1 | +from setuptools import setup | |
| 2 | + | |
| 3 | +setup( | |
| 4 | + name='k2adm', | |
| 5 | + version='1.0.0', | |
| 6 | + description='Description of my project', | |
| 7 | + author='k2 cloud', | |
| 8 | + author_email='ys@corp2.eu', | |
| 9 | + keywords="adm, k2", | |
| 10 | + python_requires=">=3.7, <=3.11.2", | |
| 11 | + packages=['adm'], | |
| 12 | + package_data={ # Optional | |
| 13 | + }, | |
| 14 | + install_requires=[""], | |
| 15 | +) |
components/k2auth/.gitignore
components/k2auth/README.md
| 1 | +# main.py | |
| 2 | + | |
| 3 | +from components.adm.adm.views import adm | |
| 4 | +from components.test.test.views import test | |
| 5 | + | |
| 6 | +app.register_blueprint(adm, url_prefix='/adm') | |
| 7 | + | |
| 8 | +cd components/adm | |
| 9 | +pip install -r requirements.txt | |
| 10 | + | |
| 11 | + | |
| 12 | +endpoint "http://127.0.0.1:5000/adm/register" | |
| 13 | +dictionary to register in such way | |
| 14 | +{ | |
| 15 | + "login": "xxx", | |
| 16 | + "password": "xxx", | |
| 17 | + "name": "xxx", | |
| 18 | + "email": "xxx" | |
| 19 | +} | |
| 20 | + | |
| 21 | + | |
| 22 | +endpoint "http://127.0.0.1:5000/adm/login" | |
| 23 | +dictionary to login in such way | |
| 24 | +{ | |
| 25 | + "login":"xxx", | |
| 26 | + "password":"xxx" | |
| 27 | +} | |
| 28 | + | |
| 29 | +endpoint http://127.0.0.1:5000/adm/changePassword | |
| 30 | +dictionary to changePassword in such way | |
| 31 | +{ | |
| 32 | + "old_password":"xxx", | |
| 33 | + "new_password": "xxx", | |
| 34 | + "re_new_password": "xxx" | |
| 35 | +} | |
| 36 | +endpoint http://127.0.0.1:5000/adm/newUser | |
| 37 | +{ | |
| 38 | + "login": "xxx", | |
| 39 | + "password": "xxx", | |
| 40 | + "name": "xxx", | |
| 41 | + "email": "xxx", | |
| 42 | + "phone": "xxx", | |
| 43 | + "repassword": "xxx" | |
| 44 | + | |
| 45 | +} |
components/k2auth/k2auth/models.py
| 1 | +import uuid | |
| 2 | +from sqlalchemy import Column, Integer, String | |
| 3 | +from sqlalchemy.ext.declarative import declarative_base | |
| 4 | +from flask_jwt_extended import create_access_token | |
| 5 | +from datetime import timedelta | |
| 6 | +import hashlib | |
| 7 | +from flask import current_app as k2 | |
| 8 | + | |
| 9 | +Base = declarative_base() | |
| 10 | + | |
| 11 | + | |
| 12 | +class k2users(Base): | |
| 13 | + __tablename__ = 'k2users' | |
| 14 | + user_id = Column(Integer, primary_key=True) | |
| 15 | + login = Column(String(70), nullable=False) | |
| 16 | + name = Column(String(50), nullable=False) | |
| 17 | + email = Column(String(150), nullable=False) | |
| 18 | + password = Column(String(150), nullable=False) | |
| 19 | + phone = Column(String(20)) | |
| 20 | + roleid = Column(String(150), nullable=False) | |
| 21 | + | |
| 22 | + def __init__(self, **kwargs): | |
| 23 | + self.user_id = hashlib.md5(str(uuid.uuid4()).encode()).hexdigest() | |
| 24 | + self.login = kwargs.get('login') | |
| 25 | + self.password = hashlib.md5(kwargs.get('password').encode()).hexdigest() | |
| 26 | + self.name = kwargs.get('name') | |
| 27 | + self.email = kwargs.get('email') | |
| 28 | + self.phone = kwargs.get('phone') | |
| 29 | + self.roleid = kwargs.get('roleid') | |
| 30 | + | |
| 31 | + def get_token(self, expire_time=24): | |
| 32 | + expires_delta = timedelta(expire_time) | |
| 33 | + token = create_access_token(identity=self.user_id, expires_delta=expires_delta) | |
| 34 | + | |
| 35 | + db = k2.extensions['sqlalchemy'].db | |
| 36 | + connection = db.engine.connect() | |
| 37 | + result = connection.execute( | |
| 38 | + db.text(f"SELECT rolename FROM k2roles where roleid = '{self.roleid}'")).fetchone() | |
| 39 | + rolename = result[0] if result else None | |
| 40 | + | |
| 41 | + userData = { | |
| 42 | + "avatar": "/src/assets/images/avatars/avatar-4.png", | |
| 43 | + "email": self.email, | |
| 44 | + "fullName": self.name, | |
| 45 | + "id": self.user_id, | |
| 46 | + "role": rolename, | |
| 47 | + "username": self.login | |
| 48 | + } | |
| 49 | + | |
| 50 | + userAbilities = [] | |
| 51 | + | |
| 52 | + abilities_query = f""" | |
| 53 | + SELECT menus.namemenu, | |
| 54 | + prava.r, prava.w, prava.i, prava.d, prava.c, prava.exp, prava.imp, prava.settable, prava.cutpast, | |
| 55 | + prava.enable, prava.del | |
| 56 | + FROM k2admin_menus menus | |
| 57 | + JOIN k2admin_menus_prava prava ON menus.menuid = prava.menuid | |
| 58 | + WHERE prava.roleid = {self.roleid} | |
| 59 | + """ | |
| 60 | + abilities_list = connection.execute(db.text(abilities_query)).fetchall() | |
| 61 | + | |
| 62 | + for ability in abilities_list: | |
| 63 | + abilities_dict = { | |
| 64 | + "subject": ability[0], | |
| 65 | + "read": ability[1], | |
| 66 | + "write": ability[2], | |
| 67 | + "insert": ability[3], | |
| 68 | + "delete": ability[4], | |
| 69 | + "copy": ability[5], | |
| 70 | + "export": ability[6], | |
| 71 | + "import": ability[7], | |
| 72 | + "settable": ability[8], | |
| 73 | + "cutpast": ability[9], | |
| 74 | + "enable": ability[10], | |
| 75 | + "del": ability[11], | |
| 76 | + } | |
| 77 | + | |
| 78 | + abilities_dict_copy = abilities_dict.copy() | |
| 79 | + for key, value in abilities_dict_copy.items(): | |
| 80 | + if value == 0: | |
| 81 | + del abilities_dict[key] | |
| 82 | + userAbilities.append(abilities_dict) | |
| 83 | + #________________________________________________________________________________________ | |
| 84 | + | |
| 85 | + menu_query = f""" | |
| 86 | + SELECT menus.prevmenu, menus.namemenu, menus.caption, menus.url | |
| 87 | + FROM k2admin_menus menus | |
| 88 | + JOIN k2admin_menus_prava prava ON menus.menuid = prava.menuid | |
| 89 | + WHERE prava.roleid = '{self.roleid}' | |
| 90 | + """ | |
| 91 | + menus = connection.execute(db.text(menu_query)).fetchall() | |
| 92 | + | |
| 93 | + menus_dict = {} | |
| 94 | + for menu in menus: | |
| 95 | + menus_dict[menu[0]] = [] | |
| 96 | + | |
| 97 | + for key in menus_dict: | |
| 98 | + for el in menus: | |
| 99 | + if key == el[0]: | |
| 100 | + menus_dict[key].append( | |
| 101 | + { | |
| 102 | + "namemenu": el[1], | |
| 103 | + "caption": el[2], | |
| 104 | + "url": el[3] | |
| 105 | + }) | |
| 106 | + | |
| 107 | + print(menus_dict) | |
| 108 | + | |
| 109 | + | |
| 110 | + #________________________________________________________________________________________ | |
| 111 | + | |
| 112 | + return (token, userData, userAbilities) | |
| 113 | + | |
| 114 | + | |
| 115 | + @classmethod | |
| 116 | + def authenticate(cls, login, password): | |
| 117 | + session = k2.extensions['sqlalchemy'].db.session | |
| 118 | + user = '' | |
| 119 | + try: | |
| 120 | + user = session.query(cls).filter(cls.login == login).filter(cls.password == hashlib.md5(password.encode()).hexdigest()).one() | |
| 121 | + except: | |
| 122 | + user = None | |
| 123 | + return user | |
| 124 | + | |
| 125 | + @classmethod | |
| 126 | + def user_by_login(cls, login): | |
| 127 | + session = k2.extensions['sqlalchemy'].db.session | |
| 128 | + user = session.query(cls).filter(cls.login == login).first() | |
| 129 | + return user |
components/k2auth/k2auth/views.py
| 1 | +# import hashlib | |
| 2 | +# import uuid | |
| 3 | +from flask import Blueprint, request, jsonify | |
| 4 | +from flask import current_app as k2 | |
| 5 | +from flask_jwt_extended import jwt_required | |
| 6 | +import re | |
| 7 | +from .models import k2users | |
| 8 | + | |
| 9 | +k2auth = Blueprint('k2auth', __name__, template_folder='templates', static_folder='static', static_url_path='/vue2') | |
| 10 | + | |
| 11 | + | |
| 12 | +class Auth(): | |
| 13 | + def __init__(self): | |
| 14 | + pass | |
| 15 | + | |
| 16 | + def register(self): | |
| 17 | + params = request.json | |
| 18 | + session = k2.extensions['sqlalchemy'].db.session | |
| 19 | + password = params.get('password') | |
| 20 | + login = params.get('login') | |
| 21 | + user_exist = k2users.user_by_login(login) | |
| 22 | + if user_exist: | |
| 23 | + return jsonify({'status': '409', 'message': 'Such user exist'}), 409 | |
| 24 | + | |
| 25 | + if len(password) < 6: | |
| 26 | + return jsonify({'status': '400', 'message': 'password has not 6 simbols'}), 400 | |
| 27 | + if re.search(r'[a-zA-Z]', password) is None or re.search(r'\d', password) is None: | |
| 28 | + return jsonify({'status': '400', 'message': 'Password must contain both letters and numbers'}), 400 | |
| 29 | + | |
| 30 | + try: | |
| 31 | + user = k2users(**params) | |
| 32 | + session.add(user) | |
| 33 | + session.commit() | |
| 34 | + token, userData, userAbilities = user.get_token() | |
| 35 | + return {'accessToken': token, "userData": userData, "userAbilities": userAbilities} | |
| 36 | + except: | |
| 37 | + return jsonify({'status': '400', 'message': "Missing required fields"}), 400 | |
| 38 | + | |
| 39 | + | |
| 40 | + def login(self): | |
| 41 | + params = request.json | |
| 42 | + user = k2users.authenticate(**params) | |
| 43 | + if user: | |
| 44 | + token, userData, userAbilities = user.get_token() | |
| 45 | + return {'accessToken': token, "userData": userData, "userAbilities": userAbilities} | |
| 46 | + else: | |
| 47 | + # k2.logger.error(('%s failed to log in ', params.get('login'), params.get('password'))) | |
| 48 | + return jsonify({'status': '401', 'message': 'Unauthorized'}), 401 | |
| 49 | + | |
| 50 | + | |
| 51 | + @jwt_required() | |
| 52 | + def logout(self): | |
| 53 | + response = { | |
| 54 | + 'message': 'Logged out successfully' | |
| 55 | + } | |
| 56 | + return jsonify(response) | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | +auth = Auth() | |
| 61 | +k2auth.add_url_rule('/login', methods=['POST'], view_func=auth.login) | |
| 62 | +k2auth.add_url_rule('/logout', methods=['GET'], view_func=auth.logout) | |
| 63 | +k2auth.add_url_rule('/register', methods=['POST'], view_func=auth.register) |
components/k2auth/requirements.txt
| 1 | +alembic==1.11.1 | |
| 2 | +Babel==2.12.1 | |
| 3 | +bcrypt==4.0.1 | |
| 4 | +bidict==0.22.1 | |
| 5 | +blinker==1.6.2 | |
| 6 | +certifi==2023.5.7 | |
| 7 | +charset-normalizer==3.1.0 | |
| 8 | +click==8.1.3 | |
| 9 | +colorama==0.4.6 | |
| 10 | +dnspython==2.3.0 | |
| 11 | +email-validator==2.0.0.post2 | |
| 12 | +Flask==2.3.2 | |
| 13 | +flask-babel==3.1.0 | |
| 14 | +Flask-Bcrypt==1.0.1 | |
| 15 | +Flask-Cors==3.0.10 | |
| 16 | +Flask-JWT-Extended==4.5.2 | |
| 17 | +Flask-Login==0.6.2 | |
| 18 | +Flask-Migrate==4.0.4 | |
| 19 | +Flask-MySQLdb==1.0.1 | |
| 20 | +Flask-SQLAlchemy==3.0.3 | |
| 21 | +flask-staticdirs==1.0.1 | |
| 22 | +Flask-WTF==1.1.1 | |
| 23 | +greenlet==2.0.2 | |
| 24 | +idna==3.4 | |
| 25 | +itsdangerous==2.1.2 | |
| 26 | +Jinja2==3.1.2 | |
| 27 | +jsonify==0.5 | |
| 28 | +Mako==1.2.4 | |
| 29 | +MarkupSafe==2.1.2 | |
| 30 | +mysql==0.0.3 | |
| 31 | +mysql-connector==2.2.9 | |
| 32 | +mysql-connector-python==8.0.33 | |
| 33 | +mysqlclient==2.1.1 | |
| 34 | +peppercorn==0.6 | |
| 35 | +protobuf==3.20.3 | |
| 36 | +PyJWT==2.7.0 | |
| 37 | +python-engineio==4.4.1 | |
| 38 | +python-socketio==5.8.0 | |
| 39 | +pytz==2023.3 | |
| 40 | +PyYAML==6.0 | |
| 41 | +requests==2.31.0 | |
| 42 | +six==1.16.0 | |
| 43 | +SQLAlchemy==2.0.15 | |
| 44 | +typing_extensions==4.6.2 | |
| 45 | +urllib3==2.0.2 | |
| 46 | +Werkzeug==2.3.4 | |
| 47 | +WTForms==3.0.1 |
components/k2auth/setup.py
| 1 | +from setuptools import setup | |
| 2 | + | |
| 3 | +setup( | |
| 4 | + name='k2auth', | |
| 5 | + version='1.0.0', | |
| 6 | + description='Description of my project', | |
| 7 | + author='k2 cloud', | |
| 8 | + author_email='ys@corp2.eu', | |
| 9 | + keywords="k2auth, k2", | |
| 10 | + python_requires=">=3.7, <=3.11.2", | |
| 11 | + packages=['k2auth'], | |
| 12 | + package_data={ # Optional | |
| 13 | + }, | |
| 14 | + install_requires=[""], | |
| 15 | +) |
components/k2test/__pycache__/__init__.cpython-310.pyc
No preview for this file type
components/k2test/k2test/__pycache__/__init__.cpython-310.pyc
No preview for this file type
components/k2test/k2test/__pycache__/views.cpython-310.pyc
No preview for this file type
components/k2test/k2test/languages/en/LC_MESSAGES/messages.mo
No preview for this file type
components/k2test/k2test/languages/uk/LC_MESSAGES/messages.mo
No preview for this file type
components/k2test/k2test/views.py
db/database.db
No preview for this file type
k2/__pycache__/__init__.cpython-310.pyc
No preview for this file type
k2/__pycache__/k2admmenu.cpython-310.pyc
No preview for this file type
k2/__pycache__/k2cfg.cpython-310.pyc
No preview for this file type
k2/__pycache__/k2comp.cpython-310.pyc
No preview for this file type
k2/__pycache__/k2obj.cpython-310.pyc
No preview for this file type
k2/__pycache__/k2rout.cpython-310.pyc
No preview for this file type
k2/k2admmenu.py
| ... | ... | @@ -2,6 +2,7 @@ |
| 2 | 2 | import uuid |
| 3 | 3 | from .k2cfg import k2 |
| 4 | 4 | |
| 5 | + | |
| 5 | 6 | db = k2.db |
| 6 | 7 | |
| 7 | 8 | class K2admin_menus(db.Model): |
| 8 | 9 | |
| 9 | 10 | |
| ... | ... | @@ -23,13 +24,26 @@ |
| 23 | 24 | caption = db.Column(db.String(1024)) |
| 24 | 25 | url = db.Column(db.String(2048)) |
| 25 | 26 | |
| 27 | + | |
| 26 | 28 | def __init__(self, **kwargs): |
| 27 | 29 | self.menuid = hashlib.md5(str(uuid.uuid4()).encode()).hexdigest() |
| 28 | 30 | super(K2admin_menus, self).__init__(**kwargs) |
| 31 | + | |
| 32 | + | |
| 29 | 33 | def __repr__(self): |
| 30 | 34 | return f"{self.namemenu}')" |
| 31 | 35 | |
| 32 | - | |
| 36 | + @classmethod | |
| 37 | + def get_menu_items_by_roles(cls, roleid): | |
| 38 | + menu_query = f""" | |
| 39 | + SELECT menus.namemenu | |
| 40 | + FROM k2admin_menus menus | |
| 41 | + JOIN k2admin_menus_prava prava ON menus.menuid = prava.menuid | |
| 42 | + WHERE prava.roleid = '{roleid}' | |
| 43 | + """ | |
| 44 | + result = db.session.execute(db.text(menu_query)).fetchall() | |
| 45 | + menu_items = [item[0].decode('utf-8') for item in result] | |
| 46 | + return menu_items | |
| 33 | 47 | |
| 34 | 48 | class K2admin_Menus_Prava(db.Model): |
| 35 | 49 | __tablename__ = 'k2admin_menus_prava' |
k2/k2rout.py
| ... | ... | @@ -15,10 +15,10 @@ |
| 15 | 15 | import sys |
| 16 | 16 | from .k2admmenu import K2admin_menus, K2admin_Menus_Prava |
| 17 | 17 | from sqlalchemy import text |
| 18 | +from flask_jwt_extended import get_jwt_identity | |
| 18 | 19 | |
| 19 | 20 | |
| 20 | 21 | |
| 21 | - | |
| 22 | 22 | # initialize db |
| 23 | 23 | # migrate = Migrate(app, db) |
| 24 | 24 | |
| 25 | 25 | |
| 26 | 26 | |
| ... | ... | @@ -471,10 +471,26 @@ |
| 471 | 471 | |
| 472 | 472 | @components_bp.route('/api/main-menu/') |
| 473 | 473 | def get_admin_menu(): |
| 474 | - requests.get(f"{k2.domain}api/add-to-menu") | |
| 475 | - return k2.menu | |
| 474 | + current_user = get_jwt_identity() | |
| 475 | + print(current_user) | |
| 476 | + role_id = current_user['user_role'] | |
| 477 | + filter_menu = [] | |
| 478 | + response = requests.get(f"{k2.domain}api/add-to-menu") | |
| 479 | + menu_items_list = K2admin_menus.get_menu_items_by_roles(role_id) | |
| 476 | 480 | |
| 481 | + for item in response.json(): | |
| 482 | + filtered_children = [] | |
| 483 | + for im in item['children']: | |
| 484 | + if im['to'] in menu_items_list: | |
| 485 | + filtered_children.append(im) | |
| 486 | + if filtered_children: | |
| 487 | + item['children'] = filtered_children | |
| 488 | + filter_menu.append(item) | |
| 489 | + filter_menu.append({"heading": 'APPS & PAGES'}) | |
| 477 | 490 | |
| 491 | + return jsonify(filter_menu) | |
| 492 | + | |
| 493 | + | |
| 478 | 494 | def add_menu_with_permissions_db(name_menu, prev_menu, caption_menu): |
| 479 | 495 | |
| 480 | 496 | # Створення об'єкта k2admin_menus |
| ... | ... | @@ -505,7 +521,7 @@ |
| 505 | 521 | settable=0, |
| 506 | 522 | cutpast=0, |
| 507 | 523 | enable=0, |
| 508 | - roleid=1 | |
| 524 | + roleid=-1 | |
| 509 | 525 | ) |
| 510 | 526 | # Додавання об'єкта k2admin_menus_prava до сесії |
| 511 | 527 | db.session.add(new_prava) |
| ... | ... | @@ -515,6 +531,7 @@ |
| 515 | 531 | @components_bp.route('/menu-admin-items') |
| 516 | 532 | def menu_items(): |
| 517 | 533 | menu = [ |
| 534 | + | |
| 518 | 535 | { |
| 519 | 536 | "title": 'Add components', |
| 520 | 537 | "icon": {"icon": 'mdi-account-circle-outline'}, |
languages/babel_translation_directories.yml
| 1 | -babel_translation_directories: languages;components/k2test/k2test/languages;components/grid/grid/languages;components/adm/adm/languages;components/k2auth/k2auth/languages | |
| 1 | +babel_translation_directories: languages;components/k2test/k2test/languages;components/k2auth/k2auth/languages;components/k2adm/k2adm/languages |
routes.py
| ... | ... | @@ -4,4 +4,8 @@ |
| 4 | 4 | app.register_blueprint(components_bp) |
| 5 | 5 | from components.k2test.k2test.views import k2test |
| 6 | 6 | app.register_blueprint(k2test, url_prefix='/k2test') |
| 7 | +from components.k2auth.k2auth.views import k2auth | |
| 8 | +app.register_blueprint(k2auth, url_prefix='/k2auth') | |
| 9 | +from components.k2adm.k2adm.views import k2adm | |
| 10 | +app.register_blueprint(k2adm, url_prefix='/k2adm') |