141 lines
3.6 KiB
Python

import json
from time import time
from traceback import format_exc
from functools import partial
from sqlor.dbpools import DBPools, get_sor_context
from appPublic.Singleton import SingletonDecorator
from appPublic.streamhttpclient import StreamHttpClient, liner
from appPublic.dictObject import DictObject
from appPublic.log import debug, exception, error
from appPublic.aes import aes_encode_b64
from ahserver.globalEnv import password_decode
from ahserver.serverenv import get_serverenv, ServerEnv
from random import randint
async def get_deerer(upappid, callerid):
db = DBPools()
dbname = get_dbname()
async with db.sqlorContext(dbname) as sor:
ki = await get_userapikey(sor, upappid, callerid)
d = deerer(ki.myappid, ki.apikey, ki.secretkey)
if not d:
return None
return d[7:]
return None
async def sor_get_uapi(sor, upappid, apiname):
sql = """select a.*,
b.auth_apiname
from uapi a, upapp b
where a.upappid = b.id
and a.name = ${apiname}$
and b.id = ${upappid}$"""
recs = await sor.sqlExe(sql, {'upappid': upappid, 'apiname': apiname})
if len(recs) == 0:
debug(f'{sql=},{upappid=}, {apiname=} uapi not found')
return None
return recs[0]
def deerer(myappid, apikey, secretkey):
t = time()
txt = f'{t}:{apikey}'
cyber = aes_encode_b64(secretkey, txt)
return f'Deerer {myappid}-:-{cyber}'
def bearer(apikey):
return f'Bearer {apikey}'
@SingletonDecorator
class UAPIData:
def __init__(self):
self.apidata = {}
self.apikeys = {}
self.org_users = {}
async def get_userapikey(self, appid, callerid):
users = await self.get_apiusers(appid)
for u in users:
if u.userid == callerid:
return DictObject(**{
'apikey':u.apikey,
'secretkey':u.secretkey,
'baseurl':u.baseurl,
'appownerid': u.ownerid,
'dynamic_func_name': u.dynamic_func,
'myappid': u.myappid
})
return None
async def get_apiusers(self, appid, orgid=None):
key = appid
d = self.org_users.get(key)
if d:
return d
env = ServerEnv()
async with get_sor_context(env, 'uapi') as sor:
sql = """select
c.id,
c.ownerid,
c.myappid,
c.baseurl,
c.secretkey,
c.dynamic_func,
a.ownerid as userid,
a.orgid as userorgid,
a.apikey
from upappkey a, users b, upapp c
where b.orgid = c.ownerid
and a.ownerid = b.id
and a.upappid = c.id
and a.upappid = ${appid}$
"""
ns = {'appid': appid, 'orgid': orgid}
if orgid:
sql += " and a.orgid = ${orgid}$"
else:
sql += " and a.orgid = c.ownerid"
d = await sor.sqlExe(sql, ns)
for r in d:
r.apikey = None if r.apikey is None else password_decode(r.apikey)
r.secretkey = None if r.secretkey is None else password_decode(r.secretkey)
if d is None:
e = Exception(f'{appid=} {orgid=} get none user')
exception(f'{e}')
raise e
self.apidata[key] = d
return d
e = Exception(f'{appid=} {orgid=} get none user')
exception(f'{e}')
raise e
async def get_calluserid(self, appid, orgid=None):
users = await self.get_apiusers(appid, orgid=orgid)
cnt = len(users)
if cnt < 1:
e = Exception(f'get_calluserid():{appid=}, {orgid=} return None')
exception(f'{e}')
raise e
i = randint(0, cnt - 1)
return users[i].userid
async def get_api(self, appid, apiname):
key = f'{appid}.{apiname}'
api = self.apidata.get(key)
if api:
return api
env = ServerEnv()
async with get_sor_context(env, 'uapi') as sor:
d = await sor_get_uapi(sor, appid, apiname)
if d is None:
e = Exception(f'{appid=}, {apiname=} get none api')
exception(f'{e}')
raise e
self.apidata[key] = d
return d
e = Exception(f'{appid=}, {apiname=} get none api')
exception(f'{e}')
raise e