#!/bin/bash

: '
#####################################################################
by Netzint GmbH 2025
Lukas Spitznagel (lukas.spitznagel@netzint.de)

This script sets all ACls recursively for all files and folders. It 
is important to repair the folder permissions in advance 
using "sophomorix-repair"!

Home-Directories:
  - /srv/samba/school/<SCHOOL>/teachers/<USERNAME> -> ACLs from <USERNAME>
  - /srv/samba/school/<SCHOOL>/students/<CLASS>/<USERNAME> -> ACLs from <USERNAME>

Share-Directories:
  - /srv/samba/school/<SCHOOL>/share/classes/<CLASS> -> ACLs from <CLASS>
  - /srv/samba/school/<SCHOOL>/share/projects/<PROJECT> -> ACLs from <PROJECT>
  - /srv/samba/school/<SCHOOL>/share/management -> ACLs from management
  - /srv/samba/school/<SCHOOL>/share/school -> ACLs from school
  - /srv/samba/school/<SCHOOL>/share/teachers -> ACLs from teachers

#####################################################################
'

if [[ -z $1 ]]; then
  echo "Keine Schule als Parameter angegeben!"
  echo "Aufruf: $(basename "$0") <SCHULE>"
  exit 1
fi

read -p "This will overwrite all permissions on the file system. Please only run this command if 'sophomorix-repair' has been run on the school server beforehand! (y/n) " input
[[ "$input" =~ ^[Yy]$ ]] || exit 1

# Basisverzeichnisse
TEACHERS_DIR="/srv/samba/schools/$1/teachers"
STUDENTS_DIR="/srv/samba/schools/$1/students"
SHARE_DIR="/srv/samba/schools/$1/share"

# Funktion zum Bereinigen der ACLs
clean_acl() {
    local acl_data="$1"
    local type="$2"

    if [[ "$type" == "dir" ]]; then
        # Entferne alle Zeilen mit "040rights"
        echo "$acl_data" | grep -v "040rights"
    elif [[ "$type" == "file" ]]; then
        # Entferne alle "default" ACL-Einträge
        echo "$acl_data" | grep -v "^default:"
    else
        echo "$acl_data"  # Falls kein Filter notwendig ist
    fi
}

# Funktion zum Setzen der ACLs für einen Benutzerordner
set_acls_for_user_folder() {
    local user_folder="$1"

    # ACL des Benutzerverzeichnisses speichern und bereinigen
    acl_user_folder=$(getfacl -p "$user_folder" 2>/dev/null)
    if [[ -z "$acl_user_folder" ]]; then
        echo "Fehler: Kann ACL von $user_folder nicht abrufen!"
        return
    fi
    acl_user_folder_cleaned=$(clean_acl "$acl_user_folder" "dir")

    # ACL des Transfer-Ordners speichern und bereinigen (falls vorhanden)
    transfer_folder="$user_folder/transfer"
    if [[ -d "$transfer_folder" ]]; then
        acl_transfer=$(getfacl -p "$transfer_folder" 2>/dev/null)
        if [[ -z "$acl_transfer" ]]; then
            echo "Fehler: Kann ACL von $transfer_folder nicht abrufen!"
            return
        fi
        acl_transfer_cleaned=$(clean_acl "$acl_transfer" "dir")
    else
        acl_transfer_cleaned=""
    fi

    echo "Setze ACLs für den Ordner: $user_folder"
    echo "$acl_user_folder_cleaned" | setfacl -R --set-file=- "$user_folder"
    if [[ -n "$acl_transfer_cleaned" ]]; then
        echo "Setze ACLs für den Ordner $user_folder/transfer"
        echo "$acl_transfer_cleaned" | setfacl -R --set-file=- "$user_folder/transfer"
    fi
}

# Funktion zum Setzen der ACLs für Share-Ordner
set_acls_for_share_folder() {
    local base_folder="$1"

    # Durchlaufe alle Unterordner in diesem Share-Bereich
    for main_folder in "$base_folder"/*; do
        echo "Verarbeite Unterordner: $main_folder"
        if [[ -d "$main_folder" ]]; then
            acl_main=$(getfacl -p "$main_folder" 2>/dev/null)
            if [[ -z "$acl_main" ]]; then
                echo "Fehler: Kann ACL von $main_folder nicht abrufen!"
                continue
            fi
            acl_main_cleaned=$(clean_acl "$acl_main" "dir")

            # Setze ACLs für alle Unterordner und Dateien
            echo "$acl_main_cleaned" | setfacl -R --set-file=- "$main_folder"
        fi
    done
}

# Funktion zum Setzen der ACLs für Flache-Share-Ordner
set_acls_for_flat_share_folder() {
    local base_folder="$1"

    if [[ -d "$base_folder" ]]; then
        acl_base=$(getfacl -p "$base_folder" 2>/dev/null)
        if [[ -z "$acl_base" ]]; then
            echo "Fehler: Kann ACL von $base_folder nicht abrufen!"
            return
        fi
        acl_base_cleaned=$(clean_acl "$acl_base" "dir")

        # Setze ACLs für alle Unterordner und Dateien
        echo "$acl_base_cleaned" | setfacl -R --set-file=- "$base_folder"
    fi
}


# Verarbeitung der Lehrerordner
if [[ -d "$TEACHERS_DIR" ]]; then
    for teacher_folder in "$TEACHERS_DIR"/*; do
        if [[ -d "$teacher_folder" ]]; then
            echo "Verarbeite Lehrerordner: $teacher_folder"
            set_acls_for_user_folder "$teacher_folder"
        fi
    done
else
    echo "Fehler: Lehrer-Verzeichnis $TEACHERS_DIR existiert nicht!"
fi

# Verarbeitung der Schülerordner mit Klassenstruktur
if [[ -d "$STUDENTS_DIR" ]]; then
    for class_folder in "$STUDENTS_DIR"/*; do
        if [[ -d "$class_folder" ]]; then
            for student_folder in "$class_folder"/*; do
                if [[ -d "$student_folder" ]]; then
                    echo "Verarbeite Schülerordner: $student_folder"
                    set_acls_for_user_folder "$student_folder"
                fi
            done
        fi
    done
else
    echo "Fehler: Schüler-Verzeichnis $STUDENTS_DIR existiert nicht!"
fi

# Verarbeitung der Share-Ordner
if [[ -d "$SHARE_DIR" ]]; then
    # Verarbeitung der Klassen- und Projekt-Ordner
    for subdir in "classes" "projects"; do
        if [[ -d "$SHARE_DIR/$subdir" ]]; then
            echo "Verarbeite Share-Unterverzeichnis: $SHARE_DIR/$subdir"
            set_acls_for_share_folder "$SHARE_DIR/$subdir"
        fi
    done
    # Verarbeitung der School- und Teacher-Ordner (keine extra Unterstrukturen)
    for simple_dir in "school" "teachers" "management"; do
        if [[ -d "$SHARE_DIR/$simple_dir" ]]; then
            echo "Setze ACLs direkt für $SHARE_DIR/$simple_dir"
            set_acls_for_flat_share_folder "$SHARE_DIR/$simple_dir"
        fi
    done
fi

echo "Berechtigungen erfolgreich gesetzt!"
