Skip to content

Commit e52d590

Browse files
committed
refactor(cloud): add middleware
1 parent c62e90d commit e52d590

File tree

5 files changed

+117
-42
lines changed

5 files changed

+117
-42
lines changed

cloud/middleware.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# 创建中间件,进行鉴权
2+
import json
3+
from datetime import datetime
4+
from hashlib import md5
5+
6+
from django.utils import timezone
7+
from rest_framework import status
8+
9+
from cloud_disk_backend import global_function
10+
11+
from cloud import models as cloud_models
12+
13+
14+
# md5加密
15+
def to_md5(string_name):
16+
md5_object = md5()
17+
md5_object.update(string_name.encode(encoding='utf-8'))
18+
return md5_object.hexdigest()
19+
20+
21+
# 验证请求头中token是否有效
22+
def check_token(request):
23+
token = request.META.get('HTTP_AMOS_CLOUD_TOKEN')
24+
# 验证token时同时对md5加密后的用户名和数据库中token对应的用户名匹配检查
25+
username_md5 = request.META.get('HTTP_AMOS_CLOUD_USER')
26+
if cloud_models.Token.objects.filter(token=token).exists():
27+
token_queryset = cloud_models.Token.objects.get(token=token)
28+
if to_md5(token_queryset.username) == username_md5:
29+
# 计算时间差
30+
current_time = timezone.now().strftime("%Y-%m-%d %H:%M:%S")
31+
current_time = datetime.strptime(current_time, "%Y-%m-%d %H:%M:%S")
32+
token_start_time = datetime.strptime(token_queryset.start_time, "%Y-%m-%d %H:%M:%S")
33+
time_difference = (current_time - token_start_time).total_seconds() / 3600
34+
# 时间差大于7*24着返回false并删除该token
35+
if time_difference > 7 * 24:
36+
cloud_models.Token.objects.filter(token=token).delete()
37+
return False
38+
# token通过则返回用户名
39+
return token_queryset.username
40+
else:
41+
return False
42+
else:
43+
return False
44+
45+
46+
def preprocess_request(request):
47+
# 在这里对请求执行操作
48+
data = json.loads(request.body)
49+
check_result = check_token(request)
50+
if check_result:
51+
print(data)
52+
else:
53+
return global_function.json_response('', 'token已过期或不存在,请重新登陆', status.HTTP_401_UNAUTHORIZED)
54+
55+
56+
class CustomMiddleware:
57+
def __init__(self, get_response):
58+
self.get_response = get_response
59+
60+
def __call__(self, request):
61+
# 在视图处理请求之前执行操作
62+
data = json.loads(request.body)
63+
check_result = check_token(request)
64+
if check_result:
65+
# 调用视图(处理请求)
66+
response = self.get_response(data)
67+
# 如果需要,也可以在此处对响应进行处理
68+
return response
69+
else:
70+
return global_function.json_response('', 'token已过期或不存在,请重新登陆', status.HTTP_401_UNAUTHORIZED)

cloud/upload_views.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ def new_folder(request):
2222
current_path = data.get('current_path')
2323
# 查看文件夹是否存在
2424
folder_path = settings.MEDIA_ROOT + '/' + check_result + current_path + folder_name
25+
print(folder_path)
2526
if not os.path.exists(folder_path):
2627
os.makedirs(folder_path)
2728
else:
@@ -109,15 +110,18 @@ def get_filelist(request):
109110
file_info = {
110111
'type': '',
111112
'name': file_name,
112-
'size': str(round(os.path.getsize(file_path) / 1024, 1)) + ' kb',
113+
'size': '',
113114
'last_modified': time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(os.path.getmtime(file_path)))
114115
}
115116
file_info_list.append(file_info)
116117
# 判断是否是文件
117118
if os.path.isfile(file_path):
118-
file_info['type'] = 'file'
119+
file_info['type'] = '文件'
120+
file_info['size'] = global_function.convert_bytes(round(os.path.getsize(file_path), 1))
119121
elif os.path.isdir(file_path):
120-
file_info['type'] = 'folder'
122+
file_info['type'] = '文件夹'
123+
total_size_bytes = global_function.get_folder_size(file_path)
124+
file_info['size'] = global_function.convert_bytes(total_size_bytes)
121125
else:
122126
return global_function.json_response('', '未知类型', status.HTTP_400_BAD_REQUEST)
123127
return global_function.json_response(file_info_list, '获取文件列表成功', status.HTTP_200_OK)
@@ -134,6 +138,7 @@ def download(request):
134138
else:
135139
file_path = settings.MEDIA_ROOT + '/' + check_result + request.GET.get('current_path') + request.GET.get(
136140
'file_name')
141+
print(file_path)
137142
# 判断当前路径是否最后一位是否为/,是的话去除
138143
if file_path[-1:] == '/':
139144
file_path = file_path[:-1]
@@ -161,14 +166,15 @@ def download(request):
161166
# 删除文件或文件夹
162167
def delete(request):
163168
params = json.loads(request.body)
164-
current_path = params.get('current_path')
165-
file_name = params.get('file_name')
169+
current_path = params['current_path']
170+
file_name = params['file_name']
166171
check_result = global_function.check_token(request)
167172
if check_result:
168173
if current_path == '/':
169174
file_path = settings.MEDIA_ROOT + '/' + check_result + file_name
170175
else:
171176
file_path = settings.MEDIA_ROOT + '/' + check_result + current_path + file_name
177+
172178
# 判断当前路径是否最后一位是否为/,是的话去除
173179
if file_path[-1:] == '/':
174180
file_path = file_path[:-1]
@@ -193,7 +199,7 @@ def delete(request):
193199

