QQ与Gitea绑定部分完成
This commit is contained in:
parent
b03b659736
commit
a3688bad16
2
cmds.py
2
cmds.py
@ -29,7 +29,7 @@ def cmds(app, data):
|
|||||||
else:
|
else:
|
||||||
user = User(id=sqt.sender_id, name=sqt.sender_name, state=state)
|
user = User(id=sqt.sender_id, name=sqt.sender_name, state=state)
|
||||||
await user.save()
|
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'client_id={app.ctx.sio_config.client_id}&'
|
||||||
f'redirect_uri={app.ctx.sio_config.localhost}/redirect&'
|
f'redirect_uri={app.ctx.sio_config.localhost}/redirect&'
|
||||||
f'response_type=code&state={state}')
|
f'response_type=code&state={state}')
|
||||||
|
10
models.py
10
models.py
@ -6,11 +6,13 @@ class User(Model):
|
|||||||
id = fields.BigIntField(pk=True, autoincrement=False)
|
id = fields.BigIntField(pk=True, autoincrement=False)
|
||||||
name = fields.CharField(max_length=60)
|
name = fields.CharField(max_length=60)
|
||||||
state = fields.CharField(max_length=60)
|
state = fields.CharField(max_length=60)
|
||||||
|
gitea_users = fields.ReverseRelation['GiteaUser']
|
||||||
|
|
||||||
|
|
||||||
class GiteaUser(Model):
|
class GiteaUser(Model):
|
||||||
id = fields.BigIntField(pk=True, autoincrement=False)
|
id = fields.BigIntField(pk=True, autoincrement=False)
|
||||||
qid = fields.ForeignKeyField('models.GiteaUser')
|
qid: fields.ForeignKeyRelation[User] = fields.ForeignKeyField(
|
||||||
name = fields.CharField(max_length=20)
|
'models.User', related_name='gitea_users')
|
||||||
ac_tk = fields.CharField(max_length=256)
|
name = fields.CharField(max_length=60)
|
||||||
rfs_tk = fields.CharField(max_length=256)
|
ac_tk = fields.CharField(max_length=2048)
|
||||||
|
rfs_tk = fields.CharField(max_length=2048)
|
||||||
|
60
server.py
60
server.py
@ -1,6 +1,7 @@
|
|||||||
import tomllib
|
import tomllib
|
||||||
from typing import Dict, Any, List, Tuple
|
from typing import Dict, Any, List, Tuple
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
import casbin
|
import casbin
|
||||||
from casbin_tortoise_adapter import TortoiseAdapter
|
from casbin_tortoise_adapter import TortoiseAdapter
|
||||||
from nacl.signing import SigningKey
|
from nacl.signing import SigningKey
|
||||||
@ -12,6 +13,7 @@ from tortoise.contrib.sanic import register_tortoise
|
|||||||
|
|
||||||
import cmds
|
import cmds
|
||||||
from gitea_model import WebHookIssueComment, WebHookIssue, GiteaEvent
|
from gitea_model import WebHookIssueComment, WebHookIssue, GiteaEvent
|
||||||
|
from models import User, GiteaUser
|
||||||
from sio_model import Ctx, SioConfig, Message
|
from sio_model import Ctx, SioConfig, Message
|
||||||
from unit import sio_log_format, int2str, cas_log_fmt
|
from unit import sio_log_format, int2str, cas_log_fmt
|
||||||
|
|
||||||
@ -95,10 +97,64 @@ async def receive(rqt: Request):
|
|||||||
return text(rsp)
|
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')
|
@app.get('/redirect')
|
||||||
async def redirect(rqt: Request):
|
async def redirect(rqt: Request):
|
||||||
print(rqt.args)
|
rqt_state = rqt.args.get('state')
|
||||||
print(rqt.ctx.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')
|
return text('success')
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ class SioConfig(BaseModel):
|
|||||||
key: str = Field(alias='private_key')
|
key: str = Field(alias='private_key')
|
||||||
self_id: int
|
self_id: int
|
||||||
admin: List[int]
|
admin: List[int]
|
||||||
validate_host: str
|
gitea_host: str
|
||||||
client_id: str
|
client_id: str
|
||||||
client_secret: str
|
client_secret: str
|
||||||
localhost: str
|
localhost: str
|
||||||
|
Loading…
Reference in New Issue
Block a user