pyceo/ceod/model/FileService.py

80 lines
2.8 KiB
Python
Raw Normal View History

2021-07-23 20:08:22 -04:00
import os
import pwd
import shutil
from typing import List
from zope import component
from zope.interface import implementer
from .validators import is_valid_forwarding_address, InvalidForwardingAddressException
from ceo_common.interfaces import IFileService, IConfig
@implementer(IFileService)
class FileService:
def __init__(self):
cfg = component.getUtility(IConfig)
self.member_home_skel = cfg.get('member_home_skel')
self.club_home_skel = cfg.get('club_home_skel')
def create_home_dir(self, username: str, is_club: bool = False):
if is_club:
skel_dir = self.club_home_skel
else:
skel_dir = self.member_home_skel
pwnam = pwd.getpwnam(username)
home = pwnam.pw_dir
uid = pwnam.pw_uid
gid = pwnam.pw_gid
# recursively copy skel dir to user's home
shutil.copytree(skel_dir, home)
# Set ownership and permissions on user's home.
# The setgid bit ensures that all files created under that
# directory belong to the owner (useful for clubs).
os.chmod(home, mode=0o2751) # rwxr-s--x
os.chown(home, uid=uid, gid=gid)
# recursively set file ownership
for root, dirs, files in os.walk(home):
for dir in dirs:
os.chown(os.path.join(root, dir), uid=uid, gid=gid)
for file in files:
os.chown(os.path.join(root, file), uid=uid, gid=gid)
def get_forwarding_addresses(self, username: str) -> List[str]:
pwnam = pwd.getpwnam(username)
home = pwnam.pw_dir
forward_file = os.path.join(home, '.forward')
if not os.path.isfile(forward_file):
return []
lines = [
line.strip() for line in open(forward_file).readlines()
]
return [
line for line in lines
if line != '' and line[0] != '#'
]
def set_forwarding_addresses(self, username: str, addresses: List[str]):
for line in addresses:
if not is_valid_forwarding_address(line):
raise InvalidForwardingAddressException(line)
pwnam = pwd.getpwnam(username)
home = pwnam.pw_dir
uid = pwnam.pw_uid
gid = pwnam.pw_gid
forward_file = os.path.join(home, '.forward')
if os.path.exists(forward_file):
# create a backup
backup_forward_file = forward_file + '.bak'
shutil.copyfile(forward_file, backup_forward_file)
os.chown(backup_forward_file, uid=uid, gid=gid)
else:
# create a new ~/.forward file
open(forward_file, 'w')
os.chown(forward_file, uid=uid, gid=gid)
with open(forward_file, 'w') as f:
for line in addresses:
f.write(line + '\n')