194200
def delete_recycle(request):
195201
params = json.loads(request.body)
196-
file_name = '/recycle' + params.get('file_name')
202+
file_name = '/recycle' + params['file_name']
197203
check_result = global_function.check_token(request)
198204
if check_result:
199205
file_path = settings.MEDIA_ROOT + '/' + check_result + file_name
@@ -212,6 +218,7 @@ def delete_recycle(request):
212218
if os.path.isdir(file_path):
213219
shutil.rmtree(file_path, ignore_errors=False, onerror=None)
214220
elif os.path.isfile(file_path):
221+
215222
os.remove(file_path)
216223
else:
217224
return global_function.json_response('', '未知类型无法删除', status.HTTP_400_BAD_REQUEST)

cloud_disk_backend/global_function.py

Lines changed: 30 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1+
import math
12
import os
23
import random
34
import re
45
import string
56
import zipfile
6-
from datetime import datetime
77

88
from django.template import loader
99
from django.utils import timezone
@@ -12,13 +12,11 @@
1212
from django.http import JsonResponse
1313
from cloud_disk_backend import settings
1414

15-
from hashlib import md5
16-
from cloud import models as cloud_models
17-
1815

1916
# 返回值全局定义
2017
def json_response(data, msg, http_status):
2118
res = {
19+
'status': http_status,
2220
'data': data,
2321
'message': msg
2422
}
@@ -49,13 +47,6 @@ def validate_personal_info(username, password, email):
4947
return True, 'success'
5048

5149

52-
# md5加密
53-
def to_md5(string_name):
54-
md5_object = md5()
55-
md5_object.update(string_name.encode(encoding='utf-8'))
56-
return md5_object.hexdigest()
57-
58-
5950
# 发送邮件
6051
def send_email(receive_list, title, content):
6152
# 此处的content可以为一段html字符串
@@ -88,31 +79,6 @@ def send_verify_code_email(receive_list, username, request):
8879
return True
8980

9081

91-
# 验证请求头中token是否有效
92-
def check_token(request):
93-
token = request.META.get('HTTP_AMOS_CLOUD_TOKEN')
94-
# 验证token时同时对md5加密后的用户名和数据库中token对应的用户名匹配检查
95-
username_md5 = request.META.get('HTTP_AMOS_CLOUD_USER')
96-
if cloud_models.Token.objects.filter(token=token).exists():
97-
token_queryset = cloud_models.Token.objects.get(token=token)
98-
if to_md5(token_queryset.username) == username_md5:
99-
# 计算时间差
100-
current_time = timezone.now().strftime("%Y-%m-%d %H:%M:%S")
101-
current_time = datetime.strptime(current_time, "%Y-%m-%d %H:%M:%S")
102-
token_start_time = datetime.strptime(token_queryset.start_time, "%Y-%m-%d %H:%M:%S")
103-
time_difference = (current_time - token_start_time).total_seconds() / 3600
104-
# 时间差大于7*24着返回false并删除该token
105-
if time_difference > 7 * 24:
106-
cloud_models.Token.objects.filter(token=token).delete()
107-
return False
108-
# token通过则返回用户名
109-
return token_queryset.username
110-
else:
111-
return False
112-
else:
113-
return False
114-
115-
11682
# 将文件夹压缩为zip
11783
# directory 是要压缩的文件夹的路径,zip_filename 是要创建的 ZIP 文件的路径和名称。
11884
# 函数内部使用 os.walk 来遍历文件夹中的文件和子文件夹,
@@ -132,3 +98,31 @@ def unzip(zip_file, extract_to):
13298
with zipfile.ZipFile(zip_file, 'r') as zip_ref:
13399
zip_ref.extractall(extract_to)
134100
return True
101+
102+
103+
# 获取文件夹总大小
104+
def get_folder_size(folder_path):
105+
total_size = 0
106+
for dirpath, dirnames, filenames in os.walk(folder_path):
107+
for filename in filenames:
108+
filepath = os.path.join(dirpath, filename)
109+
total_size += os.path.getsize(filepath)
110+
return total_size
111+
112+
113+
# 转换为更容易理解的单位
114+
def convert_bytes(size_bytes):
115+
if size_bytes == 0:
116+
return "0B"
117+
size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
118+
i = int(math.floor(math.log(size_bytes, 1024)))
119+
p = math.pow(1024, i)
120+
s = round(size_bytes / p, 1)
121+
return "%s %s" % (s, size_name[i])
122+
123+
# 校验文件或文件夹名称是否合法
124+
def is_valid_filename(filename):
125+
# 定义正则表达式:只允许字母、数字、下划线、连字符,且不能以空格开头或结尾
126+
# 不允许的字符包括:\/:*?"<>|(这些在Windows文件系统中是非法的字符)
127+
pattern = r'^[^\\/:*?"<>|]+[^\\/:*?"<>|\s]$'
128+
return bool(re.match(pattern, filename))

cloud_disk_backend/settings.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
'django.contrib.auth.middleware.AuthenticationMiddleware',
3737
'django.contrib.messages.middleware.MessageMiddleware',
3838
'django.middleware.clickjacking.XFrameOptionsMiddleware',
39+
40+
# 自定义中间件
41+
'cloud.middleware.CustomMiddleware'
3942
]
4043

4144
ROOT_URLCONF = 'cloud_disk_backend.urls'

manage.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import sys
55

66
from cloud_disk_backend import settings
7+
from cloud_disk_backend.settings import MEDIA_ROOT
78

89

910
def main():

0 commit comments

Comments
 (0)