diff --git a/0001-fix-token-is-not-invalidated-after-being-refreshed.patch b/0001-fix-token-is-not-invalidated-after-being-refreshed.patch new file mode 100644 index 0000000000000000000000000000000000000000..7f3b1495d387cdb691f76e98c17bf3c45d821e4c --- /dev/null +++ b/0001-fix-token-is-not-invalidated-after-being-refreshed.patch @@ -0,0 +1,115 @@ +From 9ab3df8bcd61a07a5eeade60053b30db84409610 Mon Sep 17 00:00:00 2001 +From: gongzt +Date: Thu, 27 Apr 2023 10:12:42 +0800 +Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=88=B7=E6=96=B0token?= + =?UTF-8?q?=E5=90=8E=EF=BC=8C=E6=97=A7=E7=9A=84token=E4=BB=8D=E7=84=B6?= + =?UTF-8?q?=E7=94=9F=E6=95=88=EF=BC=8C=E4=BB=A5=E5=8F=8A=E9=80=80=E5=87=BA?= + =?UTF-8?q?=E7=99=BB=E5=BD=95=E5=90=8E=E6=97=A7=E7=9A=84token=E6=9C=89?= + =?UTF-8?q?=E6=95=88?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +--- + zeus/account_manager/view.py | 49 +++++++++++++++++++++++++++++------- + zeus/url.py | 4 ++- + 2 files changed, 43 insertions(+), 10 deletions(-) + +diff --git a/zeus/account_manager/view.py b/zeus/account_manager/view.py +index 68194d0..40a0658 100644 +--- a/zeus/account_manager/view.py ++++ b/zeus/account_manager/view.py +@@ -15,6 +15,8 @@ Time: + Author: + Description: Restful APIs for user + """ ++from jwt.exceptions import ExpiredSignatureError ++ + from vulcanus.conf.constant import REFRESH_TOKEN_EXP + from vulcanus.database.proxy import RedisProxy + from vulcanus.log.log import LOGGER +@@ -182,20 +184,49 @@ class RefreshToken(BaseResponse): + Returns: + dict: response body + """ +- status = self.verify_token(params.get("refresh_token"), params) +- if status != state.SUCCEED: +- return self.response(code=status, message="token refreshing failure.") + try: +- username = decode_token(params.get("refresh_token"))["key"] ++ refresh_token_info = decode_token(params.get("refresh_token")) ++ except ExpiredSignatureError: ++ return self.response(code=state.TOKEN_EXPIRE) ++ except ValueError: ++ self.response(code=state.TOKEN_ERROR, message="token refreshing failure.") ++ ++ username = refresh_token_info["key"] ++ old_refresh_token = RedisProxy.redis_connect.get("refresh_token_" + username) ++ if not old_refresh_token or old_refresh_token != params.get("refresh_token"): ++ return self.response(code=state.TOKEN_ERROR, message="Invalid token.") ++ ++ try: + token = generate_token(unique_iden=username) +- refresh_token = generate_token( +- unique_iden=username, minutes=REFRESH_TOKEN_EXP) ++ refresh_token = generate_token(unique_iden=username, minutes=REFRESH_TOKEN_EXP) + except ValueError: + LOGGER.error("Token generation failed,token refreshing failure.") + return self.response(code=state.GENERATION_TOKEN_ERROR) +- ++ # Remove an expired token ++ RedisProxy.redis_connect.delete("token_" + username) ++ RedisProxy.redis_connect.delete("refresh_token_" + username) ++ # Set a new token value + RedisProxy.redis_connect.set("token_" + username, token) +- RedisProxy.redis_connect.set( +- "refresh_token_" + username, refresh_token) ++ RedisProxy.redis_connect.set("refresh_token_" + username, refresh_token) + + return self.response(code=state.SUCCEED, data=dict(token=token, refresh_token=refresh_token)) ++ ++ ++class Logout(BaseResponse): ++ """ ++ Interface for logout. ++ Restful API: post ++ """ ++ ++ @BaseResponse.handle() ++ def post(self, **params): ++ """ ++ Refresh token ++ ++ Returns: ++ dict: response body ++ """ ++ username = params.get("username") ++ RedisProxy.redis_connect.delete("token_" + username) ++ RedisProxy.redis_connect.delete("refresh_token_" + username) ++ return self.response(code=state.SUCCEED) +\ No newline at end of file +diff --git a/zeus/url.py b/zeus/url.py +index ae31276..4f1e78e 100644 +--- a/zeus/url.py ++++ b/zeus/url.py +@@ -44,7 +44,8 @@ from vulcanus.conf.constant import ( + QUERY_METRIC_NAMES, + QUERY_METRIC_DATA, + QUERY_METRIC_LIST, +- REFRESH_TOKEN ++ REFRESH_TOKEN, ++ LOGOUT + ) + from zeus.account_manager import view as account_view + from zeus.agent_manager import view as agent_view +@@ -64,6 +65,7 @@ SPECIFIC_URLS = { + (account_view.AuthRedirectUrl, AUTH_REDIRECT_URL), + (account_view.BindAuthAccount, BIND_AUTH_ACCOUNT), + (account_view.RefreshToken, REFRESH_TOKEN), ++ (account_view.Logout, LOGOUT), + ], + "HOST_URLS": [ + (host_view.AddHost, ADD_HOST), +-- +Gitee + diff --git a/0002-update-args-validation-rules-and-update-add-host-by-batch.patch b/0002-update-args-validation-rules-and-update-add-host-by-batch.patch new file mode 100644 index 0000000000000000000000000000000000000000..0653eeea58eb27d681d66f7d21f24cbd6f2368a5 --- /dev/null +++ b/0002-update-args-validation-rules-and-update-add-host-by-batch.patch @@ -0,0 +1,164 @@ +From f392c0ca19c019a092c62ffb4fd6f1f2f1d2da5c Mon Sep 17 00:00:00 2001 +From: rabbitali +Date: Mon, 24 Apr 2023 15:35:07 +0800 +Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B7=BB=E5=8A=A0=E4=B8=BB?= + =?UTF-8?q?=E6=9C=BA=E6=8E=A5=E5=8F=A3=E4=B8=BB=E6=9C=BA=E5=90=8D=E7=A7=B0?= + =?UTF-8?q?=E6=A0=A1=E9=AA=8C=E8=A7=84=E5=88=99;=E6=9B=B4=E6=96=B0?= + =?UTF-8?q?=E6=B3=A8=E5=86=8C=E7=94=A8=E6=88=B7=E6=8E=A5=E5=8F=A3=E7=9A=84?= + =?UTF-8?q?=E5=8F=82=E6=95=B0=E6=A0=A1=E9=AA=8C=E8=A7=84=E5=88=99,?= + =?UTF-8?q?=E4=B8=8E=E5=89=8D=E7=AB=AF=E4=BF=9D=E6=8C=81=E4=B8=80=E8=87=B4?= + =?UTF-8?q?;=E6=9B=B4=E6=96=B0=E6=89=B9=E9=87=8F=E6=B7=BB=E5=8A=A0?= + =?UTF-8?q?=E4=B8=BB=E6=9C=BA=E6=8E=A5=E5=8F=A3?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +--- + aops-zeus.spec | 2 +- + setup.py | 3 ++- + zeus/function/verify/acount.py | 5 +++-- + zeus/function/verify/host.py | 4 +++- + zeus/host_manager/view.py | 38 ++++++++++++++++++++++++++-------- + 5 files changed, 38 insertions(+), 14 deletions(-) + +diff --git a/aops-zeus.spec b/aops-zeus.spec +index ab83ead..2a6f94d 100644 +--- a/aops-zeus.spec ++++ b/aops-zeus.spec +@@ -9,7 +9,7 @@ Source0: %{name}-%{version}.tar.gz + + BuildRequires: python3-setuptools + Requires: aops-vulcanus >= v1.2.0 +-Requires: python3-marshmallow >= 3.13.0 python3-flask python3-flask-restful ++Requires: python3-marshmallow >= 3.13.0 python3-flask python3-flask-restful python3-gevent + Requires: python3-requests python3-uWSGI python3-sqlalchemy python3-werkzeug python3-PyMySQL + Requires: python3-paramiko >= 2.11.0 python3-redis python3-prometheus-api-client + Provides: aops-zeus +diff --git a/setup.py b/setup.py +index 46d4408..469ee11 100644 +--- a/setup.py ++++ b/setup.py +@@ -19,7 +19,8 @@ setup( + 'Werkzeug', + 'paramiko>=2.11.0', + "redis", +- 'prometheus_api_client' ++ 'prometheus_api_client', ++ 'gevent' + ], + author='cmd-lsw-yyy-zyc', + data_files=[ +diff --git a/zeus/function/verify/acount.py b/zeus/function/verify/acount.py +index b8bd67f..dfc3220 100644 +--- a/zeus/function/verify/acount.py ++++ b/zeus/function/verify/acount.py +@@ -15,6 +15,7 @@ Time: + Author: + Description: For host related interfaces + """ ++from vulcanus.restful.serialize.validate import ValidateRules + from marshmallow import Schema + from marshmallow import fields + +@@ -23,8 +24,8 @@ class LoginSchema(Schema): + """ + validators for parameter of /manage/account/login + """ +- username = fields.String(required=True, validate=lambda s: len(s) > 0) +- password = fields.String(required=True, validate=lambda s: len(s) > 0) ++ username = fields.String(required=True, validate=ValidateRules.account_name_check) ++ password = fields.String(required=True, validate=ValidateRules.account_password_check) + + + class AddUserSchema(LoginSchema): +diff --git a/zeus/function/verify/host.py b/zeus/function/verify/host.py +index f955975..4866947 100644 +--- a/zeus/function/verify/host.py ++++ b/zeus/function/verify/host.py +@@ -15,6 +15,7 @@ Time: + Author: + Description: For host related interfaces + """ ++from vulcanus.restful.serialize.validate import ValidateRules + from marshmallow import Schema + from marshmallow import fields + from marshmallow import validate +@@ -101,7 +102,8 @@ class AddHostSchema(Schema): + """ + ssh_user = fields.String(required=True, validate=lambda s: len(s) > 0) + password = fields.String(required=True, validate=lambda s: len(s) > 0) +- host_name = fields.String(required=True, validate=lambda s: len(s) > 0) ++ host_name = fields.String(required=True, ++ validate=[validate.Length(min=1, max=50), ValidateRules.space_character_check]) + host_ip = fields.IP(required=True) + ssh_port = fields.Integer(required=True, validate=lambda s: 65535 >= s > 0) + host_group_name = fields.String(required=True, validate=lambda s: len(s) > 0) +diff --git a/zeus/host_manager/view.py b/zeus/host_manager/view.py +index a5af075..8dd4c2b 100644 +--- a/zeus/host_manager/view.py ++++ b/zeus/host_manager/view.py +@@ -16,10 +16,12 @@ Author: + Description: Restful APIs for host + """ + import json +-import socket + from io import BytesIO + from typing import Iterable, List, Tuple, Union ++from gevent import monkey; monkey.patch_all(ssl=False) ++import socket + ++import gevent + import paramiko + from flask import request, send_file + from marshmallow import Schema +@@ -523,14 +525,8 @@ class AddHostBatch(BaseResponse): + message="invalid host info or all hosts has been added", + data=self.add_result) + +- # Generate Rsa-key pair and save public_key on host +- multi_thread = MultiThreadHandler(lambda data: self.update_rsa_key_to_host(*data), +- valid_hosts, None) +- multi_thread.create_thread() +- result = multi_thread.get_result() +- +- # Add host +- status = proxy.add_host_batch(result) ++ # save public_key on host and add host to database ++ status = proxy.add_host_batch(self.save_key_to_client(valid_hosts)) + if status != state.SUCCEED: + self.update_add_result(valid_hosts, + {"result": self.add_failed, "reason": "Insert Database error"}) +@@ -605,6 +601,30 @@ class AddHostBatch(BaseResponse): + valid_host.append((host, password)) + return valid_host + ++ def save_key_to_client(self, host_connect_infos: List[tuple]) -> list: ++ """ ++ save key to client ++ ++ Args: ++ host_connect_infos (list): client connect info ++ ++ Returns: ++ host object list ++ """ ++ # 30 connections are created at a time. ++ tasks = [host_connect_infos[index:index + 30] for index in range(0, len(host_connect_infos), 30)] ++ result = [] ++ ++ for task in tasks: ++ jobs = [gevent.spawn(self.update_rsa_key_to_host, *host_connect_info) ++ for host_connect_info in task] ++ ++ gevent.joinall(jobs) ++ for job in jobs: ++ result.append(job.value) ++ ++ return result ++ + @staticmethod + def update_rsa_key_to_host(host: Host, password: str) -> Host: + """ +-- +Gitee + diff --git a/aops-zeus.spec b/aops-zeus.spec index 14bd8c5cc39b5e552d1fe2d43f0b6e39933e7c74..15918832ecc54de729f36edadc43689132965579 100644 --- a/aops-zeus.spec +++ b/aops-zeus.spec @@ -1,15 +1,17 @@ Name: aops-zeus Version: v1.2.0 -Release: 1 +Release: 2 Summary: A host and user manager service which is the foundation of aops. License: MulanPSL2 URL: https://gitee.com/openeuler/%{name} Source0: %{name}-%{version}.tar.gz +Patch0001: 0001-fix-token-is-not-invalidated-after-being-refreshed.patch +Patch0002: 0002-update-args-validation-rules-and-update-add-host-by-batch.patch BuildRequires: python3-setuptools Requires: aops-vulcanus >= v1.2.0 -Requires: python3-marshmallow >= 3.13.0 python3-flask python3-flask-restful +Requires: python3-marshmallow >= 3.13.0 python3-flask python3-flask-restful python3-gevent Requires: python3-requests python3-uWSGI python3-sqlalchemy python3-werkzeug python3-PyMySQL Requires: python3-paramiko >= 2.11.0 python3-redis python3-prometheus-api-client Provides: aops-zeus @@ -21,7 +23,7 @@ A host and user manager service which is the foundation of aops. %prep -%autosetup -n %{name}-%{version} +%autosetup -n %{name}-%{version} -p1 # build for aops-zeus @@ -42,6 +44,11 @@ A host and user manager service which is the foundation of aops. %changelog +* Thu Apr 27 2023 wenixn - v1.2.0-2 +- Fix token is not invalidated after the token was refreshed +- update args validation rules for add account and for add host +- replace thread scheduling with gevent scheduling when add host by batch + * Mon Apr 17 2023 wenixn - v1.2.0-1 - update the call method of ceres; add function how to add host from web - add api: update host info