Add delete_inactive_gitea_users.py

This commit is contained in:
gru
2025-05-30 09:40:33 +02:00
parent 237775e9db
commit 1fa427bea7

View File

@ -0,0 +1,129 @@
#!/usr/bin/env python3
"""
CRON (przykład codziennie o 3:00):
0 3 * * * /usr/bin/python3 /root/gitea_clean/delete_inactive_gitea_users.py --delete-spammers >> /var/log/gitea_cleanup.log 2>&1
"""
import requests
import configparser
from datetime import datetime, timedelta, timezone
import os
import argparse
import dns.resolver
CONFIG_FILE = 'config.ini'
GITEA_URL = 'https://gitea.linuxiarz.pl'
DNI_BEZ_AKTYWNOŚCI = 180
def save_token_to_config(token):
config = configparser.ConfigParser()
config['auth'] = {'token': token}
with open(CONFIG_FILE, 'w') as configfile:
config.write(configfile)
def verify_token(token):
headers = {'Authorization': f'token {token}'}
r = requests.get(f'{GITEA_URL}/api/v1/admin/users?page=1', headers=headers)
return r.status_code == 200
def load_token():
config = configparser.ConfigParser()
if os.path.exists(CONFIG_FILE):
config.read(CONFIG_FILE)
token = config.get('auth', 'token', fallback=None)
if token and verify_token(token):
return token
else:
print("Token nie działa lub jest nieprawidłowy.")
token = input("Wklej ważny token API admina Gitea: ").strip()
save_token_to_config(token)
return token
def get_users(token):
headers = {'Authorization': f'token {token}'}
users = []
page = 1
while True:
r = requests.get(f'{GITEA_URL}/api/v1/admin/users?page={page}', headers=headers)
r.raise_for_status()
data = r.json()
if not data:
break
users.extend(data)
page += 1
return users
def delete_user(username, token, debug=False):
headers = {'Authorization': f'token {token}'}
r = requests.delete(f'{GITEA_URL}/api/v1/admin/users/{username}', headers=headers)
if r.status_code == 204:
if debug:
print(f"✅ Użytkownik {username} usunięty.")
else:
print(f"❌ Błąd przy usuwaniu {username}: {r.status_code} - {r.text}")
def is_email_domain_valid(email):
try:
domain = email.split('@')[1].lower()
answers = dns.resolver.resolve(domain, 'MX')
return len(answers) > 0
except Exception:
return False
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--delete-spammers', action='store_true', help='Usuń konta nieaktywne, zablokowane lub z błędnym e-mailem')
parser.add_argument('--delete-id-range', nargs=2, type=int, metavar=('MIN_ID', 'MAX_ID'), help='Usuń konta o ID z danego zakresu (włącznie)')
parser.add_argument('--debug', action='store_true', help='Tryb debugowania (wypisz operacje i użytkowników)')
args = parser.parse_args()
token = load_token()
cutoff = datetime.now(timezone.utc) - timedelta(days=DNI_BEZ_AKTYWNOŚCI)
users = get_users(token)
if args.debug:
print(f"📋 Pobrano {len(users)} użytkowników.")
print(f"⏱ Granica nieaktywności: {cutoff.isoformat()}")
for user in users:
user_id = user.get('id')
login = user['login']
email = user.get('email', '')
is_active = user.get('is_active', True)
prohibit_login = user.get('prohibit_login', False)
last_login = user.get('last_login', '')
if args.debug:
print(f"🔍 ID: {user_id} | {login} | aktywny: {is_active} | zablokowany: {prohibit_login} | e-mail: {email} | logowanie: {last_login or 'brak'}")
# ID zakres
if args.delete_id_range:
min_id, max_id = args.delete_id_range
if min_id <= user_id <= max_id:
if args.debug:
print(f"➡️ Usuwam ID {user_id}: {login}")
delete_user(login, token, args.debug)
continue
# Spammerzy
if args.delete_spammers:
if not is_email_domain_valid(email) or not is_active or prohibit_login:
if args.debug:
print(f"➡️ Usuwam spammera: {login}")
delete_user(login, token, args.debug)
continue
# Nieaktywni
if last_login:
last_login_dt = datetime.strptime(last_login, "%Y-%m-%dT%H:%M:%S%z")
if last_login_dt < cutoff:
if args.debug:
print(f"➡️ Usuwam nieaktywnego: {login}")
delete_user(login, token, args.debug)
else:
if args.debug:
print(f"➡️ Usuwam: {login} (nigdy się nie logował)")
delete_user(login, token, args.debug)
if __name__ == '__main__':
main()