commit 36669b71c4cc3a48eee69437001ed2213cdefaef Author: yumoqing Date: Thu Jul 3 19:28:56 2025 +0800 first commit diff --git a/json/build.sh b/json/build.sh new file mode 100755 index 0000000..6fd2291 --- /dev/null +++ b/json/build.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +xls2ui -m ../models -o ../wwwroot kyapikey *.json diff --git a/kyapikey/client.py b/kyapikey/client.py new file mode 100644 index 0000000..778510f --- /dev/null +++ b/kyapikey/client.py @@ -0,0 +1,15 @@ + +from time import time +from appPublic.aes import aes_encrypt_ecb, aes_decrypt_ecb + +def build_beardata(appid, apikey, secretkey): + """ + this appid is isusses by upapp we connect to, + secretkey is with the appid, is s fixed key from upapp + apikey is user's apikey assigned by upapp when the users is synchronous to upapp + """ + t = time() + txt = f'{t}:{apikey} + cyber = aes_encrypt_ecb(secretkey, txt) + return f'Bear {appid}-:-{cyber}' + diff --git a/kyapikey/server.py b/kyapikey/server.py new file mode 100644 index 0000000..c25842d --- /dev/null +++ b/kyapikey/server.py @@ -0,0 +1,115 @@ +from traceback import format_exc +from appPublic.log import debug, exception, info +from appPublic.timeUtils import curDateString +from time import time +from ahserver.serverenv import ServerEnv +from sqlor.dbpools import DBPools + +from appPublic.aes import aes_encrypt_ecb, aes_decrypt_ecb + +return_messages = { + -9: '用户同步:未知未知错误', + -4: '用户同步:添加用户apikey失败', + -3: '用户同步:添加用户失败', + -2: '用户同步:添加机构失败', + -1: '用户同步:用户已同步' +} + +def get_dbname(): + dbname = get_serverenv('get_module_dbname')('dapi') + return dbname + +def get_secretkey(sor, appid): + recs = await sor.R('downapp', {'id':appid}) + if len(recs) < 1: + return None + secret_key = recs[0].secret_key + f = get_serverenv('password_decode') + return f(secret_key).encode('utf-8') + +async def get_apikey_user(sor, apikey): + f = get_serverenv('password_encode') + apikey = f(apikey) + users = await sor.R('downapikey', {'apikey': apikey}) + if len(users) < 1: + return None + apiuser = users[0] + if not apiuser.enabled: + e = Exception(f'user(id={apiuser.userid}) is not enabled') + exception(f'{e},{format_exc()}') + raise e + if apiuser.expires_at < curDateString(): + e = Exception(f"user(id={apiuser.userid})'s apikey is expired({apiuser.expires_at})') + exception(f'{e}, {format_exc()}') + raise e + users = await sor.R('users', {'id': apiuser.userid, 'orgid': apiuser.orgid}) + if len(users) < 1: + e = Exception(f'user(id={apiuser.userid}) not found in users') + exception(f'{e}, {format_exc()}') + raise e + return users[0] + +asunc def build_beardata(appid, apikey, secretkey): + t = time() + txt = f'{t}:{apikey} + cyber = aes_encrypt_ecb(secretkey, txt) + return f'Bear {appid}-:-{cyber}' + +async def get_user_from_bear_data(self, bear_data): + if not bear_data[:5] == 'Bear ': + return None + bear_data = bear_data[5:] + appid, cyber = bear_data.split('-:-') + db = DBPools() + dbname = get_dbname() + async with db.sqlorContext(dbname) as sor: + secretkey = await get_secretkey(sor, appid) + apikey = aes_decrypt_ecb(secretkey, cyber) + userinfo = await get_apikey_user(apikey) + return userinfo + + return None + +def return_error(code): + return { + 'status':'error', + 'errcode': code, + 'errmsg': return_messages.get(code, '未定义信息') + } + +def return_success(data): + return { + 'status':'success', + 'data':data + } + +async def sync_user(request, params_kw, *args, **kw): + dappid = params_kw.dappid + db = DBPools() + dbname = get_dbname() + async with db.sqlorContext(dbname) as sor: + ret_users = [] + for o in params_ke.organizations: + for u in o['users']: + exists = check_dorgid_exists(sor, dappid, o['id']) + if not exists: + orgid = await add_organzation(sor, dappid, o) + if orgid is None: + return return_error(-2) + u['orgid'] = o['id'] + exists = check_duserid_exists(sor, dappid, u) + if exists: + return return_error(-1) + userid = await add_user(sor, u) + if userid is None: + return return_error(-3) + apikey = await add_apikey(sor, dappid, orgid, userid, u) + if apikey is None: + return return_error(-4) + ret_users.append({ + 'id': u['id'], + 'apikey': apikey + }) + return return_success(ret_users) + return return_error(-9) + diff --git a/models/kydownapikey.xlsx b/models/kydownapikey.xlsx new file mode 100644 index 0000000..f452696 Binary files /dev/null and b/models/kydownapikey.xlsx differ diff --git a/models/kydownapp.xlsx b/models/kydownapp.xlsx new file mode 100644 index 0000000..d02a9f2 Binary files /dev/null and b/models/kydownapp.xlsx differ diff --git a/models/kyupapp.xlsx b/models/kyupapp.xlsx new file mode 100644 index 0000000..3631e08 Binary files /dev/null and b/models/kyupapp.xlsx differ diff --git a/models/kyupuserapikey.xlsx b/models/kyupuserapikey.xlsx new file mode 100644 index 0000000..4d20fa0 Binary files /dev/null and b/models/kyupuserapikey.xlsx differ diff --git a/models/mysql.ddl.sql b/models/mysql.ddl.sql new file mode 100644 index 0000000..942b88e --- /dev/null +++ b/models/mysql.ddl.sql @@ -0,0 +1,58 @@ + +-- ./downapikey.xlsx + + + + + +drop table if exists downapikey; +CREATE TABLE downapikey +( + + `id` VARCHAR(32) comment 'id', + `dappid` VARCHAR(32) comment '下位系统id', + `orgid` VARCHAR(32) DEFAULT '0' comment '机构id', + `userid` VARCHAR(32) comment '用户id', + `apikey` VARCHAR(32) comment 'akikey', + `secretkey` VARCHAR(32) comment '加密密码', + `enabled` VARCHAR(1) comment '是否启用', + `created_at` date comment '创建日期', + `expires_at` date comment '失效日期' + + +,primary key(id) + + +) +engine=innodb +default charset=utf8 +comment '下位系统apikey' +; + + +-- ./downapp.xlsx + + + + + +drop table if exists downapp; +CREATE TABLE downapp +( + + `id` VARCHAR(32) comment 'id', + `name` VARCHAR(200) comment '下位应用名', + `description` longtext DEFAULT '0' comment '描述', + `secret_key` VARCHAR(32) comment '加密key' + + +,primary key(id) + + +) +engine=innodb +default charset=utf8 +comment '下位系统' +; + +