QQ与Gitea绑定部分完成

This commit is contained in:
San Liy 2023-12-20 23:29:54 +08:00
parent b03b659736
commit a3688bad16
4 changed files with 66 additions and 8 deletions

View File

@ -29,7 +29,7 @@ def cmds(app, data):
else:
user = User(id=sqt.sender_id, name=sqt.sender_name, state=state)
await user.save()
url = (f'{app.ctx.sio_config.validate_host}/login/oauth/authorize?'
url = (f'{app.ctx.sio_config.gitea_host}/login/oauth/authorize?'
f'client_id={app.ctx.sio_config.client_id}&'
f'redirect_uri={app.ctx.sio_config.localhost}/redirect&'
f'response_type=code&state={state}')

View File

@ -6,11 +6,13 @@ class User(Model):
id = fields.BigIntField(pk=True, autoincrement=False)
name = fields.CharField(max_length=60)
state = fields.CharField(max_length=60)
gitea_users = fields.ReverseRelation['GiteaUser']
class GiteaUser(Model):
id = fields.BigIntField(pk=True, autoincrement=False)
qid = fields.ForeignKeyField('models.GiteaUser')
name = fields.CharField(max_length=20)
ac_tk = fields.CharField(max_length=256)
rfs_tk = fields.CharField(max_length=256)
qid: fields.ForeignKeyRelation[User] = fields.ForeignKeyField(
'models.User', related_name='gitea_users')
name = fields.CharField(max_length=60)
ac_tk = fields.CharField(max_length=2048)
rfs_tk = fields.CharField(max_length=2048)

View File

@ -1,6 +1,7 @@
import tomllib
from typing import Dict, Any, List, Tuple
import aiohttp
import casbin
from casbin_tortoise_adapter import TortoiseAdapter
from nacl.signing import SigningKey
@ -12,6 +13,7 @@ from tortoise.contrib.sanic import register_tortoise
import cmds
from gitea_model import WebHookIssueComment, WebHookIssue, GiteaEvent
from models import User, GiteaUser
from sio_model import Ctx, SioConfig, Message
from unit import sio_log_format, int2str, cas_log_fmt
@ -95,10 +97,64 @@ async def receive(rqt: Request):
return text(rsp)
async def get_gitea_token(_app, form: dict, q_user: User):
async with aiohttp.ClientSession() as session:
url = f'{app.ctx.sio_config.gitea_host}/login/oauth/access_token'
async with session.post(url, data=form) as rps:
if rps.status == 200:
json = await rps.json()
act = json['access_token']
rft = json['refresh_token']
else:
logger.warn(f'Gitea: {rps}')
return f'绑定失败:{await rps.text()}'
url = f'{app.ctx.sio_config.gitea_host}/api/v1/user'
headers = {'Authorization': f'token {act}'}
async with session.get(url, headers=headers) as rps:
if rps.status == 200:
json = await rps.json()
gid = json['id']
login = json['login']
else:
logger.warn(f'Gitea: {rps}')
return f'绑定失败:{await rps.text()}'
g_user = await GiteaUser.filter(id=gid).get_or_none()
if g_user:
g_user.id = gid
g_user.name = login
g_user.qid = q_user
g_user.ac_tk = act
g_user.rfs_tk = rft
await g_user.save()
else:
await GiteaUser(id=gid, name=login, qid=q_user, ac_tk=act, rfs_tk=rft).save()
return f'绑定成功QQ:{q_user.name}, Gitea:{login}'
@app.get('/redirect')
async def redirect(rqt: Request):
print(rqt.args)
print(rqt.ctx.state)
rqt_state = rqt.args.get('state')
code = rqt.args.get('code')
if rqt_state is None or code is None:
logger.warn(f'Gitea返回消息格式错误{rqt.args}')
return text(f'返回信息错误:{rqt.args}')
q_user = await User.filter(state=rqt_state).get_or_none()
if q_user is None:
logger.warn(f'该请求不是从QQ中请求的链接')
return text('请从QQ处申请绑定')
msg = Message(content='已在绑定中,可能因为意外而失败', room_id=q_user.id)
await app.ctx.sio.emit('sendMessage', msg.to_json())
await app.add_task(get_gitea_token(app, {'client_id': app.ctx.sio_config.client_id,
'client_secret': app.ctx.sio_config.client_secret,
'code': code,
'grant_type': 'authorization_code',
'redirect_uri': f'{app.ctx.sio_config.localhost}/redirect'},
q_user), name=str(q_user.id))
return text('success')

View File

@ -69,7 +69,7 @@ class SioConfig(BaseModel):
key: str = Field(alias='private_key')
self_id: int
admin: List[int]
validate_host: str
gitea_host: str
client_id: str
client_secret: str
localhost: str