Backups können gelöscht werden
Dieser Commit ist enthalten in:
@@ -1 +0,0 @@
|
|||||||
gAAAAABoRdxjzYyCvIeUaYc9K1vaykwB7TPKSrBtn0XTGFnjRN8Apb0oHxrcK0H7Kzc9OnsK-XgNLeABneIJytDoP_pd3B-omvJ9MHgmrFMSUUya7EkZPzV_DYQ_hepekkKe-zWR153orrwCZiPyWevymn7WkxtqPVcm_tSzhyKsbwWiEkECcsgUMV5TxEzPlJ369ZkMh0KJjcPSKLn5hD8pB03u8oPtbysDaGPRqIuXxzfG280yLpa5RUaix-QfvoD87BbrffW2d6S04816f0C9LR8UkJ4TjHVlslJH9O8Hbw9EhnNVwHeHa1O3trF-dAUqNzzE75v4ZRD4DgmvXlwovTa3GvSMINwBUrCg_uFjkEgMt4Jm9WbOoBGLrUMAUkRGmXDqB-H1mWuMejbS2BoGh-pFsDjmDAo6wRj2VeH2xckjZoMbrUS7oTs2nWJaj8edMRTftpsM419E0GUHK4nl03-Hn_ccZ4Azq_lsR92lioWh_YnG0N6EsmFfyW2nbMEwXTsL-0TuwwCkZXrzhMjhyuFDgwoPR26Z2sqeX8dX6oPNo7zp1JdGfGMc-wiacgmYwjHRuMLq5Oh8KpI9qn_BVhZIn8rYE64afRQYqqSjQUYwssninzfP3H9y_Hxvoq_xc7ryQNvfSCsvuqstMrCNyhKRVOktRAJ9n5VB_TRdSOryswgJzkyRI_BVZZH3ZZpF_QmC6C5OU4ArJ3l_lHbsDR5f6VRzBP-HN1uidi8AlWj3GQREMBbgnmNI25r_5OICZnSBjtAmF-gAwI7V8pv2LGjY_YpXIRoi-HAD7NLGUhS1_Y_l-k1kF-qw4MClFEaVPBuLSYOWI7gxg81stNsqWnRpdBkdQ6-OxBi8yg1Crkyf8Gsd_k_VRO9trIyyj5em3XJTxCrE6NeKX2Zbjd2cNKsQBotXan_pASwvxSXN7RJ9SxcLTB7KUgDhQZPx8oLRhs_c-zG1DnrJBE2xGClzEy1rlHhfL0VLkuwiyS5sL0jS6sxqNfN20-j7qhQG2SZjyNffZF3UaWtYeRvxpYFDosyQCmj49VvN5Sci70TTOl_tFJ4KttjDHY0npt7ZiypcX-Uvx-8gkoMoWBjMS_StndgibhQtuq4Annuj8O-JMP48x2BHIeC6yme34aPWKNu8Fj-ZOrOTWiXrIrroqXEh4B4SMtp4O1Pi7QiXJm39o-cceYwhwzA5WOXrlQ0hyGtKezP2zW4x5okMnAPVu2bLouIGvl05Tc_8X_Y3j_i9ffeo8YWYs66prEDr7fXX_4mi2fWrCdeNRErN08Hl7lvyV3x_nO5Ax_oEk8CWLcYA4GJ2-WDui0qJGiPKv345WZwi8ePUfd45wJmuWFXGjQ1ZCLl0ZXMeg4eT04x3IKuHNAbKIlvyd8kFHnEykGV-zAyiqPK4TVwtgZNZBecyxmmWfW7hP62v0ySTuvViQQS6Cy0X8DeChB7UrcsY7_ST7XmVFjM6iVlCZUfzKeU9UbMzLL6JGRXDudE1vyRdCJdwDg5IYWzSAd21Ibtqof6xfCVMPlFWK0YHt2Y79Pqk-aEsHg7PJlT-Kpr5N2dGvYkBrENt9WLGdzokVDANSGG_BFkTWgA-DZ-nUnjCxcBE3Yf58opcqGli_b7cDuTx_ZwUOXm6Rwm2KmxUNtX5InExKO_J_E1X4-_wDnOaS8330bbS-a1al83SntifM2Gv71yrxQE4y52buIDD4h9KJdnoGQE68CLjjI0oecdg2DGH5y74Jp7ZIJ3P3EOg4ITn7AXr53liXalmKP0m8JkHkJNvduDAtpCItHd9RAIPaZFi7xIRjIzbhif3rSx0UMW87v4tdX8lKa0RVGYKwpo7wU31F6EDx5L-bOWxr0BpSgpa_qNnc17e6yswGyLKlmqPWh07I08IwzflXV3l_td7-M8OLHIh3shMHngUorC04pz4FTtONkLBjZbKvLtNOorvjIVPezvdOvn_3Ii1CburGKiXkBH3c8Hrr2OotD1Ycgq2sqt50CvzmFS1asyA-jnPlBBlx5RJUWcU9TWX_QsvcDuFwNljPakN7phf2aR7QRFi8pUAIahJN1SQ6zsXKDRpv9l0hKmIt-wNRPx4ZBaZCZGiQrTycbKdfXvX_xSz7SRM7B4Tfhev0Iel0GZd-gAnQmJ5uwXhMYzQmRHjX_tfZf-FFV8YpVJ3d2uv9VBBIczKn9Epra-g97C1tKMfoLGzQ12dniH5u9vq0x7V58myxICuOmu2FIKXw0L0DN7IDpoxW5s9Tht8kA85wGpiANqf_BqLCILfmAPjX_jH6xfstqVDfu7aF5lrFcLYpyaqB-g2k4g8pPGMlUuowCZnVyo4sGcoSN_mt8vwgVNntWwzrcb6S727-tA8LXT6pnEm6ShURCTJiSOV3MXrqDoHvapvtCPYhRla2a8kS9Y3Fx654BwUbUloGXCgHlg5BCAbgjiJPYbn9-0FrjLIK9eqFPcs_dipokOF-z-__hgZNC-h_2oqlAyTVFrr_zfYIgHfsDdiDriUcXV4WTn4NGitIfa_P_hybFqR7TXgR9Ih5nQKBdOVpvJmlUGFvimhlga07UrSBd2hGjB6N6TBqJzzeZBsO1XfaXbVc0la2MrmsjRgr4sKLsfeJQi6VnYZHeBh3f9ra1Zq9Qqz80X4N0i6L6uF1DvfKgms7xkFLyy0sgjcnmKau5ZhgKlNh9CqJsO54vFciKyyOdFazuT7EGobXFHZhRcu1P0RE0grtGJ9cv8At-wgp72pmP_srNOVdje5Q1gVr0HcL3i3ywz0jT7eO8O30iB6aXFYdD2SF4DsdXNX3wzzZfuqSd2ii6L_Av2gLjRjW_TZXZgrZ0-PE0CSTf70cAL7W6D6k8hYz7HwPeJRFkjfQgtqXXfaB3gIX07olOBVxiPNN_5JMLMknp7S3Ij9W1Z0ZHE42aalqe_8L5Vh3S717P5IlvlCIZqzmyGxZF_i3ARCJV9sZ065xmR6-cAflP-48Q2Voemo99d2AH-2x8jgyu-7Vg5J3Bz19rC05wGkjzQSGoRqwyVpOm-RUERf5SOspVhrdh5Jxpkq_ydPlmGEpSjOShK3xBcy-HGqKVf3wnNVp1Tu3_PzbYn-4I2phJbUK14Cf5tdmj4SqZAjPoOcnK_tu5-Xxy2Js81kByi7VS6hIvAINhdcdi4ifgOPFkN03t5pX0pLppiroUJ8iybkLR4HtJL5RHJq0FjMxyUwAsfFGQx19v6QHJp2jxIW7Z-ZWPmPXz5_wTtZPs_UubJBiJxXD_2JWyW3lHu-Dldj1yWe9EEjqxivm71v5MUT0jQYfeDwf0esXYfQ6tJ2ZAhVUkPZHtlV4zgv34h8mp5k8GsZlqFAHaw6-aQqmjDFPTNZ9gYzP2MIhiv6GAjWcxevXwLXbQgSm6HSBNqHztRItNw_b6McCfbU91AYBp-fkJrenXLRFURuoC__YdTcxlg9CNW7lJh3v0RULw0JwfX93BBwrvrEXS93DoNw2AIJssIV0cfvgglHrmGMnK3xiQXU5hpGyp7T7rz09XzOB_10mdAAJCLVaJT42IZAeI__QHnV0L4mSuaiXBgzTSd5BokeU2QR3FtZw_axrAIwGqXVn3sMlzylFE7cNp1K49Fk_FfbeeKFPHmD-nSXZW-tO4WIUgPyQtzLFRNpxxPulZ3t_tK4RtgniDsb78aSMV32P4zxeG0Y8-2XkXb3rXaIgSidh8H_o1oV_5_cdnBNSp8eR8uE3mRZw3cKC891OQuC5V2t1MOKNIYNIhMJBHF2WYcMQgw-q0McqmzkUVBKv2fb6bGNzxldE_dz6830slVpaqu3SRKsMqKMZT4=
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
gAAAAABoReAamhCZ8jE9qi5Klhy4BxnffoaWCZn7X-sxrxzHpwCO9-BmDaV9sAr_IAZ78yXiZ5w_OqonOXR68CLJ75DIpi3EiSfbZdxIynni15vkmcoaVZq8MTMjw3_F_O6DSBKw_v6arV_NwnIQEOO0yBYcvIoX9W9QPzWhVnzC1-1vvHIpAyHpWinp1BrJ0jd0ec0dBk3CT5YvnPYZyf1ul8f0zAHbjcWnke1abOWk3GyUJoLLnDPRf6LCLTQf0SKyfnICPiBK_pNM67rOBcs50N645EB0iS9XtZ3_68OgXIYIqvwLVGNAfKXTOrTDFGkIHISCeHH-bd64966lo9KNnGLA_eEzpYTJqB1rO8_5G5trR3dXOVBW09TF73BfoWG9slIn-wNymkHH94XLvyPKGicNYXPnattDDZQtZY-pRdWV4qznYIgEm7Q3qGKZxj-DiyFCGQq7altk9Cm6zQ9ohlneOe4cWlevLFsWGl9Q8za-G7gHj1lTnyvb5O9MhmVAiDF5zvzdAvclF5q_wvc2poPjuZVY1tilT11iUSbtf9vb-0MSoL35wAKmvJU1KXX4xNBmlmC20rvL8BCiaRUsZrmai5Nm8GESMN2x6ohXLevVcU75Bnh4H_2EndgkBNxnj9fpiurlXpSq6NS1A-BQGLLuFgJxjokbkRRO-12R0tvrchA1tr8a9uIF5JyujyKyBABEI-q5SC60Ujcqzst_B7oTzxUTDgbuRk_0IVfz6OzfmqWrhEj40pXyYSyrmcih_TPN99ZOo725qT3zDSAAnNDqe5r_26Nr2-SXB9oZMLztCNBzcU4mXst5ZPeZ--BZh_E7azw18SDMuR-0zleXK30d1MC64-2T_dePBEagO1Grp2jOfRAraG7V3lqyYZS3w1UD_NoFAYksuJzu-msMVc910hDjH1tP01VbHsPULni0Em8J9sJatFQ0JSz9kjHn9DoEqGCaXhmxldcBRK6InL4SS08HjtwvSbbfz-dUBxtrC2p6HevYb1kDJAS2JrwS_HunjMpL05ZHKm-CeNqsoNKjAGBeqr3kERrFrmja7qBl_aPPJmeSh7_nvVDh6tc_F9UiDkMj3ScGAEMeJkoewBk51oNEspmdePydudsv1kht9lL8GSK3FoX3d-WQ2K92XY6Tw-VXm1JvCwDVpAy6kBUiCWS0KG9qE0O6BUU5J0JMc4GjYDBVe7sP-O1AcOe__rZ4oWqMHwmv7q3uNFkY98KZGPqVdg2kUNgtdBjzRjJDxbfUqvGP5c6PbWRFO0QKGYtbU0C7H6d-Bwi3suo65-9A6FBp6yZX6PwXBXLU2hz_d06szYdON4qZMwu9UwcvISm4jCuK_Qh6v8UyL_VfeZrt7VD4S7ChOWxs405h6-pxhH744N-wwJ-BpjyqOUfIn9Vv2-axY4JshNBOuk2dmZzNxXPW-u5O4rnBGZUnYdsuULa3YCR6JtC76t59EnbLpQO5S3EFw2_f6wfpiJc3RGYUu9rZQq_xPPwWgewWKxsvnhX3eRQGAdK50TwL86T0vP-e45Z-tGqI05WocIbxUr9SE2Xx1mqxe2prLK6rakulwNbwKkizsaK4GVTeya0PV8pLqVdIirqSbWcsgsP969b5Vz27clFpS_QZCG5eAYxUkNXKbwSEWcif-rXtudNBlrI9cS6zgC-d6RuDKbqdwe83Sb67W-_xjEE34DDod_jQe5Es4jnwDcBjUpgv8UKv1aOia3ICNIE5TgiufBmp_qA3lw0iyH-gk2oXr-p20sG-DIbcCALx9eP3pup25ow36nzUEqIGCG7YSN6kT5MUThKdiW0wu3AeWN9QCBaGUxoEU9OGGwOQx5kDkBVhBwvc2G0IrlZYzNHnkoawPRvHjpDbqFruAJIzU9hwVR-54mKqe7pJL3YuDzud7GK5c4xAgm4zF8v4lUMF1MkjmXvJFAI3wDLgx5i_J8U7VkDRjoClij_EZ27YTvPfheFA-_F1WLE3Cpc353uOyCt3vvPHHcH1UeazshgOIaVzdjuH3gzi4iUDP0MT7rWQJo-v0Ace3N5iYsZAkhtWVLGIa4tke174j97riWsqAQTnIz5unlTCSOieLtGprNxdm9FVPPVLdg5GWsz-wJ6aMq3Qm26yS01VBlzKud0rVU28hNaYj9Inyn_zwUm9sMC2XCTLFKbMqWw4CgH0udCSsMZUze7kEPjQF1wsJ-DQ54DbXZ_Ccb3og79qvaIm19XVEWA5gJ1qARpmWNdsrSJhEeMoJD5tkLGUwuPHRh7ADh8095EIrDCpbV0kRNlQzh5Q-_UX2XqbDX8aAPxuQGM0gdfmqSG_vaoYxYqJuA9CSasgelqlS1tYXpDxwlQALEmleebolT3HR-6hKNhTRDiuoCaxEuM5raPXq0HkB_NAnkNIxoVlVCFP1FQxs65YDtoym9dhfc5_Hqe6xVdDBDrMp-H2E2kCfBEMrs_ZR75uVO2j26SZqVLLy1iR_ER-u7uFZnWlH-3_fqkoJcYAbIQGZMe8wtOUfcvY5pPEzA9NNsuOqU3i4JO--Lin1Jiy9eowGx8ZtpxAsALb_X8rSOuZBIO8rf3zFEp8WDWKwdhTcoOJxL_tXBJ-BRCX8XRxxPKoas-xv6jq48O4gkQwh2ydfdQ-aN7su4k9maMx98uFBErqbrYIi9gs4dw60uxNl3whjxJVrO8pNjhRaHe0-_-l_LRb4MnCJL4OfmPxdHE7ecqCb5npbOIdI15AD93DB_cEQYzD3ZoBj_2LNT3NGUHLdy2WzLnd7Yudohi8LBymo1DBmWKnK1-lrhn58EhK1jMDrtuzETMmfNGR5sRY4OhCM7W32WxQqNO0gbQE4d09YLx8RGX4hi0hKP4kVeZFQLu8EauLkKTw_fxCtYs2p0cHu5u4mlUd-YI0_UTK01l6jomOQq9Bt12q0YPztKgdJZYDMbAsmdZrGfZHOSnCG44OD97Gq3QwNp6n7GwbW5qq36ybBbedc3BYK6101yqwVGZkDNBs4wrNPy9ZkJDxMEEaLBVshcJeOsw7uk7giozbc8s4PCvJwYaJNNoJe7bj-E-CSmdiXsBnFPY7DEfcjctDz05gcOmCAb1uMqXObvKooP8P0nUZojfVFkA6y6OZzCWza2-gtr2_DsQd3pn7aYxhf7JsGY3V652cYFlcuASbpH4BBbk5SRnPsCfrYDnLDmurFkMn0tPg8Bj2kyJ4wgh9vcY9AvxFpYiDI6gnAVa_eYijAmfOTczTk3SV3Yl0srRFhYYkutXLatf2pm3_aMg3HbB5N91kNqf4hJgcroJugvts1SeiGFKu6nQFhJdaoBBcEQQRsgEvyZiRF-HT5TMfg-_xY0-bmoPepd1qtvrR4q_sfubFEfwc9ExWPZPAkq6QPscYFXxaIX25mUKD8QkiEivhY2vEv3C8y9vyvG01KEeKyQXRBWLMMKWenPA6bpauVfgqPIXe3qvmMRwBKIugYAxZPKugMMOXSNcd-eYnQAgJ9kTDDajEeGyRyPNdgDYaIMvoEpZvMsOJ7_IcQeeMB88l9KUCC9F0FRjhwrFVFyHcoGdlUv4dg8bRvFQJWpwwqWhM1y3DPgaWOn28BO4bPY_X8CnYIqmMK7buWarpFlQMQC5bbuaeO_JXzuSn_w5Ap2wEcJFHvqqUy0YUsYBswomvvQbmqaIVpH74sbhfQu8OGS0vdtnA-3JggvNxv3YHrv6NExazJs2IMRbqr1hXwQj0G0oPj690j39trbZLNuCZpejjTrMu2npyy_mIFRAYEKT7eibBqcFrDcxAjf2G7t59eVi06ecVOq2O8o4cclFQrMwjMm4a66P3CFmsZldqecFSR0nIC_yW14clyvwu3rvCPssWwAkVzl_uF7RbVMHi6RgyWwuZ8sEGyoZ1p0TFlFFF0bMuSuMGVb8NG_sQl5faneRPjCh2f39ApoxciHD-bRgwhsS54jtoxSi0AFKzrjFK4PsWuCY6Qt3VU80hPv_3RlbVjALLise8w_0J_jQmQ7Z7Xrc6feNrYrg=
|
|
||||||
Dateidiff unterdrückt, weil mindestens eine Zeile zu lang ist
Dateidiff unterdrückt, weil mindestens eine Zeile zu lang ist
@@ -3024,6 +3024,62 @@ def download_backup(backup_id):
|
|||||||
|
|
||||||
return send_file(filepath, as_attachment=True, download_name=filename)
|
return send_file(filepath, as_attachment=True, download_name=filename)
|
||||||
|
|
||||||
|
@app.route("/backup/delete/<int:backup_id>", methods=["DELETE"])
|
||||||
|
@login_required
|
||||||
|
def delete_backup(backup_id):
|
||||||
|
"""Löscht ein Backup"""
|
||||||
|
conn = get_connection()
|
||||||
|
cur = conn.cursor()
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Backup-Informationen abrufen
|
||||||
|
cur.execute("""
|
||||||
|
SELECT filename, filepath
|
||||||
|
FROM backup_history
|
||||||
|
WHERE id = %s
|
||||||
|
""", (backup_id,))
|
||||||
|
backup_info = cur.fetchone()
|
||||||
|
|
||||||
|
if not backup_info:
|
||||||
|
return jsonify({
|
||||||
|
'success': False,
|
||||||
|
'message': 'Backup nicht gefunden'
|
||||||
|
}), 404
|
||||||
|
|
||||||
|
filename, filepath = backup_info
|
||||||
|
filepath = Path(filepath)
|
||||||
|
|
||||||
|
# Datei löschen, wenn sie existiert
|
||||||
|
if filepath.exists():
|
||||||
|
filepath.unlink()
|
||||||
|
|
||||||
|
# Aus Datenbank löschen
|
||||||
|
cur.execute("""
|
||||||
|
DELETE FROM backup_history
|
||||||
|
WHERE id = %s
|
||||||
|
""", (backup_id,))
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
# Audit-Log
|
||||||
|
log_audit('DELETE', 'backup', backup_id,
|
||||||
|
additional_info=f"Backup gelöscht: {filename}")
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'success': True,
|
||||||
|
'message': f'Backup "{filename}" wurde erfolgreich gelöscht'
|
||||||
|
})
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
conn.rollback()
|
||||||
|
return jsonify({
|
||||||
|
'success': False,
|
||||||
|
'message': f'Fehler beim Löschen des Backups: {str(e)}'
|
||||||
|
}), 500
|
||||||
|
finally:
|
||||||
|
cur.close()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
@app.route("/security/blocked-ips")
|
@app.route("/security/blocked-ips")
|
||||||
@login_required
|
@login_required
|
||||||
def blocked_ips():
|
def blocked_ips():
|
||||||
|
|||||||
@@ -131,6 +131,11 @@
|
|||||||
title="Backup wiederherstellen">
|
title="Backup wiederherstellen">
|
||||||
🔄 Wiederherstellen
|
🔄 Wiederherstellen
|
||||||
</button>
|
</button>
|
||||||
|
<button class="btn btn-outline-danger"
|
||||||
|
onclick="deleteBackup({{ backup[0] }}, '{{ backup[1] }}')"
|
||||||
|
title="Backup löschen">
|
||||||
|
🗑️ Löschen
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
@@ -268,5 +273,30 @@ function confirmRestore() {
|
|||||||
document.body.removeChild(loadingDiv);
|
document.body.removeChild(loadingDiv);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function deleteBackup(backupId, filename) {
|
||||||
|
if (!confirm(`Soll das Backup "${filename}" wirklich gelöscht werden?\n\nDieser Vorgang kann nicht rückgängig gemacht werden!`)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch(`/backup/delete/${backupId}`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
alert('✅ ' + data.message);
|
||||||
|
location.reload();
|
||||||
|
} else {
|
||||||
|
alert('❌ ' + data.message);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
alert('❌ Fehler beim Löschen des Backups: ' + error);
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
In neuem Issue referenzieren
Einen Benutzer sperren