Python CSC Electronic Office
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

79 lines
2.9 KiB

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
from ceo_common.interfaces import IFileService, IConfig, IUser
class FileService:
def __init__(self):
cfg = component.getUtility(IConfig)
self.member_home_skel = cfg.get('members_skel')
self.club_home_skel = cfg.get('clubs_skel')
def create_home_dir(self, user: IUser):
if user.is_club():
skel_dir = self.club_home_skel
skel_dir = self.member_home_skel
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
# 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 delete_home_dir(self, user: IUser):
def get_forwarding_addresses(self, user: IUser) -> List[str]:
forward_file = os.path.join(user.home_directory, '.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, user: IUser, addresses: List[str]):
for line in addresses:
if not is_valid_forwarding_address(line):
raise InvalidForwardingAddressException(line)
uid = user.uid_number
gid = user.gid_number
forward_file = os.path.join(user.home_directory, '.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)
# 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')