Commit 0966a93c9fc9e6066557a3965d61fcfa2af0dd45
1 parent
2cd26db164
add k2adm
Showing 17 changed files with 338 additions and 7 deletions Side-by-side Diff
- .gitignore
- __pycache__/main.cpython-310.pyc
- __pycache__/routes.cpython-310.pyc
- components/k2adm/__pycache__/__init__.cpython-310.pyc
- components/k2adm/k2adm/README.md
- components/k2adm/k2adm/__pycache__/__init__.cpython-310.pyc
- components/k2adm/k2adm/__pycache__/models.cpython-310.pyc
- components/k2adm/k2adm/__pycache__/views.cpython-310.pyc
- components/k2adm/k2adm/models.py
- components/k2adm/k2adm/requirements.txt
- components/k2adm/k2adm/setup.py
- components/k2adm/k2adm/views.py
- components/k2auth/k2auth/views.py
- db/first-login.yml
- languages/babel_translation_directories.yml
- routes.py
- yml/users.yml
.gitignore
__pycache__/main.cpython-310.pyc
No preview for this file type
__pycache__/routes.cpython-310.pyc
No preview for this file type
components/k2adm/__pycache__/__init__.cpython-310.pyc
No preview for this file type
components/k2adm/k2adm/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/k2adm/k2adm/__pycache__/__init__.cpython-310.pyc
No preview for this file type
components/k2adm/k2adm/__pycache__/models.cpython-310.pyc
No preview for this file type
components/k2adm/k2adm/__pycache__/views.cpython-310.pyc
No preview for this file type
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, decode_token | |
| 5 | +from datetime import timedelta | |
| 6 | +import hashlib | |
| 7 | +from flask import current_app as k2 | |
| 8 | + | |
| 9 | + | |
| 10 | +Base = declarative_base() | |
| 11 | + | |
| 12 | +class k2users(Base): | |
| 13 | + __tablename__ = 'k2users' | |
| 14 | + user_id = Column(Integer, primary_key=True) | |
| 15 | + login = Column(String(50), unique=True) | |
| 16 | + name = Column(String(50)) | |
| 17 | + email = Column(String(150)) | |
| 18 | + password = Column(String(50)) | |
| 19 | + phone = Column(String(20)) | |
| 20 | + firstname = Column(String(50)) | |
| 21 | + roleid = Column(String(50)) | |
| 22 | + | |
| 23 | + def __init__(self, **kwargs): | |
| 24 | + self.user_id = hashlib.md5(str(uuid.uuid4()).encode()).hexdigest() | |
| 25 | + self.login = kwargs.get('login') | |
| 26 | + self.password = hashlib.md5(kwargs.get('password').encode()).hexdigest() | |
| 27 | + self.name = kwargs.get('name') | |
| 28 | + self.email = kwargs.get('email') | |
| 29 | + self.phone = kwargs.get('phone') | |
| 30 | + self.firstname = kwargs.get('firstname') | |
| 31 | + self.roleid = kwargs.get('roleid') | |
| 32 | + | |
| 33 | + | |
| 34 | + def get_token(self, expire_time=24): | |
| 35 | + expires_delta = timedelta(expire_time) | |
| 36 | + token = create_access_token(identity=self.user_id, expires_delta=expires_delta) | |
| 37 | + if self.roleid == '1': | |
| 38 | + role = 'admin' | |
| 39 | + else: | |
| 40 | + role = "client" | |
| 41 | + | |
| 42 | + userData = { | |
| 43 | + "avatar": "/src/assets/images/avatars/avatar-4.png", | |
| 44 | + "email": self.email, | |
| 45 | + "fullName": self.name, | |
| 46 | + "id": self.user_id, | |
| 47 | + "role": role, | |
| 48 | + "username": self.login | |
| 49 | + | |
| 50 | + } | |
| 51 | + if self.roleid != '1': | |
| 52 | + userAbilities = [ | |
| 53 | + { | |
| 54 | + "action": "read", | |
| 55 | + "subject": "Auth"}, | |
| 56 | + | |
| 57 | + { | |
| 58 | + "action": "read", | |
| 59 | + "subject": "AclDemo"} | |
| 60 | + ] | |
| 61 | + else: | |
| 62 | + userAbilities = [ | |
| 63 | + { | |
| 64 | + "action": "manage", | |
| 65 | + "subject": "all" | |
| 66 | + } | |
| 67 | + ] | |
| 68 | + return (token, userData,userAbilities) | |
| 69 | + | |
| 70 | + @classmethod | |
| 71 | + def authenticate(cls, login, password): | |
| 72 | + session = k2.extensions['sqlalchemy'].db.session | |
| 73 | + user = '' | |
| 74 | + try: | |
| 75 | + user = session.query(cls).filter(cls.login == login).filter(cls.password == hashlib.md5(password.encode()).hexdigest()).one() | |
| 76 | + except: | |
| 77 | + user = None | |
| 78 | + return user | |
| 79 | + | |
| 80 | + @classmethod | |
| 81 | + def user_by_login(cls, login): | |
| 82 | + session = k2.extensions['sqlalchemy'].db.session | |
| 83 | + user = session.query(cls).filter(cls.login == login).first() | |
| 84 | + return user |
components/k2adm/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/k2adm/setup.py
| 1 | +from setuptools import setup | |
| 2 | + | |
| 3 | +setup( | |
| 4 | + name='adm', | |
| 5 | + version='1.0.0', | |
| 6 | + description='Description of my project', | |
| 7 | + author='Your Name', | |
| 8 | + author_email='yourname@example.com', | |
| 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/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 | + | |
| 7 | + | |
| 8 | +from .models import k2users | |
| 9 | + | |
| 10 | + | |
| 11 | +k2adm = Blueprint('adm', __name__, template_folder='templates', static_folder='static', static_url_path='/adm') | |
| 12 | + | |
| 13 | + | |
| 14 | +@k2adm.route('/usersclients', methods=["GET"]) | |
| 15 | +@jwt_required() | |
| 16 | +def users_clients(): | |
| 17 | + return jsonify({"data": "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 | +# @adm.route('/register', methods=["POST"]) | |
| 34 | +# def register(): | |
| 35 | +# params = request.json | |
| 36 | +# session = k2.extensions['sqlalchemy'].db.session | |
| 37 | +# exist = k2users.user_by_login(request.json['login']) | |
| 38 | +# if not exist: | |
| 39 | +# user = k2users(**params) | |
| 40 | +# session.add(user) | |
| 41 | +# session.commit() | |
| 42 | +# token, userData, userAbilities = user.get_token() | |
| 43 | +# return {'accessToken': token, "userData": userData, "userAbilities": userAbilities} | |
| 44 | +# else: | |
| 45 | +# return jsonify({'error': 'User exist'}), 401 | |
| 46 | + | |
| 47 | + | |
| 48 | +# @adm.route('/login', methods=["POST"]) | |
| 49 | +# def login(): | |
| 50 | +# params = request.json | |
| 51 | +# user = k2users.authenticate(**params) | |
| 52 | +# if user: | |
| 53 | +# token, userData, userAbilities = user.get_token() | |
| 54 | +# return {'accessToken': token, "userData": userData, "userAbilities": userAbilities} | |
| 55 | +# else: | |
| 56 | +# return jsonify({'error': 'Unauthorized'}), 401 | |
| 57 | + | |
| 58 | + | |
| 59 | +# @adm.route('/logout', methods=["GET"]) | |
| 60 | +# @jwt_required() | |
| 61 | +# def logout(): | |
| 62 | +# | |
| 63 | +# response = { | |
| 64 | +# 'message': 'Logged out successfully' | |
| 65 | +# } | |
| 66 | + | |
| 67 | + # return jsonify(response) | |
| 68 | + | |
| 69 | + | |
| 70 | +@k2adm.route('/api_get_roles', methods=["GET"]) | |
| 71 | +@jwt_required() | |
| 72 | +def roles(): | |
| 73 | + db = k2.extensions['sqlalchemy'].db | |
| 74 | + connection = db.engine.connect() | |
| 75 | + query = db.text("SELECT roleid, rolename FROM k2roles") | |
| 76 | + result = connection.execute(query).fetchall() | |
| 77 | + roles = [dict(id=res.roleid, role=res.rolename) for res in result] | |
| 78 | + return {'roles': roles} | |
| 79 | + | |
| 80 | + | |
| 81 | +@k2adm.route('/newUser', methods=["GET", "POST"]) | |
| 82 | +@jwt_required() | |
| 83 | +def newUser(): | |
| 84 | + session = k2.extensions['sqlalchemy'].db.session | |
| 85 | + exist = k2users.user_by_login(request.json['login']) | |
| 86 | + if not exist: | |
| 87 | + res = k2users( | |
| 88 | + user_id=hashlib.md5(str(uuid.uuid4()).encode()).hexdigest(), | |
| 89 | + login=request.json['login'], | |
| 90 | + name=request.json['name'], | |
| 91 | + email=request.json['email'], | |
| 92 | + password=hashlib.md5(request.json['password'].encode()).hexdigest(), | |
| 93 | + phone=request.json['phone']) | |
| 94 | + if res: | |
| 95 | + session.add(res) | |
| 96 | + session.commit() | |
| 97 | + return jsonify({'status': 'ok'}) | |
| 98 | + else: | |
| 99 | + return jsonify({'error': 'Such user exist'}), 404 | |
| 100 | + | |
| 101 | + | |
| 102 | +@k2adm.route('/changePassword', methods=["POST"]) | |
| 103 | +@jwt_required() | |
| 104 | +def changePassword(): | |
| 105 | + session = k2.extensions['sqlalchemy'].db.session | |
| 106 | + current_user = get_jwt_identity() | |
| 107 | + user = session.query(k2users).filter_by(user_id=current_user).first() | |
| 108 | + if user.password == hashlib.md5(request.json['old_password'].encode()).hexdigest(): | |
| 109 | + if request.json['new_password'] == request.json['re_new_password']: | |
| 110 | + user.password = hashlib.md5(request.json['new_password'].encode()).hexdigest() | |
| 111 | + session.commit() | |
| 112 | + else: | |
| 113 | + return jsonify({'error': 'Пароль не найден в базе'}), 404 | |
| 114 | + else: | |
| 115 | + return jsonify({'error': 'Пароль не совпвдает'}), 404 | |
| 116 | + return jsonify({'status': 'ok'}) | |
| 117 | + | |
| 118 | + | |
| 119 | +@k2adm.route('/menu-items') | |
| 120 | +def menu_items(): | |
| 121 | + menu = [ | |
| 122 | + { | |
| 123 | + "title": 'Site administration', | |
| 124 | + "icon": {"icon": 'mdi-account-circle-outline'}, | |
| 125 | + "children": [ | |
| 126 | + {'title': 'Password change', 'to': 'adm-changePassword'}, | |
| 127 | + {'title': 'New user', 'to': 'adm-newUser'}, | |
| 128 | + {'title': 'Users', 'to': 'adm-users'}, | |
| 129 | + {'title': 'Users are clients', 'to': 'adm-usersclients'}, | |
| 130 | + {'title': 'Roles', 'to': 'adm-roles'}, | |
| 131 | + {'title': 'Access to the menu', 'to': 'adm-menuaaccess'}, | |
| 132 | + ], | |
| 133 | + }] | |
| 134 | + | |
| 135 | + return menu |
components/k2auth/k2auth/views.py
| ... | ... | @@ -6,7 +6,7 @@ |
| 6 | 6 | |
| 7 | 7 | from .models import k2users |
| 8 | 8 | |
| 9 | -k2auth = Blueprint('k2auth', __name__, template_folder='templates', static_folder='static', static_url_path='/adm') | |
| 9 | +k2auth = Blueprint('k2auth', __name__, template_folder='templates', static_folder='static', static_url_path='/vue2') | |
| 10 | 10 | |
| 11 | 11 | |
| 12 | 12 | class Auth(): |
db/first-login.yml
languages/babel_translation_directories.yml
routes.py
yml/users.yml