import multiprocessing import os import traceback from pwd import getpwnam from typing import Callable, Optional, TypeVar R = TypeVar('R') class CallAsUser: def __init__(self, target: Callable[[], R], user: str): self._target = target self._user = user def __call__(self, *args, **kwargs) -> R: try: os.setuid(getpwnam(self._user).pw_uid) return self._target() except Exception: traceback.print_exc() class WriteToFile: def __init__(self, file_path: str, content: str): self._file_path = file_path self._content = content def __call__(self, *args, **kwargs) -> bool: try: with open(self._file_path, 'w+') as f: f.write(self._content) return True except Exception: traceback.print_exc() return False def exec_as_user(target: Callable[[], R], user: Optional[str] = None) -> R: if user: with multiprocessing.Pool(1) as pool: return pool.apply(CallAsUser(target, user)) else: return target() def write_as_user(content: str, file_path: str, user: Optional[str] = None) -> bool: return exec_as_user(target=WriteToFile(file_path=file_path, content=content), user=user)