From 0966a93c9fc9e6066557a3965d61fcfa2af0dd45 Mon Sep 17 00:00:00 2001 From: Yana Date: Mon, 19 Jun 2023 14:51:56 +0200 Subject: [PATCH] add k2adm --- .gitignore | 2 +- __pycache__/main.cpython-310.pyc | Bin 779 -> 779 bytes __pycache__/routes.cpython-310.pyc | Bin 496 -> 502 bytes components/k2adm/__init__.py | 0 .../k2adm/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 144 bytes components/k2adm/k2adm/README.md | 45 +++++++ components/k2adm/k2adm/__init__.py | 0 .../k2adm/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 150 bytes .../k2adm/k2adm/__pycache__/models.cpython-310.pyc | Bin 0 -> 2478 bytes .../k2adm/k2adm/__pycache__/views.cpython-310.pyc | Bin 0 -> 3249 bytes components/k2adm/k2adm/models.py | 89 ++++++++++++++ components/k2adm/k2adm/requirements.txt | 47 +++++++ components/k2adm/k2adm/setup.py | 15 +++ components/k2adm/k2adm/views.py | 135 +++++++++++++++++++++ components/k2auth/k2auth/views.py | 2 +- db/first-login.yml | 2 +- languages/babel_translation_directories.yml | 2 +- routes.py | 4 +- yml/users.yml | 2 +- 19 files changed, 338 insertions(+), 7 deletions(-) create mode 100644 components/k2adm/__init__.py create mode 100644 components/k2adm/__pycache__/__init__.cpython-310.pyc create mode 100644 components/k2adm/k2adm/README.md create mode 100644 components/k2adm/k2adm/__init__.py create mode 100644 components/k2adm/k2adm/__pycache__/__init__.cpython-310.pyc create mode 100644 components/k2adm/k2adm/__pycache__/models.cpython-310.pyc create mode 100644 components/k2adm/k2adm/__pycache__/views.cpython-310.pyc create mode 100644 components/k2adm/k2adm/models.py create mode 100644 components/k2adm/k2adm/requirements.txt create mode 100644 components/k2adm/k2adm/setup.py create mode 100644 components/k2adm/k2adm/views.py diff --git a/.gitignore b/.gitignore index 2da5d63..c59c9bc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -/components/adm/ +/components/vue2/ /components/grid/ /components/vue/ diff --git a/__pycache__/main.cpython-310.pyc b/__pycache__/main.cpython-310.pyc index b6eabe74f06438de1788479df728663dec7688ac..4b2076bd27020e955ee0736594c2a3043149e1bb 100644 GIT binary patch delta 26 gcmeBX>t^H1=jG*M0D@BQja&tcj2)Y+87D9T07y6m^#A|> delta 26 gcmeBX>t^H1=jG*M0D^M4ja&tcjBhqqGfrRx07#AoE&u=k diff --git a/__pycache__/routes.cpython-310.pyc b/__pycache__/routes.cpython-310.pyc index 086743dd3c175c75acd601cf1b327e2461e084ca..91228c457fc0fbcad5a01699c90ab5c77ccab8ea 100644 GIT binary patch delta 53 zcmeys{EeA6pO=@50SI>aPDn|a$ora^HQQ+7&o&X6l48AVqr{Y4AUV08 GF%baF2@&i7 delta 47 zcmeyy{DGM_pO=@50SFjfCZxnng`k0(svFDIoeWh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6vQKO;XkRlhPZ zFHzsn(!fkV+o&i%zeGPdKer%1FEy{E7$}mMlB*vdpP83g5+AQuPg`kg3pc M0~uM&1SD7(00JK&Jpcdz literal 0 HcmV?d00001 diff --git a/components/k2adm/k2adm/__pycache__/models.cpython-310.pyc b/components/k2adm/k2adm/__pycache__/models.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c315ae14ec32611c9161a15d0f7ac80de15894a6 GIT binary patch literal 2478 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 YQ*m7MEAA0`k@~fQnOP>9uU6Q90AI*Ui2wiq literal 0 HcmV?d00001 diff --git a/components/k2adm/k2adm/models.py b/components/k2adm/k2adm/models.py new file mode 100644 index 0000000..738e07e --- /dev/null +++ b/components/k2adm/k2adm/models.py @@ -0,0 +1,89 @@ +import uuid +from sqlalchemy import Column, Integer, String +from sqlalchemy.ext.declarative import declarative_base +from flask_jwt_extended import create_access_token, decode_token +from datetime import timedelta +import hashlib +from flask import current_app as k2 + + +Base = declarative_base() + +class k2users(Base): + __tablename__ = 'k2users' + user_id = Column(Integer, primary_key=True) + login = Column(String(50), unique=True) + name = Column(String(50)) + email = Column(String(150)) + password = Column(String(50)) + phone = Column(String(20)) + firstname = Column(String(50)) + roleid = Column(String(50)) + + def __init__(self, **kwargs): + self.user_id = hashlib.md5(str(uuid.uuid4()).encode()).hexdigest() + self.login = kwargs.get('login') + self.password = hashlib.md5(kwargs.get('password').encode()).hexdigest() + self.name = kwargs.get('name') + self.email = kwargs.get('email') + self.phone = kwargs.get('phone') + self.firstname = kwargs.get('firstname') + self.roleid = kwargs.get('roleid') + + + def get_token(self, expire_time=24): + expires_delta = timedelta(expire_time) + token = create_access_token(identity=self.user_id, expires_delta=expires_delta) + if self.roleid == '1': + role = 'admin' + else: + role = "client" + + userData = { + "avatar": "/src/assets/images/avatars/avatar-4.png", + "email": self.email, + "fullName": self.name, + "id": self.user_id, + "role": role, + "username": self.login + + } + if self.roleid != '1': + userAbilities = [ + { + "action": "read", + "subject": "Auth"}, + + { + "action": "read", + "subject": "AclDemo"} + ] + else: + userAbilities = [ + { + "action": "manage", + "subject": "all" + } + ] + return (token, userData,userAbilities) + + @classmethod + def authenticate(cls, login, password): + session = k2.extensions['sqlalchemy'].db.session + user = '' + try: + user = session.query(cls).filter(cls.login == login).filter(cls.password == hashlib.md5(password.encode()).hexdigest()).one() + except: + user = None + return user + + @classmethod + def user_by_login(cls, login): + session = k2.extensions['sqlalchemy'].db.session + user = session.query(cls).filter(cls.login == login).first() + return user + + + + + diff --git a/components/k2adm/k2adm/requirements.txt b/components/k2adm/k2adm/requirements.txt new file mode 100644 index 0000000..4807af4 --- /dev/null +++ b/components/k2adm/k2adm/requirements.txt @@ -0,0 +1,47 @@ +alembic==1.11.1 +Babel==2.12.1 +bcrypt==4.0.1 +bidict==0.22.1 +blinker==1.6.2 +certifi==2023.5.7 +charset-normalizer==3.1.0 +click==8.1.3 +colorama==0.4.6 +dnspython==2.3.0 +email-validator==2.0.0.post2 +Flask==2.3.2 +flask-babel==3.1.0 +Flask-Bcrypt==1.0.1 +Flask-Cors==3.0.10 +Flask-JWT-Extended==4.5.2 +Flask-Login==0.6.2 +Flask-Migrate==4.0.4 +Flask-MySQLdb==1.0.1 +Flask-SQLAlchemy==3.0.3 +flask-staticdirs==1.0.1 +Flask-WTF==1.1.1 +greenlet==2.0.2 +idna==3.4 +itsdangerous==2.1.2 +Jinja2==3.1.2 +jsonify==0.5 +Mako==1.2.4 +MarkupSafe==2.1.2 +mysql==0.0.3 +mysql-connector==2.2.9 +mysql-connector-python==8.0.33 +mysqlclient==2.1.1 +peppercorn==0.6 +protobuf==3.20.3 +PyJWT==2.7.0 +python-engineio==4.4.1 +python-socketio==5.8.0 +pytz==2023.3 +PyYAML==6.0 +requests==2.31.0 +six==1.16.0 +SQLAlchemy==2.0.15 +typing_extensions==4.6.2 +urllib3==2.0.2 +Werkzeug==2.3.4 +WTForms==3.0.1 \ No newline at end of file diff --git a/components/k2adm/k2adm/setup.py b/components/k2adm/k2adm/setup.py new file mode 100644 index 0000000..8370eae --- /dev/null +++ b/components/k2adm/k2adm/setup.py @@ -0,0 +1,15 @@ +from setuptools import setup + +setup( + name='adm', + version='1.0.0', + description='Description of my project', + author='Your Name', + author_email='yourname@example.com', + keywords="adm, k2", + python_requires=">=3.7, <=3.11.2", + packages=['adm'], + package_data={ # Optional + }, + install_requires=[""], +) \ No newline at end of file diff --git a/components/k2adm/k2adm/views.py b/components/k2adm/k2adm/views.py new file mode 100644 index 0000000..82d0ba5 --- /dev/null +++ b/components/k2adm/k2adm/views.py @@ -0,0 +1,135 @@ +import hashlib +import uuid +from flask import Blueprint, request, jsonify +from flask import current_app as k2 +from flask_jwt_extended import jwt_required, get_jwt_identity + + +from .models import k2users + + +k2adm = Blueprint('adm', __name__, template_folder='templates', static_folder='static', static_url_path='/adm') + + +@k2adm.route('/usersclients', methods=["GET"]) +@jwt_required() +def users_clients(): + return jsonify({"data": "roles"}) + + +@k2adm.route('/users', methods=["GET"]) +@jwt_required() +def grid_users(): + return jsonify({"data": "users"}) + + +@k2adm.route('/roles', methods=["GET"]) +@jwt_required() +def grid_roles(): + return jsonify({"data": "roles"}) + + + +# @adm.route('/register', methods=["POST"]) +# def register(): +# params = request.json +# session = k2.extensions['sqlalchemy'].db.session +# exist = k2users.user_by_login(request.json['login']) +# if not exist: +# user = k2users(**params) +# session.add(user) +# session.commit() +# token, userData, userAbilities = user.get_token() +# return {'accessToken': token, "userData": userData, "userAbilities": userAbilities} +# else: +# return jsonify({'error': 'User exist'}), 401 + + +# @adm.route('/login', methods=["POST"]) +# def login(): +# params = request.json +# user = k2users.authenticate(**params) +# if user: +# token, userData, userAbilities = user.get_token() +# return {'accessToken': token, "userData": userData, "userAbilities": userAbilities} +# else: +# return jsonify({'error': 'Unauthorized'}), 401 + + +# @adm.route('/logout', methods=["GET"]) +# @jwt_required() +# def logout(): +# +# response = { +# 'message': 'Logged out successfully' +# } + + # return jsonify(response) + + +@k2adm.route('/api_get_roles', methods=["GET"]) +@jwt_required() +def roles(): + db = k2.extensions['sqlalchemy'].db + connection = db.engine.connect() + query = db.text("SELECT roleid, rolename FROM k2roles") + result = connection.execute(query).fetchall() + roles = [dict(id=res.roleid, role=res.rolename) for res in result] + return {'roles': roles} + + +@k2adm.route('/newUser', methods=["GET", "POST"]) +@jwt_required() +def newUser(): + session = k2.extensions['sqlalchemy'].db.session + exist = k2users.user_by_login(request.json['login']) + if not exist: + res = k2users( + user_id=hashlib.md5(str(uuid.uuid4()).encode()).hexdigest(), + login=request.json['login'], + name=request.json['name'], + email=request.json['email'], + password=hashlib.md5(request.json['password'].encode()).hexdigest(), + phone=request.json['phone']) + if res: + session.add(res) + session.commit() + return jsonify({'status': 'ok'}) + else: + return jsonify({'error': 'Such user exist'}), 404 + + +@k2adm.route('/changePassword', methods=["POST"]) +@jwt_required() +def changePassword(): + session = k2.extensions['sqlalchemy'].db.session + current_user = get_jwt_identity() + user = session.query(k2users).filter_by(user_id=current_user).first() + if user.password == hashlib.md5(request.json['old_password'].encode()).hexdigest(): + if request.json['new_password'] == request.json['re_new_password']: + user.password = hashlib.md5(request.json['new_password'].encode()).hexdigest() + session.commit() + else: + return jsonify({'error': 'Пароль не найден в базе'}), 404 + else: + return jsonify({'error': 'Пароль не совпвдает'}), 404 + return jsonify({'status': 'ok'}) + + +@k2adm.route('/menu-items') +def menu_items(): + menu = [ + { + "title": 'Site administration', + "icon": {"icon": 'mdi-account-circle-outline'}, + "children": [ + {'title': 'Password change', 'to': 'adm-changePassword'}, + {'title': 'New user', 'to': 'adm-newUser'}, + {'title': 'Users', 'to': 'adm-users'}, + {'title': 'Users are clients', 'to': 'adm-usersclients'}, + {'title': 'Roles', 'to': 'adm-roles'}, + {'title': 'Access to the menu', 'to': 'adm-menuaaccess'}, + ], + }] + + return menu \ No newline at end of file diff --git a/components/k2auth/k2auth/views.py b/components/k2auth/k2auth/views.py index ac5e7d5..a8b5533 100644 --- a/components/k2auth/k2auth/views.py +++ b/components/k2auth/k2auth/views.py @@ -6,7 +6,7 @@ from flask_jwt_extended import jwt_required from .models import k2users -k2auth = Blueprint('k2auth', __name__, template_folder='templates', static_folder='static', static_url_path='/adm') +k2auth = Blueprint('k2auth', __name__, template_folder='templates', static_folder='static', static_url_path='/vue2') class Auth(): diff --git a/db/first-login.yml b/db/first-login.yml index c7ce326..dbe5bce 100644 --- a/db/first-login.yml +++ b/db/first-login.yml @@ -1,3 +1,3 @@ users: - - username: adm + - username: vue2 password: k2cloud123456 \ No newline at end of file diff --git a/languages/babel_translation_directories.yml b/languages/babel_translation_directories.yml index a0533f7..a8fa0f7 100644 --- a/languages/babel_translation_directories.yml +++ b/languages/babel_translation_directories.yml @@ -1 +1 @@ -babel_translation_directories: languages;components/k2test/k2test/languages;components/grid/grid/languages;components/adm/adm/languages +babel_translation_directories: languages;components/k2test/k2test/languages;components/grid/grid/languages;components/vue2/vue2/languages diff --git a/routes.py b/routes.py index 889322a..ad8abd3 100644 --- a/routes.py +++ b/routes.py @@ -15,5 +15,5 @@ from components.k2auth.k2auth.views import k2auth app.register_blueprint(k2auth, url_prefix='/k2auth') -from components.adm.adm.views import adm -app.register_blueprint(adm, url_prefix='/adm') \ No newline at end of file +from components.k2adm.k2adm.views import k2adm +app.register_blueprint(k2adm, url_prefix='/adm') \ No newline at end of file diff --git a/yml/users.yml b/yml/users.yml index c006ecc..48bda0c 100644 --- a/yml/users.yml +++ b/yml/users.yml @@ -79,7 +79,7 @@ fields: type_field: condition cond: exp: (false) - url2: "/?adm=k2adminfunc_changepassword&userid={login}&mode=admin" + url2: "/?vue2=k2adminfunc_changepassword&userid={login}&mode=admin" caption2: "Змінити" -- 1.9.1