YCom: Ordnerschutz statt einzelner Dateischutz

Quell-ID: GitHub Discussion #26

Use Case

Statt jede Datei im Medienpool einzeln zu schützen, sollen ganze Ordner inklusive Unterordner mit YCom geschützt werden.

Verwendete AddOns

  • YCom
  • MediaAuth-Plugin (YCom)

Problemstellung

Das MediaAuth-Plugin in YCom ermöglicht nur den Schutz einzelner Dateien. Für jeden Upload muss der Dateischutz manuell aktiviert werden, was bei vielen Dateien unpraktisch ist.

Lösung

Diese Frage wurde in der Discussion gestellt, aber noch nicht vollständig beantwortet. Hier ist ein möglicher Lösungsansatz:

Variante 1: Über Medienpool-Kategorien

YCom prüft standardmäßig nur einzelne Dateien. Um ganze Kategorien zu schützen, kann ein Extension Point genutzt werden:

<?php
// In boot.php des project-AddOns

rex_extension::register('MEDIA_IS_PERMITTED', function (rex_extension_point $ep) {
    $media = $ep->getParam('media');
    
    // Geschützte Kategorie-IDs definieren
    $protectedCategories = [5, 8, 12]; // Anpassen!
    
    if (in_array($media->getCategoryId(), $protectedCategories)) {
        // Prüfen ob User eingeloggt ist
        if (!rex_ycom_auth::getUser()) {
            return false; // Zugriff verweigern
        }
    }
    
    return $ep->getSubject();
});

Variante 2: Pfad-basierter Schutz

<?php
// Dateien mit bestimmtem Präfix schützen
rex_extension::register('MEDIA_IS_PERMITTED', function (rex_extension_point $ep) {
    $filename = $ep->getParam('filename');
    
    // Dateien die mit "protected_" beginnen
    if (str_starts_with($filename, 'protected_')) {
        if (!rex_ycom_auth::getUser()) {
            return false;
        }
    }
    
    return $ep->getSubject();
});

Variante 3: Meta-Feld für Kategorie-Schutz

  1. Meta-Feld med_protected für Medienpool-Kategorien anlegen
  2. In der boot.php prüfen:
<?php
rex_extension::register('MEDIA_IS_PERMITTED', function (rex_extension_point $ep) {
    $media = $ep->getParam('media');
    $category = rex_media_category::get($media->getCategoryId());
    
    if ($category && $category->getValue('med_protected')) {
        if (!rex_ycom_auth::getUser()) {
            return false;
        }
    }
    
    return $ep->getSubject();
});

Besserer Ansatz

Vollständige Implementierung mit Benutzergruppen

<?php
// In lib/MediaProtection.php des project-AddOns

class MediaProtection
{
    private static array $protectedCategories = [];
    
    public static function init(): void
    {
        // Konfiguration aus Datenbank laden
        $sql = rex_sql::factory();
        $categories = $sql->getArray('
            SELECT id, med_required_groups 
            FROM ' . rex::getTable('media_category') . '
            WHERE med_protected = 1
        ');
        
        foreach ($categories as $cat) {
            self::$protectedCategories[$cat['id']] = explode(',', $cat['med_required_groups']);
        }
        
        rex_extension::register('MEDIA_IS_PERMITTED', [self::class, 'checkPermission']);
    }
    
    public static function checkPermission(rex_extension_point $ep): bool
    {
        $media = $ep->getParam('media');
        $categoryId = $media->getCategoryId();
        
        // Nicht geschützte Kategorie
        if (!isset(self::$protectedCategories[$categoryId])) {
            return $ep->getSubject();
        }
        
        $user = rex_ycom_auth::getUser();
        if (!$user) {
            return false;
        }
        
        // Benutzergruppen prüfen
        $requiredGroups = self::$protectedCategories[$categoryId];
        $userGroups = explode(',', $user->getValue('ycom_groups'));
        
        return !empty(array_intersect($requiredGroups, $userGroups));
    }
}

// In boot.php
if (rex_addon::get('ycom')->isAvailable()) {
    MediaProtection::init();
}

Hinweis

Diese Lösung erfordert, dass die .htaccess korrekt konfiguriert ist und alle Medien-Zugriffe durch PHP geleitet werden. Bei YRewrite ist dies standardmäßig der Fall.