mdbq 4.0.102__py3-none-any.whl → 4.0.103__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 +134 -0
- {mdbq-4.0.102.dist-info → mdbq-4.0.103.dist-info}/METADATA +1 -1
- {mdbq-4.0.102.dist-info → mdbq-4.0.103.dist-info}/RECORD +6 -6
- {mdbq-4.0.102.dist-info → mdbq-4.0.103.dist-info}/WHEEL +0 -0
- {mdbq-4.0.102.dist-info → mdbq-4.0.103.dist-info}/top_level.txt +0 -0
mdbq/__version__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
VERSION = '4.0.
|
|
1
|
+
VERSION = '4.0.103'
|
mdbq/auth/auth_backend.py
CHANGED
|
@@ -1522,6 +1522,140 @@ class StandaloneAuthManager:
|
|
|
1522
1522
|
cursor.close()
|
|
1523
1523
|
conn.close()
|
|
1524
1524
|
|
|
1525
|
+
def logout_current_device(self, user_id, access_token=None):
|
|
1526
|
+
"""
|
|
1527
|
+
退出当前设备(通过token识别)
|
|
1528
|
+
|
|
1529
|
+
Args:
|
|
1530
|
+
user_id: 用户ID
|
|
1531
|
+
access_token: 当前的访问令牌(用于识别设备会话)
|
|
1532
|
+
|
|
1533
|
+
Returns:
|
|
1534
|
+
dict: 登出结果
|
|
1535
|
+
"""
|
|
1536
|
+
conn = self.pool.connection()
|
|
1537
|
+
cursor = conn.cursor()
|
|
1538
|
+
|
|
1539
|
+
try:
|
|
1540
|
+
current_time_utc = datetime.now(timezone.utc)
|
|
1541
|
+
|
|
1542
|
+
if access_token:
|
|
1543
|
+
# 方式1:通过access_token解析出设备会话信息
|
|
1544
|
+
try:
|
|
1545
|
+
payload = self.verify_access_token(access_token)
|
|
1546
|
+
if not payload:
|
|
1547
|
+
return {'success': False, 'message': '无效的访问令牌'}
|
|
1548
|
+
|
|
1549
|
+
# 查找该用户最近活跃的设备(作为当前设备的近似)
|
|
1550
|
+
cursor.execute('''
|
|
1551
|
+
SELECT ds.id, ds.device_name, rt.id as token_id
|
|
1552
|
+
FROM device_sessions ds
|
|
1553
|
+
LEFT JOIN refresh_tokens rt ON ds.id = rt.device_session_id AND rt.is_revoked = 0
|
|
1554
|
+
WHERE ds.user_id = %s AND ds.is_active = 1
|
|
1555
|
+
ORDER BY ds.last_activity DESC
|
|
1556
|
+
LIMIT 1
|
|
1557
|
+
''', (user_id,))
|
|
1558
|
+
|
|
1559
|
+
except Exception:
|
|
1560
|
+
# token解析失败,使用备用方案
|
|
1561
|
+
cursor.execute('''
|
|
1562
|
+
SELECT id, device_name FROM device_sessions
|
|
1563
|
+
WHERE user_id = %s AND is_active = 1
|
|
1564
|
+
ORDER BY last_activity DESC
|
|
1565
|
+
LIMIT 1
|
|
1566
|
+
''', (user_id,))
|
|
1567
|
+
else:
|
|
1568
|
+
# 方式2:没有token时,登出最新活跃的设备
|
|
1569
|
+
cursor.execute('''
|
|
1570
|
+
SELECT id, device_name FROM device_sessions
|
|
1571
|
+
WHERE user_id = %s AND is_active = 1
|
|
1572
|
+
ORDER BY last_activity DESC
|
|
1573
|
+
LIMIT 1
|
|
1574
|
+
''', (user_id,))
|
|
1575
|
+
|
|
1576
|
+
device = cursor.fetchone()
|
|
1577
|
+
|
|
1578
|
+
if not device:
|
|
1579
|
+
return {'success': False, 'message': '没有找到活跃的设备会话'}
|
|
1580
|
+
|
|
1581
|
+
device_session_id = device['id']
|
|
1582
|
+
device_name = device['device_name']
|
|
1583
|
+
|
|
1584
|
+
# 撤销该设备的刷新令牌
|
|
1585
|
+
cursor.execute('''
|
|
1586
|
+
UPDATE refresh_tokens
|
|
1587
|
+
SET is_revoked = 1, revoked_at = %s, revoked_reason = 'current_device_logout'
|
|
1588
|
+
WHERE device_session_id = %s AND is_revoked = 0
|
|
1589
|
+
''', (current_time_utc, device_session_id))
|
|
1590
|
+
|
|
1591
|
+
# 停用设备会话
|
|
1592
|
+
cursor.execute('''
|
|
1593
|
+
UPDATE device_sessions
|
|
1594
|
+
SET is_active = 0
|
|
1595
|
+
WHERE id = %s
|
|
1596
|
+
''', (device_session_id,))
|
|
1597
|
+
|
|
1598
|
+
return {'success': True, 'message': f'已成功退出当前设备 "{device_name}"'}
|
|
1599
|
+
|
|
1600
|
+
except Exception as e:
|
|
1601
|
+
return {'success': False, 'message': f'退出当前设备失败: {str(e)}'}
|
|
1602
|
+
finally:
|
|
1603
|
+
cursor.close()
|
|
1604
|
+
conn.close()
|
|
1605
|
+
|
|
1606
|
+
def logout_specific_device(self, user_id, device_id):
|
|
1607
|
+
"""
|
|
1608
|
+
退出指定设备(通过device_id)
|
|
1609
|
+
|
|
1610
|
+
Args:
|
|
1611
|
+
user_id: 用户ID
|
|
1612
|
+
device_id: 要退出的设备ID
|
|
1613
|
+
|
|
1614
|
+
Returns:
|
|
1615
|
+
dict: 登出结果
|
|
1616
|
+
"""
|
|
1617
|
+
conn = self.pool.connection()
|
|
1618
|
+
cursor = conn.cursor()
|
|
1619
|
+
|
|
1620
|
+
try:
|
|
1621
|
+
current_time_utc = datetime.now(timezone.utc)
|
|
1622
|
+
|
|
1623
|
+
# 通过device_id查找设备,确保属于该用户
|
|
1624
|
+
cursor.execute('''
|
|
1625
|
+
SELECT id, device_name FROM device_sessions
|
|
1626
|
+
WHERE user_id = %s AND device_id = %s AND is_active = 1
|
|
1627
|
+
''', (user_id, device_id))
|
|
1628
|
+
|
|
1629
|
+
device = cursor.fetchone()
|
|
1630
|
+
|
|
1631
|
+
if not device:
|
|
1632
|
+
return {'success': False, 'message': '设备不存在或已退出'}
|
|
1633
|
+
|
|
1634
|
+
device_session_id = device['id']
|
|
1635
|
+
device_name = device['device_name']
|
|
1636
|
+
|
|
1637
|
+
# 撤销该设备的刷新令牌
|
|
1638
|
+
cursor.execute('''
|
|
1639
|
+
UPDATE refresh_tokens
|
|
1640
|
+
SET is_revoked = 1, revoked_at = %s, revoked_reason = 'specific_device_logout'
|
|
1641
|
+
WHERE device_session_id = %s AND is_revoked = 0
|
|
1642
|
+
''', (current_time_utc, device_session_id))
|
|
1643
|
+
|
|
1644
|
+
# 停用设备会话
|
|
1645
|
+
cursor.execute('''
|
|
1646
|
+
UPDATE device_sessions
|
|
1647
|
+
SET is_active = 0
|
|
1648
|
+
WHERE id = %s
|
|
1649
|
+
''', (device_session_id,))
|
|
1650
|
+
|
|
1651
|
+
return {'success': True, 'message': f'已成功退出设备 "{device_name}"'}
|
|
1652
|
+
|
|
1653
|
+
except Exception as e:
|
|
1654
|
+
return {'success': False, 'message': f'退出指定设备失败: {str(e)}'}
|
|
1655
|
+
finally:
|
|
1656
|
+
cursor.close()
|
|
1657
|
+
conn.close()
|
|
1658
|
+
|
|
1525
1659
|
def get_user_profile_stats(self, user_id):
|
|
1526
1660
|
"""获取用户资料统计信息"""
|
|
1527
1661
|
conn = self.pool.connection()
|
|
@@ -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=qTcnY2bvQn-NzVBlZcbrJG8Y5EPJqPqlZRvmmiZhj_k,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=9hYqpILqlpOJ89qi6N0h35QS7No2QNT8qCu78tajwIs,86999
|
|
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.103.dist-info/METADATA,sha256=PdQ5SB6ffus_bjg8DWRonFLHRF_JYD_BMtuqbv238g8,365
|
|
37
|
+
mdbq-4.0.103.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
38
|
+
mdbq-4.0.103.dist-info/top_level.txt,sha256=2FQ-uLnCSB-OwFiWntzmwosW3X2Xqsg0ewh1axsaylA,5
|
|
39
|
+
mdbq-4.0.103.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|