mdbq 4.0.103__py3-none-any.whl → 4.0.104__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of mdbq might be problematic. Click here for more details.
- mdbq/__version__.py +1 -1
- mdbq/auth/auth_backend.py +25 -25
- {mdbq-4.0.103.dist-info → mdbq-4.0.104.dist-info}/METADATA +1 -1
- {mdbq-4.0.103.dist-info → mdbq-4.0.104.dist-info}/RECORD +6 -6
- {mdbq-4.0.103.dist-info → mdbq-4.0.104.dist-info}/WHEEL +0 -0
- {mdbq-4.0.103.dist-info → mdbq-4.0.104.dist-info}/top_level.txt +0 -0
mdbq/__version__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
VERSION = '4.0.
|
|
1
|
+
VERSION = '4.0.104'
|
mdbq/auth/auth_backend.py
CHANGED
|
@@ -147,8 +147,8 @@ class StandaloneAuthManager:
|
|
|
147
147
|
ping=1,
|
|
148
148
|
charset='utf8mb4',
|
|
149
149
|
cursorclass=pymysql.cursors.DictCursor,
|
|
150
|
-
autocommit=True
|
|
151
|
-
|
|
150
|
+
autocommit=True # 启用自动提交,避免锁冲突
|
|
151
|
+
# 使用系统本地时区,不强制设置UTC
|
|
152
152
|
)
|
|
153
153
|
|
|
154
154
|
except Exception as e:
|
|
@@ -515,15 +515,15 @@ class StandaloneAuthManager:
|
|
|
515
515
|
}
|
|
516
516
|
|
|
517
517
|
# 检查账户锁定状态
|
|
518
|
-
|
|
518
|
+
current_time = datetime.now()
|
|
519
519
|
if locked_until:
|
|
520
520
|
if locked_until.tzinfo is None:
|
|
521
521
|
locked_until = locked_until.replace(tzinfo=timezone.utc)
|
|
522
522
|
elif locked_until.tzinfo != timezone.utc:
|
|
523
523
|
locked_until = locked_until.astimezone(timezone.utc)
|
|
524
524
|
|
|
525
|
-
if locked_until >
|
|
526
|
-
remaining_seconds = int((locked_until -
|
|
525
|
+
if locked_until > current_time:
|
|
526
|
+
remaining_seconds = int((locked_until - current_time).total_seconds())
|
|
527
527
|
self._log_login_attempt(username_or_email, ip_address, user_agent, 'failure', 'account_locked', user_id)
|
|
528
528
|
self._record_ip_failure(ip_address, 'login')
|
|
529
529
|
return {
|
|
@@ -540,7 +540,7 @@ class StandaloneAuthManager:
|
|
|
540
540
|
|
|
541
541
|
if login_attempts >= self.auth_config['max_login_attempts']:
|
|
542
542
|
lockout_duration = self.auth_config['lockout_duration']
|
|
543
|
-
locked_until =
|
|
543
|
+
locked_until = current_time + timedelta(seconds=lockout_duration)
|
|
544
544
|
cursor.execute('''
|
|
545
545
|
UPDATE users SET login_attempts = %s, locked_until = %s WHERE id = %s
|
|
546
546
|
''', (login_attempts, locked_until, user_id))
|
|
@@ -573,7 +573,7 @@ class StandaloneAuthManager:
|
|
|
573
573
|
# 登录成功,重置尝试次数
|
|
574
574
|
cursor.execute('''
|
|
575
575
|
UPDATE users SET login_attempts = 0, locked_until = NULL, last_login = %s WHERE id = %s
|
|
576
|
-
''', (
|
|
576
|
+
''', (current_time, user_id))
|
|
577
577
|
|
|
578
578
|
# 记录成功登录
|
|
579
579
|
self._log_login_attempt(username_or_email, ip_address, user_agent, 'success', None, user_id)
|
|
@@ -586,7 +586,7 @@ class StandaloneAuthManager:
|
|
|
586
586
|
'email': email,
|
|
587
587
|
'role': role,
|
|
588
588
|
'permissions': self._safe_json_parse(permissions),
|
|
589
|
-
'last_login':
|
|
589
|
+
'last_login': current_time.isoformat()
|
|
590
590
|
}
|
|
591
591
|
|
|
592
592
|
finally:
|
|
@@ -595,16 +595,16 @@ class StandaloneAuthManager:
|
|
|
595
595
|
|
|
596
596
|
def generate_access_token(self, user_info):
|
|
597
597
|
"""生成访问令牌"""
|
|
598
|
-
|
|
599
|
-
|
|
598
|
+
now = datetime.now()
|
|
599
|
+
exp = now + timedelta(seconds=self.auth_config['access_token_expires'])
|
|
600
600
|
|
|
601
601
|
payload = {
|
|
602
602
|
'user_id': user_info['user_id'],
|
|
603
603
|
'username': user_info['username'],
|
|
604
604
|
'role': user_info['role'],
|
|
605
605
|
'permissions': user_info['permissions'],
|
|
606
|
-
'iat': int(
|
|
607
|
-
'exp': int(
|
|
606
|
+
'iat': int(now.timestamp()),
|
|
607
|
+
'exp': int(exp.timestamp()),
|
|
608
608
|
'type': 'access'
|
|
609
609
|
}
|
|
610
610
|
|
|
@@ -646,7 +646,7 @@ class StandaloneAuthManager:
|
|
|
646
646
|
cursor = conn.cursor()
|
|
647
647
|
|
|
648
648
|
try:
|
|
649
|
-
|
|
649
|
+
current_time = datetime.now()
|
|
650
650
|
|
|
651
651
|
# 软删除:将该用户在该域名下的相同设备指纹的所有活跃会话标记为非活跃
|
|
652
652
|
cursor.execute('''
|
|
@@ -702,7 +702,7 @@ class StandaloneAuthManager:
|
|
|
702
702
|
full_device_info.get('timezone_offset'),
|
|
703
703
|
full_device_info.get('language'),
|
|
704
704
|
full_device_info.get('hardware_concurrency'),
|
|
705
|
-
ip_address, ip_address, user_agent,
|
|
705
|
+
ip_address, ip_address, user_agent, current_time))
|
|
706
706
|
|
|
707
707
|
device_session_id = cursor.lastrowid
|
|
708
708
|
|
|
@@ -716,9 +716,9 @@ class StandaloneAuthManager:
|
|
|
716
716
|
"""生成刷新令牌"""
|
|
717
717
|
token = secrets.token_urlsafe(64)
|
|
718
718
|
token_hash = hashlib.sha256(token.encode()).hexdigest()
|
|
719
|
-
|
|
720
|
-
expires_at =
|
|
721
|
-
absolute_expires_at =
|
|
719
|
+
current_time = datetime.now()
|
|
720
|
+
expires_at = current_time + timedelta(seconds=self.auth_config['refresh_token_expires'])
|
|
721
|
+
absolute_expires_at = current_time + timedelta(days=self.auth_config['absolute_refresh_expires_days'])
|
|
722
722
|
|
|
723
723
|
conn = self.pool.connection()
|
|
724
724
|
cursor = conn.cursor()
|
|
@@ -737,7 +737,7 @@ class StandaloneAuthManager:
|
|
|
737
737
|
rotation_count, max_rotations, created_at
|
|
738
738
|
) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)
|
|
739
739
|
''', (token_hash, token, user_info['user_id'], device_session_id, expires_at,
|
|
740
|
-
absolute_expires_at, 0, self.auth_config['max_refresh_rotations'],
|
|
740
|
+
absolute_expires_at, 0, self.auth_config['max_refresh_rotations'], current_time))
|
|
741
741
|
|
|
742
742
|
return token
|
|
743
743
|
|
|
@@ -758,8 +758,7 @@ class StandaloneAuthManager:
|
|
|
758
758
|
|
|
759
759
|
try:
|
|
760
760
|
# 验证刷新令牌
|
|
761
|
-
|
|
762
|
-
current_time_naive = current_time_utc.replace(tzinfo=None)
|
|
761
|
+
current_time = datetime.now()
|
|
763
762
|
|
|
764
763
|
cursor.execute('''
|
|
765
764
|
SELECT rt.user_id, rt.device_session_id, rt.expires_at, rt.absolute_expires_at,
|
|
@@ -775,7 +774,7 @@ class StandaloneAuthManager:
|
|
|
775
774
|
AND rt.rotation_count < rt.max_rotations
|
|
776
775
|
AND rt.is_revoked = 0
|
|
777
776
|
AND ds.is_active = 1
|
|
778
|
-
''', (token_hash,
|
|
777
|
+
''', (token_hash, current_time, current_time))
|
|
779
778
|
|
|
780
779
|
result = cursor.fetchone()
|
|
781
780
|
|
|
@@ -787,7 +786,7 @@ class StandaloneAuthManager:
|
|
|
787
786
|
UPDATE device_sessions
|
|
788
787
|
SET last_activity = %s
|
|
789
788
|
WHERE id = %s
|
|
790
|
-
''', (
|
|
789
|
+
''', (current_time, result['device_session_id']))
|
|
791
790
|
|
|
792
791
|
# 生成新的tokens
|
|
793
792
|
user_info = {
|
|
@@ -803,7 +802,7 @@ class StandaloneAuthManager:
|
|
|
803
802
|
# 生成新的refresh token(轮换)
|
|
804
803
|
new_token = secrets.token_urlsafe(64)
|
|
805
804
|
new_token_hash = hashlib.sha256(new_token.encode()).hexdigest()
|
|
806
|
-
token_expires_at =
|
|
805
|
+
token_expires_at = current_time + timedelta(seconds=self.auth_config['refresh_token_expires'])
|
|
807
806
|
|
|
808
807
|
# 删除旧token并插入新token
|
|
809
808
|
cursor.execute('''
|
|
@@ -818,7 +817,7 @@ class StandaloneAuthManager:
|
|
|
818
817
|
) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)
|
|
819
818
|
''', (new_token_hash, new_token, result['user_id'], result['device_session_id'],
|
|
820
819
|
token_expires_at, result['absolute_expires_at'],
|
|
821
|
-
result['rotation_count'] + 1, result['max_rotations'],
|
|
820
|
+
result['rotation_count'] + 1, result['max_rotations'], current_time))
|
|
822
821
|
|
|
823
822
|
return {
|
|
824
823
|
'access_token': access_token,
|
|
@@ -1013,7 +1012,7 @@ class StandaloneAuthManager:
|
|
|
1013
1012
|
|
|
1014
1013
|
# 生成重置令牌
|
|
1015
1014
|
reset_token = secrets.token_urlsafe(32)
|
|
1016
|
-
expires_at = datetime.now(
|
|
1015
|
+
expires_at = datetime.now() + timedelta(hours=1) # 1小时有效期
|
|
1017
1016
|
|
|
1018
1017
|
# 保存重置令牌
|
|
1019
1018
|
cursor.execute('''
|
|
@@ -1429,6 +1428,7 @@ class StandaloneAuthManager:
|
|
|
1429
1428
|
|
|
1430
1429
|
def logout_device(self, user_id, device_id=None, ip_address=None, user_agent=None, device_info=None, login_domain=''):
|
|
1431
1430
|
"""
|
|
1431
|
+
【已废弃】
|
|
1432
1432
|
登出设备(支持两种识别方式)
|
|
1433
1433
|
|
|
1434
1434
|
Args:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
mdbq/__init__.py,sha256=Il5Q9ATdX8yXqVxtP_nYqUhExzxPC_qk_WXQ_4h0exg,16
|
|
2
|
-
mdbq/__version__.py,sha256=
|
|
2
|
+
mdbq/__version__.py,sha256=kxyPyk2WXu3DvipWC0icSn0MFXbrNZr1qZab1hWurG8,19
|
|
3
3
|
mdbq/auth/__init__.py,sha256=pnPMAt63sh1B6kEvmutUuro46zVf2v2YDAG7q-jV_To,24
|
|
4
|
-
mdbq/auth/auth_backend.py,sha256=
|
|
4
|
+
mdbq/auth/auth_backend.py,sha256=P3kaQqnT1TdZEHMeR5_UDqGzlx1v-7BWdsD3Uu7YYzo,86787
|
|
5
5
|
mdbq/auth/rate_limiter.py,sha256=1m_Paxp8pDNpmyoFGRpFMVOJpbmeIvfVcfiQ2oH72qM,32850
|
|
6
6
|
mdbq/js/__init__.py,sha256=hpMi3_ZKwIWkzc0LnKL-SY9AS-7PYFHq0izYTgEvxjc,30
|
|
7
7
|
mdbq/js/jc.py,sha256=FOc6HOOTJwnoZLZmgmaE1SQo9rUnVhXmefhKMD2MlDA,13229
|
|
@@ -33,7 +33,7 @@ mdbq/route/routes.py,sha256=QVGfTvDgu0CpcKCvk1ra74H8uojgqTLUav1fnVAqLEA,29433
|
|
|
33
33
|
mdbq/selenium/__init__.py,sha256=AKzeEceqZyvqn2dEDoJSzDQnbuENkJSHAlbHAD0u0ZI,10
|
|
34
34
|
mdbq/selenium/get_driver.py,sha256=1NTlVUE6QsyjTrVVVqTO2LOnYf578ccFWlWnvIXGtic,20903
|
|
35
35
|
mdbq/spider/__init__.py,sha256=RBMFXGy_jd1HXZhngB2T2XTvJqki8P_Fr-pBcwijnew,18
|
|
36
|
-
mdbq-4.0.
|
|
37
|
-
mdbq-4.0.
|
|
38
|
-
mdbq-4.0.
|
|
39
|
-
mdbq-4.0.
|
|
36
|
+
mdbq-4.0.104.dist-info/METADATA,sha256=EwEeO0P8TpW-CyVkRnnxB1FNSswUPgLik7H1jV8P4po,365
|
|
37
|
+
mdbq-4.0.104.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
38
|
+
mdbq-4.0.104.dist-info/top_level.txt,sha256=2FQ-uLnCSB-OwFiWntzmwosW3X2Xqsg0ewh1axsaylA,5
|
|
39
|
+
mdbq-4.0.104.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|