198 lines
6.8 KiB
Python
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)
|