bucket-password-helper.py 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. Bucket密码管理工具
  5. 用于生成、验证和修改bucket访问密码
  6. """
  7. import hashlib
  8. import secrets
  9. import string
  10. import sys
  11. import mysql.connector
  12. from mysql.connector import Error
  13. class BucketPasswordHelper:
  14. def __init__(self, host='localhost', user='root', password='', database='ry-vue'):
  15. self.host = host
  16. self.user = user
  17. self.password = password
  18. self.database = database
  19. def connect_db(self):
  20. """连接数据库"""
  21. try:
  22. connection = mysql.connector.connect(
  23. host=self.host,
  24. user=self.user,
  25. password=self.password,
  26. database=self.database
  27. )
  28. return connection
  29. except Error as e:
  30. print(f"数据库连接失败: {e}")
  31. return None
  32. def generate_password(self, length=12):
  33. """生成强密码"""
  34. # 确保包含至少一个大写字母、小写字母、数字和特殊字符
  35. password = (
  36. secrets.choice(string.ascii_uppercase) +
  37. secrets.choice(string.ascii_lowercase) +
  38. secrets.choice(string.digits) +
  39. secrets.choice('!@#$%^&*') +
  40. ''.join(secrets.choice(string.ascii_letters + string.digits + '!@#$%^&*')
  41. for _ in range(length - 4))
  42. )
  43. # 打乱密码字符顺序
  44. password_list = list(password)
  45. secrets.SystemRandom().shuffle(password_list)
  46. return ''.join(password_list)
  47. def encrypt_password(self, password, bucket_name):
  48. """加密密码(MD5 + 盐值)"""
  49. salt = f"{bucket_name}_salt_2025"
  50. encrypted = hashlib.md5((password + salt).encode('utf-8')).hexdigest()
  51. return encrypted
  52. def update_bucket_password(self, bucket_name, new_password):
  53. """更新bucket密码"""
  54. connection = self.connect_db()
  55. if not connection:
  56. return False
  57. try:
  58. cursor = connection.cursor()
  59. # 加密新密码
  60. encrypted_password = self.encrypt_password(new_password, bucket_name)
  61. # 检查是否存在密码记录
  62. cursor.execute(
  63. "SELECT id FROM sys_bucket_access_password WHERE bucket_name = %s AND deleted = 0",
  64. (bucket_name,)
  65. )
  66. result = cursor.fetchone()
  67. if result:
  68. # 更新现有记录
  69. cursor.execute("""
  70. UPDATE sys_bucket_access_password
  71. SET access_password = %s, update_time = NOW(), update_by = 1
  72. WHERE bucket_name = %s AND deleted = 0
  73. """, (encrypted_password, bucket_name))
  74. else:
  75. # 插入新记录
  76. cursor.execute("""
  77. INSERT INTO sys_bucket_access_password
  78. (bucket_name, access_password, password_salt, is_active, max_access_count, create_by, tenant_id)
  79. VALUES (%s, %s, %s, 1, 0, 1, 0)
  80. """, (bucket_name, encrypted_password, f"{bucket_name}_salt_2025"))
  81. connection.commit()
  82. print(f"✅ Bucket '{bucket_name}' 密码更新成功")
  83. print(f"📝 新密码: {new_password}")
  84. print(f"🔐 加密后: {encrypted_password}")
  85. return True
  86. except Error as e:
  87. print(f"❌ 更新密码失败: {e}")
  88. return False
  89. finally:
  90. if connection.is_connected():
  91. cursor.close()
  92. connection.close()
  93. def verify_password(self, bucket_name, password):
  94. """验证密码"""
  95. connection = self.connect_db()
  96. if not connection:
  97. return False
  98. try:
  99. cursor = connection.cursor()
  100. encrypted_password = self.encrypt_password(password, bucket_name)
  101. cursor.execute("""
  102. SELECT access_password FROM sys_bucket_access_password
  103. WHERE bucket_name = %s AND deleted = 0
  104. """, (bucket_name,))
  105. result = cursor.fetchone()
  106. if result and result[0] == encrypted_password:
  107. print(f"✅ 密码验证成功")
  108. return True
  109. else:
  110. print(f"❌ 密码验证失败")
  111. return False
  112. except Error as e:
  113. print(f"❌ 验证密码失败: {e}")
  114. return False
  115. finally:
  116. if connection.is_connected():
  117. cursor.close()
  118. connection.close()
  119. def get_password_info(self, bucket_name):
  120. """获取密码信息"""
  121. connection = self.connect_db()
  122. if not connection:
  123. return None
  124. try:
  125. cursor = connection.cursor()
  126. cursor.execute("""
  127. SELECT bucket_name, is_active, max_access_count, current_access_count,
  128. expire_time, update_time
  129. FROM sys_bucket_access_password
  130. WHERE bucket_name = %s AND deleted = 0
  131. """, (bucket_name,))
  132. result = cursor.fetchone()
  133. if result:
  134. print(f"📊 Bucket '{bucket_name}' 密码信息:")
  135. print(f" 状态: {'启用' if result[1] == 1 else '禁用'}")
  136. print(f" 最大访问次数: {result[2] if result[2] > 0 else '无限制'}")
  137. print(f" 当前访问次数: {result[3]}")
  138. print(f" 过期时间: {result[4] if result[4] else '永不过期'}")
  139. print(f" 更新时间: {result[5]}")
  140. return result
  141. else:
  142. print(f"❌ Bucket '{bucket_name}' 密码配置不存在")
  143. return None
  144. except Error as e:
  145. print(f"❌ 获取密码信息失败: {e}")
  146. return None
  147. finally:
  148. if connection.is_connected():
  149. cursor.close()
  150. connection.close()
  151. def main():
  152. """主函数"""
  153. print("🔐 Bucket密码管理工具")
  154. print("=" * 50)
  155. # 数据库配置
  156. host = input("数据库主机 (默认: localhost): ").strip() or "localhost"
  157. user = input("数据库用户名 (默认: root): ").strip() or "root"
  158. password = input("数据库密码: ").strip()
  159. database = input("数据库名称 (默认: ry-vue): ").strip() or "ry-vue"
  160. helper = BucketPasswordHelper(host, user, password, database)
  161. while True:
  162. print("\n请选择操作:")
  163. print("1. 生成强密码")
  164. print("2. 更新bucket密码")
  165. print("3. 验证bucket密码")
  166. print("4. 查看密码信息")
  167. print("5. 退出")
  168. choice = input("\n请输入选择 (1-5): ").strip()
  169. if choice == "1":
  170. length = int(input("密码长度 (默认: 12): ").strip() or "12")
  171. new_password = helper.generate_password(length)
  172. print(f"🔑 生成的强密码: {new_password}")
  173. elif choice == "2":
  174. bucket_name = input("Bucket名称: ").strip()
  175. if not bucket_name:
  176. print("❌ Bucket名称不能为空")
  177. continue
  178. use_generated = input("是否使用生成的强密码? (y/n): ").strip().lower()
  179. if use_generated == 'y':
  180. length = int(input("密码长度 (默认: 12): ").strip() or "12")
  181. new_password = helper.generate_password(length)
  182. print(f"🔑 生成的密码: {new_password}")
  183. else:
  184. new_password = input("新密码: ").strip()
  185. if not new_password:
  186. print("❌ 密码不能为空")
  187. continue
  188. helper.update_bucket_password(bucket_name, new_password)
  189. elif choice == "3":
  190. bucket_name = input("Bucket名称: ").strip()
  191. password = input("密码: ").strip()
  192. if bucket_name and password:
  193. helper.verify_password(bucket_name, password)
  194. else:
  195. print("❌ Bucket名称和密码不能为空")
  196. elif choice == "4":
  197. bucket_name = input("Bucket名称: ").strip()
  198. if bucket_name:
  199. helper.get_password_info(bucket_name)
  200. else:
  201. print("❌ Bucket名称不能为空")
  202. elif choice == "5":
  203. print("👋 再见!")
  204. break
  205. else:
  206. print("❌ 无效选择,请重新输入")
  207. if __name__ == "__main__":
  208. main()