123 lines
3.7 KiB
Python
123 lines
3.7 KiB
Python
import json
|
||
import os
|
||
import hashlib
|
||
|
||
|
||
class UserProfile:
|
||
"""Объект пользователя системы.
|
||
|
||
Хранит логин, хэш пароля и список сохранённых репозиториев.
|
||
Используется как логическая модель для диаграммы классов.
|
||
"""
|
||
|
||
def __init__(self, login, password_hash="", repositories=None):
|
||
self.login = login
|
||
self.password_hash = password_hash
|
||
self.repositories = repositories or []
|
||
|
||
def to_dict(self):
|
||
return {
|
||
"password": self.password_hash,
|
||
"repositories": self.repositories,
|
||
}
|
||
|
||
|
||
class StorageManager:
|
||
"""Класс локального хранилища.
|
||
|
||
Отвечает за регистрацию, вход, сохранение и удаление ссылок.
|
||
Данные хранятся в JSON-файле рядом с программой.
|
||
"""
|
||
|
||
def __init__(self, data_file="users_data.json"):
|
||
self.data_file = data_file
|
||
|
||
def _load(self):
|
||
if not os.path.exists(self.data_file):
|
||
return {"users": {}}
|
||
try:
|
||
with open(self.data_file, "r", encoding="utf-8") as f:
|
||
return json.load(f)
|
||
except Exception:
|
||
return {"users": {}}
|
||
|
||
def _save(self, data):
|
||
with open(self.data_file, "w", encoding="utf-8") as f:
|
||
json.dump(data, f, ensure_ascii=False, indent=2)
|
||
|
||
def _hash_password(self, password):
|
||
return hashlib.sha256(password.encode("utf-8")).hexdigest()
|
||
|
||
def register_user(self, login, password):
|
||
data = self._load()
|
||
if login in data["users"]:
|
||
return False, "Такой пользователь уже существует"
|
||
|
||
user = UserProfile(
|
||
login=login,
|
||
password_hash=self._hash_password(password),
|
||
repositories=[],
|
||
)
|
||
data["users"][login] = user.to_dict()
|
||
self._save(data)
|
||
return True, "Профиль создан"
|
||
|
||
def check_user(self, login, password):
|
||
data = self._load()
|
||
user = data["users"].get(login)
|
||
if not user:
|
||
return False
|
||
return user.get("password") == self._hash_password(password)
|
||
|
||
def get_repositories(self, login):
|
||
data = self._load()
|
||
return data["users"].get(login, {}).get("repositories", [])
|
||
|
||
def add_repository(self, login, link):
|
||
data = self._load()
|
||
repos = data["users"].setdefault(
|
||
login,
|
||
{"password": "", "repositories": []},
|
||
).setdefault("repositories", [])
|
||
|
||
if link in repos:
|
||
return False
|
||
|
||
repos.append(link)
|
||
self._save(data)
|
||
return True
|
||
|
||
def delete_repository(self, login, link):
|
||
data = self._load()
|
||
repos = data["users"].get(login, {}).get("repositories", [])
|
||
if link in repos:
|
||
repos.remove(link)
|
||
self._save(data)
|
||
return True
|
||
return False
|
||
|
||
|
||
# Обратная совместимость: если старый код где-то импортирует функции,
|
||
# они всё равно работают через объект StorageManager.
|
||
_default_storage = StorageManager()
|
||
|
||
|
||
def register_user(login, password):
|
||
return _default_storage.register_user(login, password)
|
||
|
||
|
||
def check_user(login, password):
|
||
return _default_storage.check_user(login, password)
|
||
|
||
|
||
def get_repositories(login):
|
||
return _default_storage.get_repositories(login)
|
||
|
||
|
||
def add_repository(login, link):
|
||
return _default_storage.add_repository(login, link)
|
||
|
||
|
||
def delete_repository(login, link):
|
||
return _default_storage.delete_repository(login, link)
|