restructure static file directory
parent
9eed55164a
commit
6721ae550d
|
@ -192,3 +192,28 @@ async def delete_group_chat(group_chat_id: str, members: list[str]):
|
|||
raise Exception
|
||||
finally:
|
||||
await session.close()
|
||||
|
||||
|
||||
async def delete_group_chat_member(group_chat_id: str, member_id: str):
|
||||
session = async_session()
|
||||
try:
|
||||
group_chat: GroupChat = (
|
||||
await session.scalars(
|
||||
select(GroupChat).where(GroupChat.id == group_chat_id)
|
||||
)
|
||||
).one()
|
||||
group_chat.members.remove(member_id)
|
||||
flag_modified(group_chat, "members")
|
||||
|
||||
contact: Contact = (
|
||||
await session.scalars(select(Contact).where(Contact.user_id == member_id))
|
||||
).one()
|
||||
del contact.group_chats[group_chat_id]
|
||||
flag_modified(contact, "group_chats")
|
||||
|
||||
session.add_all([group_chat, contact])
|
||||
await session.commit()
|
||||
except Exception:
|
||||
raise Exception
|
||||
finally:
|
||||
session.close()
|
||||
|
|
|
@ -54,6 +54,7 @@ async def invite_members(member_invitation: GroupChatMembers):
|
|||
@router.get("/member_name_avatar", response_model=MemberNameAvatarResponse)
|
||||
async def get_member_name_avatar(group_chat_id: str, member_id: str, is_friend: bool):
|
||||
res = await group_chat_crud.select_member_name_avatar(member_id, is_friend)
|
||||
print(res)
|
||||
data = {}
|
||||
if is_friend:
|
||||
if res.get(group_chat_id):
|
||||
|
@ -66,7 +67,7 @@ async def get_member_name_avatar(group_chat_id: str, member_id: str, is_friend:
|
|||
# make sure this user is still in this group chat
|
||||
data["remark"] = res[2][group_chat_id]["myRemark"]
|
||||
data["nickname"] = res[0]
|
||||
data["avatar"] = res[1]
|
||||
data["avatar"] = res[1] or ""
|
||||
|
||||
return {
|
||||
"code": 10800,
|
||||
|
@ -149,3 +150,13 @@ async def delete_group_chat(deletion: GroupChatMembers):
|
|||
except Exception as e:
|
||||
print(f"Delete Group Chat Fail With Error: {e}")
|
||||
return {"code": 9999, "msg": "Server Error"}
|
||||
|
||||
|
||||
@router.post("/quit", response_model=BaseResponseModel)
|
||||
async def quit_group_chat(group_chat_id: str, member_id: str):
|
||||
try:
|
||||
await group_chat_crud.delete_group_chat_member(group_chat_id, member_id)
|
||||
return {"code": 10800, "msg": "Quit Group Chat Successfully"}
|
||||
except Exception as e:
|
||||
print(f"Quit Group Chat Fail With Error: {e}")
|
||||
return {"code": 9999, "msg": "Server Error"}
|
||||
|
|
|
@ -6,7 +6,7 @@ from ..utils import password
|
|||
from ..utils.email_code import send_email, has_code, verify_code
|
||||
from ..response_models.base import BaseResponseModel
|
||||
|
||||
router = APIRouter(prefix='/user_account', tags=['user_account'])
|
||||
router = APIRouter(prefix="/user_account", tags=["user_account"])
|
||||
|
||||
|
||||
class ChangedAccount(BaseModel):
|
||||
|
@ -17,58 +17,71 @@ class ChangedAccount(BaseModel):
|
|||
code: str | None = None
|
||||
|
||||
|
||||
@router.post('/change/username', response_model=BaseResponseModel)
|
||||
@router.post("/change/username", response_model=BaseResponseModel)
|
||||
async def change_username(changed_account: ChangedAccount):
|
||||
is_existed, user = await user_crud.select_account_by('username', changed_account.username)
|
||||
is_existed, user = await user_crud.select_account_by(
|
||||
"username", changed_account.username
|
||||
)
|
||||
if is_existed:
|
||||
return {'code': 10401, 'msg': f'This Username ({changed_account.username}) Has Been Used'}
|
||||
return {
|
||||
"code": 10401,
|
||||
"msg": f"This Username ({changed_account.username}) Has Been Used",
|
||||
}
|
||||
|
||||
await user_crud.update_account('username', changed_account.id, changed_account.username)
|
||||
await user_crud.update_account(
|
||||
"username", changed_account.id, changed_account.username
|
||||
)
|
||||
|
||||
return {'code': 10400, 'msg': 'Update Username Successfully'}
|
||||
return {"code": 10400, "msg": "Update Username Successfully"}
|
||||
|
||||
|
||||
@router.get('/get/email_code', response_model=BaseResponseModel)
|
||||
@router.get("/get/email_code", response_model=BaseResponseModel)
|
||||
async def get_change_email_code(email: str, background_tasks: BackgroundTasks):
|
||||
is_existed, _ = await user_crud.select_account_by('email', email)
|
||||
is_existed, _ = await user_crud.select_account_by("email", email)
|
||||
if is_existed:
|
||||
return {'code': 10401, 'msg': f'This Email ({email}) Has Been Used'}
|
||||
return {"code": 10401, "msg": f"This Email ({email}) Has Been Used"}
|
||||
|
||||
if has_code(email):
|
||||
return {'code': 10402, 'msg': f'Code of Email ({email}) Is Still Available'}
|
||||
return {"code": 10402, "msg": f"Code of Email ({email}) Is Still Available"}
|
||||
|
||||
background_tasks.add_task(send_email, email)
|
||||
return {'code': 10400, 'msg': 'Send Verification Code Successfully'}
|
||||
return {"code": 10400, "msg": "Send Verification Code Successfully"}
|
||||
|
||||
|
||||
@router.post('/change/email', response_model=BaseResponseModel)
|
||||
@router.post("/change/email", response_model=BaseResponseModel)
|
||||
async def change_email(changed_account: ChangedAccount):
|
||||
is_correct = verify_code(changed_account.email, changed_account.code)
|
||||
if not is_correct:
|
||||
return {'code': 10403, 'msg': f'Email Code ({changed_account.code}) Is Not Correct'}
|
||||
return {
|
||||
"code": 10403,
|
||||
"msg": f"Email Code ({changed_account.code}) Is Not Correct",
|
||||
}
|
||||
|
||||
await user_crud.update_account('email', changed_account.id, changed_account.email)
|
||||
await user_crud.update_account("email", changed_account.id, changed_account.email)
|
||||
|
||||
return {'code': 10400, 'msg': 'Update Email Successfully'}
|
||||
return {"code": 10400, "msg": "Update Email Successfully"}
|
||||
|
||||
|
||||
@router.get('/get/password_code', response_model=BaseResponseModel)
|
||||
@router.get("/get/password_code", response_model=BaseResponseModel)
|
||||
async def get_change_password_code(email: str, background_tasks: BackgroundTasks):
|
||||
if has_code(email):
|
||||
return {'code': 10402, 'msg': f'Code of Email ({email}) Is Still Available'}
|
||||
return {"code": 10402, "msg": f"Code of Email ({email}) Is Still Available"}
|
||||
|
||||
background_tasks.add_task(send_email, email)
|
||||
return {'code': 10400, 'msg': 'Send Verification Code Successfully'}
|
||||
return {"code": 10400, "msg": "Send Verification Code Successfully"}
|
||||
|
||||
|
||||
@router.post('/change/password', response_model=BaseResponseModel)
|
||||
@router.post("/change/password", response_model=BaseResponseModel)
|
||||
async def change_password(changed_account: ChangedAccount):
|
||||
is_correct = verify_code(changed_account.email, changed_account.code)
|
||||
if not is_correct:
|
||||
return {'code': 10403, 'msg': f'Email Code ({changed_account.code}) Is Not Correct'}
|
||||
return {
|
||||
"code": 10403,
|
||||
"msg": f"Email Code ({changed_account.code}) Is Not Correct",
|
||||
}
|
||||
|
||||
hashed_password = password.get_hashed_password(changed_account.password)
|
||||
|
||||
await user_crud.update_account('password', changed_account.id, hashed_password)
|
||||
await user_crud.update_account("password", changed_account.id, hashed_password)
|
||||
|
||||
return {'code': 10400, 'msg': 'Update Email Successfully'}
|
||||
return {"code": 10400, "msg": "Update Email Successfully"}
|
||||
|
|
|
@ -48,13 +48,13 @@ async def get_profile(id: str):
|
|||
|
||||
@router.get("/avatar")
|
||||
async def download_avatar(avatar_filename: str):
|
||||
avatar_dir_path = static_file.create_dir("avatars")
|
||||
return FileResponse(avatar_dir_path / avatar_filename)
|
||||
user_avatar_dir_path = static_file.create_avatar_dir("user", "avatars")
|
||||
return FileResponse(user_avatar_dir_path / avatar_filename)
|
||||
|
||||
|
||||
@router.post("/change/avatar", response_model=UserAvatarResponse)
|
||||
async def change_avatar(id: str, file: Uint8List):
|
||||
avatar_dir_path = static_file.create_dir("avatars")
|
||||
avatar_dir_path = static_file.create_avatar_dir("user", "avatars")
|
||||
avatar_filename = static_file.create_avatar_filename()
|
||||
|
||||
async with await open_file(avatar_dir_path / avatar_filename, "wb") as f:
|
||||
|
|
|
@ -29,7 +29,7 @@ def send_email(to: str):
|
|||
msg = EmailMessage()
|
||||
connect_email_server()
|
||||
msg["Subject"] = "Together app signup verification code"
|
||||
msg["From"] = "TogetherApp <together_app@outlook.com>"
|
||||
msg["From"] = f"TogetherApp <{username}>"
|
||||
msg["To"] = f"<{to}>"
|
||||
|
||||
email_content = f"""\
|
||||
|
|
|
@ -35,8 +35,14 @@ alphabet = [
|
|||
]
|
||||
|
||||
|
||||
def create_dir(dir_name: str) -> Path:
|
||||
avatar_dir_path = Path(os.getcwd()) / "static" / dir_name
|
||||
def create_avatar_dir(type: Literal["user", "group_chat"], dir_name: str) -> Path:
|
||||
if type == "user":
|
||||
avatar_dir_path = Path(os.getcwd()) / "static" / dir_name / "user"
|
||||
if not avatar_dir_path.exists():
|
||||
avatar_dir_path.mkdir()
|
||||
return avatar_dir_path
|
||||
else:
|
||||
avatar_dir_path = Path(os.getcwd()) / "static" / dir_name / "group_chat"
|
||||
if not avatar_dir_path.exists():
|
||||
avatar_dir_path.mkdir()
|
||||
return avatar_dir_path
|
||||
|
|
|
@ -6,10 +6,10 @@ from fastapi.security import OAuth2PasswordBearer
|
|||
from jose import jwt, ExpiredSignatureError, JWTError
|
||||
|
||||
# openssl rand -hex 32
|
||||
SECRET_KEY = '1c3c03b79d084f0c7b41ba11d1d9a4979f72d9fc6eaaaa0a855065e8a5be0468'
|
||||
ALGORITHM = 'HS256'
|
||||
SECRET_KEY = "1c3c03b79d084f0c7b41ba11d1d9a4979f72d9fc6eaaaa0a855065e8a5be0468"
|
||||
ALGORITHM = "HS256"
|
||||
|
||||
oauth2_scheme = OAuth2PasswordBearer(tokenUrl='token')
|
||||
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
|
||||
|
||||
|
||||
class SigninClaim(TypedDict):
|
||||
|
@ -22,33 +22,34 @@ class SigninClaim(TypedDict):
|
|||
|
||||
def create_signin_token(id: str, device_id: str) -> str:
|
||||
claim: SigninClaim = {
|
||||
'sub': id,
|
||||
'iss': 'together',
|
||||
'iat': datetime.now().timestamp(),
|
||||
'exp': (datetime.now() + timedelta(days=23)).timestamp(),
|
||||
'device_id': device_id,
|
||||
"sub": id,
|
||||
"iss": "together",
|
||||
"iat": datetime.now().timestamp(),
|
||||
"exp": (datetime.now() + timedelta(days=23)).timestamp(),
|
||||
"device_id": device_id,
|
||||
}
|
||||
return jwt.encode(claim, SECRET_KEY, algorithm=ALGORITHM)
|
||||
|
||||
|
||||
def verify_signin_token(token) -> Tuple[str | None, str]:
|
||||
def verify_signin_token(token: str) -> Tuple[str | None, str]:
|
||||
try:
|
||||
claim: SigninClaim = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
|
||||
if claim['exp'] - datetime.now().timestamp() <= 10*24*60*60:
|
||||
new_token = _prolong_token(token)
|
||||
return new_token, claim['sub']
|
||||
print(claim["sub"])
|
||||
if claim["exp"] - datetime.now().timestamp() <= 10 * 24 * 60 * 60:
|
||||
new_token = _prolong_token(claim)
|
||||
return new_token, claim["sub"]
|
||||
else:
|
||||
return None, claim['sub']
|
||||
return None, claim["sub"]
|
||||
except ExpiredSignatureError:
|
||||
print(f'{token} expire ========================')
|
||||
print(f"{token} expire ========================")
|
||||
raise ExpiredSignatureError
|
||||
except JWTError:
|
||||
print(f'This token {token} is not sign by me ==========================')
|
||||
print(f"This token {token} is not sign by me ==========================")
|
||||
raise JWTError
|
||||
|
||||
|
||||
def _prolong_token(claim: SigninClaim) -> str:
|
||||
claim['iat'] = datetime.now().timestamp()
|
||||
claim['exp'] = (datetime.now() + timedelta(days=30)).timestamp()
|
||||
claim["iat"] = datetime.now().timestamp()
|
||||
claim["exp"] = (datetime.now() + timedelta(days=30)).timestamp()
|
||||
token = jwt.encode(claim, SECRET_KEY, algorithm=ALGORITHM)
|
||||
return token
|
||||
|
|
Loading…
Reference in New Issue