Files
2024-09-27 17:49:37 +08:00

198 lines
6.8 KiB
Python

from flask import Flask, request, jsonify
import os
import pandas as pd
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding
import base64
import requests
from datetime import datetime
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
def get_csv_path():
return os.path.join(os.path.dirname(__file__), 'Authorize.csv')
def get_info_csv_path():
return os.path.join(os.path.dirname(__file__), 'Information.csv')
def get_public_key():
csv_path = get_csv_path()
if not os.path.exists(csv_path):
return None
df = pd.read_csv(csv_path)
if not df.empty:
return df['PublicKey'].iloc[0].encode('utf-8')
return None
def get_current_time():
response = requests.get('http://localhost:12235/current-time')
print(f"API 返回: {response.json()}")
if response.status_code == 200:
time_data = response.json()
return datetime(time_data['year'], time_data['month'], time_data['day'])
else:
raise Exception("请求时间失败")
@app.route('/check_time', methods=['POST'])
def check_time():
current_time = get_current_time()
csv_path = get_info_csv_path()
if not os.path.exists(csv_path):
return jsonify({"valid": False, "message": "信息文件不存在"}), 404
df = pd.read_csv(csv_path)
if df.empty:
return jsonify({"valid": False, "message": "信息文件为空"}), 404
start_time = datetime.strptime(df['StartTime'].iloc[0], '%Y-%m-%d')
end_time = datetime.strptime(df['EndTime'].iloc[0], '%Y-%m-%d')
time_range_message = f"有效时间范围: {start_time.strftime('%Y-%m-%d')}{end_time.strftime('%Y-%m-%d')}"
if start_time <= current_time <= end_time:
days_remaining = (end_time - current_time).days
return jsonify({
"valid": True,
"message": f"{time_range_message}",
"days_remaining": days_remaining
})
return jsonify({
"valid": False,
"message": f"{time_range_message}"
})
@app.route('/navigate', methods=['POST'])
def navigate():
current_time = get_current_time()
csv_path = get_info_csv_path()
if not os.path.exists(csv_path):
return jsonify({"valid": False, "message": "信息文件不存在"}), 404
df = pd.read_csv(csv_path)
if df.empty:
return jsonify({"valid": False, "message": "信息文件为空"}), 404
start_time = datetime.strptime(df['StartTime'].iloc[0], '%Y-%m-%d')
end_time = datetime.strptime(df['EndTime'].iloc[0], '%Y-%m-%d')
if start_time <= current_time <= end_time:
return jsonify({"valid": True, "redirect": "device"})
return jsonify({"valid": False, "redirect": "error"})
@app.route('/verify', methods=['POST', 'OPTIONS'])
def handle_verification():
if request.method == 'OPTIONS':
return jsonify({'message': 'Options request handled successfully'}), 200
data = request.get_json()
signature_data = data.get('signatureData', '')
print("Received signature data:", signature_data)
if not signature_data:
return jsonify({'error': '缺少授权码'}), 400
public_key_pem = get_public_key()
if public_key_pem is None:
return jsonify({'error': '无法加载公钥'}), 500
is_valid, message, time_range, current_time = verify_signature(public_key_pem, signature_data)
print("公钥:", public_key_pem)
print("验证结果:", is_valid)
print("从授权码获取的时间范围:", time_range)
print("当前时间:", current_time)
# Format current_time to "YYYY-MM-DD"
current_time_str = current_time.strftime('%Y-%m-%d') if current_time else None
# Save signature and timestamps to Information.csv if valid
if is_valid:
start_time, end_time = time_range
save_to_information_csv(signature_data, start_time, end_time)
return jsonify({
"valid": is_valid,
"message": message["time_range"],
"current_time": current_time_str,
"signatureData": signature_data
})
def verify_signature(public_key_pem, signature_data):
try:
public_key = serialization.load_pem_public_key(public_key_pem)
parts = signature_data.split('&&')
if len(parts) != 3:
print("授权码错误:", parts)
return False, {"valid": False, "time_range": "授权码格式错误"}, None, None
start_timestamp_base64, end_timestamp_base64, signature_base64 = parts
# 解码签名部分
signature_bytes = base64.b64decode(signature_base64)
# 解码时间戳部分
start_timestamp_bytes = base64.b64decode(start_timestamp_base64)
end_timestamp_bytes = base64.b64decode(end_timestamp_base64)
# 解析时间戳
start_timestamp_str = start_timestamp_bytes.decode('utf-8').strip()
end_timestamp_str = end_timestamp_bytes.decode('utf-8').strip()
# 重新构建原始消息(只包括时间戳)
original_message = f"{start_timestamp_str}{end_timestamp_str}".encode('utf-8')
# 验证签名
public_key.verify(
signature_bytes,
original_message,
padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH),
hashes.SHA256()
)
# 当前时间
current_time = get_current_time()
# 时间比较
start_time = datetime.strptime(start_timestamp_str, '%Y-%m-%d')
end_time = datetime.strptime(end_timestamp_str, '%Y-%m-%d')
if start_time <= current_time <= end_time:
return True, {"valid": True, "time_range": f"成功。时间范围: {start_time.year}-{start_time.month}-{start_time.day}{end_time.year}-{end_time.month}-{end_time.day}"}, (start_time, end_time), current_time
else:
return False, {"valid": False, "time_range": f"时间不在有效范围内。时间范围: {start_time.year}-{start_time.month}-{start_time.day}{end_time.year}-{end_time.month}-{end_time.day}"}, (start_time, end_time), current_time
except Exception as e:
print("发生错误:", str(e))
return False, {"valid": False, "time_range": f"请输入正确的授权码"}, None, None
def save_to_information_csv(signature_data, start_time, end_time):
csv_path = get_info_csv_path()
# 创建DataFrame
data = {
'SignatureData': [signature_data],
'StartTime': [start_time.strftime('%Y-%m-%d')],
'EndTime': [end_time.strftime('%Y-%m-%d')]
}
# 如果文件存在,先读取数据
if os.path.exists(csv_path):
existing_df = pd.read_csv(csv_path)
# 清空文件内容
existing_df.to_csv(csv_path, index=False, header=False)
# 将新的数据写入CSV文件
df = pd.DataFrame(data)
df.to_csv(csv_path, index=False)
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5001)