pyceo/ceod/model/FileService.py

80 lines
2.9 KiB
Python
Raw Normal View History

2021-07-23 20:08:22 -04:00
import os
import shutil
from typing import List
from zope import component
from zope.interface import implementer
from .validators import is_valid_forwarding_address, InvalidForwardingAddressException
2021-07-24 17:09:10 -04:00
from ceo_common.interfaces import IFileService, IConfig, IUser
2021-07-23 20:08:22 -04:00
@implementer(IFileService)
class FileService:
def __init__(self):
cfg = component.getUtility(IConfig)
2021-08-03 19:19:33 -04:00
self.member_home_skel = cfg.get('members_skel')
self.club_home_skel = cfg.get('clubs_skel')
2021-07-23 20:08:22 -04:00
2021-07-24 17:09:10 -04:00
def create_home_dir(self, user: IUser):
if user.is_club():
2021-07-23 20:08:22 -04:00
skel_dir = self.club_home_skel
else:
skel_dir = self.member_home_skel
2021-07-24 17:09:10 -04:00
home = user.home_directory
# It's important to NOT use pwd here because if the user was recently
# deleted (e.g. as part of a rolled back transaction), their old UID
# and GID numbers will still be in the NSS cache.
uid = user.uid_number
gid = user.gid_number
2021-07-23 20:08:22 -04:00
# 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)
2021-07-24 17:09:10 -04:00
def delete_home_dir(self, user: IUser):
shutil.rmtree(user.home_directory)
def get_forwarding_addresses(self, user: IUser) -> List[str]:
forward_file = os.path.join(user.home_directory, '.forward')
2021-07-23 20:08:22 -04:00
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] != '#'
]
2021-07-24 17:09:10 -04:00
def set_forwarding_addresses(self, user: IUser, addresses: List[str]):
2021-07-23 20:08:22 -04:00
for line in addresses:
if not is_valid_forwarding_address(line):
raise InvalidForwardingAddressException(line)
2021-07-24 17:09:10 -04:00
uid = user.uid_number
gid = user.gid_number
forward_file = os.path.join(user.home_directory, '.forward')
2021-07-23 20:08:22 -04:00
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')