|
|
|
from flask import request, current_app
|
|
from flask_restful import Resource
|
|
from flask_jwt_extended import jwt_required, get_jwt_identity
|
|
from datetime import datetime, timedelta
|
|
from app import db
|
|
from app.models import Customer, SendCode
|
|
from app.utils.security import hash_password, verify_password
|
|
from app.utils.response import APIResponse
|
|
from app.utils.mail_service import EmailService
|
|
from app.utils.validators import (
|
|
validate_verification_code,
|
|
validate_password_confirmation,
|
|
validate_password_complexity
|
|
)
|
|
import random
|
|
|
|
|
|
class ChangePasswordResource(Resource):
|
|
@jwt_required()
|
|
def post(self):
|
|
"""修改密码(旧密码验证)[^1]"""
|
|
user_id = get_jwt_identity()
|
|
data = request.json
|
|
|
|
|
|
required_fields = ['oldpwd', 'newpwd', 'newpwd_confirmation']
|
|
if not all(field in data for field in required_fields):
|
|
return APIResponse.error('缺少必要参数', 400)
|
|
|
|
|
|
is_valid, msg = validate_password_confirmation({
|
|
'password': data['newpwd'],
|
|
'password_confirmation': data['newpwd_confirmation']
|
|
})
|
|
if not is_valid:
|
|
return APIResponse.error(msg, 400)
|
|
|
|
|
|
is_valid, msg = validate_password_complexity(data['newpwd'])
|
|
if not is_valid:
|
|
return APIResponse.error(msg, 422)
|
|
|
|
customer = Customer.query.get(user_id)
|
|
if not verify_password(customer.password, data['oldpwd']):
|
|
return APIResponse.error('旧密码不正确', 401)
|
|
|
|
customer.password = hash_password(data['newpwd'])
|
|
customer.updated_at = datetime.utcnow()
|
|
db.session.commit()
|
|
return APIResponse.success(message='密码修改成功')
|
|
|
|
|
|
class SendChangeCodeResource(Resource):
|
|
@jwt_required()
|
|
def post(self):
|
|
"""发送修改密码验证码[^2]"""
|
|
user_id = get_jwt_identity()
|
|
customer = Customer.query.get(user_id)
|
|
|
|
code = ''.join(random.choices('0123456789', k=6))
|
|
send_code = SendCode(
|
|
send_type=3,
|
|
send_to=customer.email,
|
|
code=code,
|
|
created_at=datetime.utcnow()
|
|
)
|
|
db.session.add(send_code)
|
|
try:
|
|
EmailService.send_verification_code(customer.email, code)
|
|
db.session.commit()
|
|
return APIResponse.success(message='验证码已发送')
|
|
except Exception as e:
|
|
db.session.rollback()
|
|
return APIResponse.error('邮件发送失败', 500)
|
|
|
|
|
|
class EmailChangePasswordResource(Resource):
|
|
@jwt_required()
|
|
def post(self):
|
|
"""通过邮箱验证码修改密码[^3]"""
|
|
user_id = get_jwt_identity()
|
|
data = request.json
|
|
|
|
|
|
required_fields = ['code', 'newpwd', 'newpwd_confirmation']
|
|
if not all(field in data for field in required_fields):
|
|
return APIResponse.error('缺少必要参数', 400)
|
|
|
|
|
|
is_valid, msg = validate_password_confirmation({
|
|
'password': data['newpwd'],
|
|
'password_confirmation': data['newpwd_confirmation']
|
|
})
|
|
if not is_valid:
|
|
return APIResponse.error(msg, 400)
|
|
|
|
|
|
customer = Customer.query.get(user_id)
|
|
is_valid, msg = validate_verification_code(
|
|
customer.email, data['code'], 3
|
|
)
|
|
if not is_valid:
|
|
return APIResponse.error(msg, 400)
|
|
|
|
|
|
customer.password = hash_password(data['newpwd'])
|
|
customer.updated_at = datetime.utcnow()
|
|
db.session.commit()
|
|
return APIResponse.success(message='密码修改成功')
|
|
|
|
|
|
class StorageInfoResource(Resource):
|
|
@jwt_required()
|
|
def get(self):
|
|
"""获取存储空间信息[^2]"""
|
|
user_id = get_jwt_identity()
|
|
customer = Customer.query.get(user_id)
|
|
|
|
total = current_app.config['MAX_USER_STORAGE'] / (1024 * 1024)
|
|
used = customer.storage / (1024 * 1024)
|
|
percentage = (used / total) * 100 if total > 0 else 0
|
|
|
|
return APIResponse.success({
|
|
'storage': f"{total:.2f}",
|
|
'used': f"{used:.2f}",
|
|
'percentage': f"{percentage:.1f}"
|
|
})
|
|
|
|
|
|
class UserInfoResource(Resource):
|
|
@jwt_required()
|
|
def get(self):
|
|
"""获取用户基本信息[^5]"""
|
|
user_id = get_jwt_identity()
|
|
customer = Customer.query.get(user_id)
|
|
|
|
return APIResponse.success({
|
|
'email': customer.email,
|
|
'level': customer.level,
|
|
'created_at': customer.created_at.isoformat(),
|
|
'storage': customer.storage
|
|
})
|
|
|