Folgende Funktionen hab ich hinzugefügt / bzw geändert:
Code: Alles auswählen
<?php
/*
* Sicherheitswert Pruefen
*/
function rex_com_checkPerm($type = '')
{
global $REX;
if ($type == "") return true; // Zugriff fuer alle
if ($type == "0") return true; // Zugriff fuer alle
if (isset($REX['COM_USER']) && is_object($REX['COM_USER']))
{
if ($REX['COM_USER']->getValue("secu_group") >= $type) return true;
}
if(!isset($REX['COM_USER']) || !is_object($REX['COM_USER']))
{
if ($type == "-1") return true; // Zugriff fuer nicht eingeloggte User
}
}
/*
* Sicherheitsrechte von Kategorien Pruefen
*/
function rex_com_checkCatPerm($category_id)
{
$cat = OOCategory::getCategoryById($category_id);
$tree = $cat->getParentTree();
foreach($tree as $cat)
{
if($type <= $cat->getValue('cat_com_perm'))
$type = $cat->getValue('cat_com_perm');
}
return rex_com_checkPerm($type);
}
/*
* Sicherheitsrechte von Dateien Pruefe
*/
function rex_com_checkFilePerm($filename)
{
if(isset($filename))
{
$file = OOMedia::getMediaByFileName($filename);
$value = rex_com_checkPerm($file->getValue('med_com_perm'));
}
else
{
$value = false;
}
return $value;
}
?>
Diese Funktionen setzen voraus, dass es ein MetaFeld "cat_com_perm" für Kategorien, ein MetaFeld "med_com_perm" für Medien (kannst Du auch weg lassen, wenn du Medien nicht durch php streamst und überprüfen möchtest) und ein UserFeld im Community AddOn "secu_group" gibt.
Ein Select-Feld mit (in meinem Beispiel folgenden Werten)
Code: Alles auswählen
0:Alle|-1:Nur nicht Eingeloggte|1:mind. S1 (Freunde, Anwärter, Kandidaten)|2:mind. S2 (Vollmitglieder, Aktive)|3:mind. S3 (Vorstand)
Die Beispielnavigation wurde dann mit der neuen Funktion rex_com_checkCatPerm erweitert:
Code: Alles auswählen
<?php
// EXPLODE PATH
$PATH = explode("|",$this->getValue("path").$this->getValue("article_id")."|");
// GET CURRENTS
$path1 = $PATH[1];
$path2 = $PATH[2];
$path3 = $PATH[3];
$path4 = $PATH[4];
$catsArr = array();
$nav = '';
$c1 = 0;
$lev1Cats = OOCategory::getChildrenById($path1, "true");
foreach ($lev1Cats as $lev1)
{
if(rex_com_checkCatPerm($lev1->_id)) {
if ($lev1->getId() == $path2)
$nav .= '<li><a class="active" href="'.rex_getUrl($lev1->getId()).'">'.$lev1->getName().'</a>';
else
$nav .= '<li><a href="'.rex_getUrl($lev1->getId()).'">'.$lev1->getName().'</a>';
$lev2Cats = $lev1->getChildren(true);
$nav2 = '';
if ($lev1->getId() == $path2 AND sizeof($lev2Cats) != 0)
{
foreach ($lev2Cats as $lev2)
{
if (rex_com_checkCatPerm($lev2->_id))
{
if ($lev2->getId() == $path3)
$nav2 .= '<li><a class="active" href="'.rex_getUrl($lev2->getId()).'">'.$lev2->getName().'</a>';
else
$nav2 .= '<li><a href="'.rex_getUrl($lev2->getId()).'">'.$lev2->getName().'</a>';
$lev3Cats = $lev2->getChildren(true);
$nav3 = '';
if ($lev2->getId() == $path3 AND sizeof($lev3Cats) != 0)
{
foreach ($lev3Cats as $lev3)
{
if (rex_com_checkCatPerm($lev3->_id))
{
if ($lev3->getId() == $path4)
$nav3 .= '<li><a class="active" href="'.rex_getUrl($lev3->getId()).'">'.$lev3->getName().'</a></li>';
else
$nav3 .= '<li><a href="'.rex_getUrl($lev3->getId()).'">'.$lev3->getName().'</a></li>';
}
}
}
if ($nav3 != '')
$nav2 .= '<ul>'.$nav3.'</ul>';
$nav2 .= '</li>';
}
}
}
if ($nav2 != '')
$nav .= '<ul>'.$nav2.'</ul>';
$nav .= '</li>';
}
}
if(!empty($nav)){print '<div class="subnav-head"> </div><ul id="subnav">'.$nav.'</ul>';}
?>
Edit: Die Navigation wurde bei mir nur als Subnavi eingesetzt. Die Root-Navigation hatte keine Rechteprüfung, da dies nicht erforderlich war. Wenn als Root-Navi verwendet werden soll muss oben das Path Array angepasst werden.
Ich glaub das waren alle Änderungen die ich gemacht hatte.
Eidt: Ach halt nein. das Wichtigste hätte ich ja fast vergessen. Im Template selbst steht dann natürlich jetzt:
Code: Alles auswählen
.
.
.
<?php if(rex_com_checkCatPerm($this->getValue("category_id"))){ ?>
.
.
.
TEMPLATE
.
.
.
<?php
}
else
{
header('Location:'.rex_getUrl($REX["ADDON"]["COMMUNITY_VARS"]["COM_PAGE_LOGIN_ID"],'',array('redirect_to'=>$this->article_id),'&').'');
}
?>
Okay
Danke für deine PM - auf Wunsch auch eine Ausführung zum Dateischutz
Zunächst muss man den direkten Zugriff auf den /files/ Ordner natürlich erst mit .htaccess (liegt bei mir direkt im files Ordner) gegen direkten Zugriff schützen - das hab ich wie folgt (und dank Hilfe hier im Forum) gelöst:
Code: Alles auswählen
RewriteCond %{REQUEST_URI} !files/(.*).(jpg|jpeg|png|gif|ico|css|js|swf)$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/index.php?get_file=$1 [R=301,L]
Aus Perfomancegründen und der Einfachkeithalber hab ich Grafiken, CSS usw (siehe oben) von dieser Regel ausgenommen. Sofern sicher gestellt ist, dass Grafiken generell über den Image_manager / image_resize aufgerufen werden kann man diese Regel auch reduzieren.
Den Funktionen von oben muss nun noch diese Funktion hinzugefügt werden welche die aufgerufene Datei durch php zu Streamen.
Code: Alles auswählen
function rex_com_sendFile($filename)
{
global $REX;
if(rex_com_checkFilePerm($filename) == true)
{
$filename = $REX['HTDOCS_PATH'].'files/'.basename($filename);
if($filename <> '' and file_exists($filename))
{
if(is_file($filename) && is_readable($filename))
{
// fix for IE catching or PHP bug issue
header("Pragma: public");
header("Expires: 0"); // set expiration time
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
// browser must download file from server instead of cache
// force download dialog
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
// use the Content-Disposition header to supply a recommended filename and
// force the browser to display the save dialog.
header("Content-Disposition: attachment; filename=".basename($filename).";");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filename)); @readfile($filename); exit(0);
}
}
}
else
{
header('HTTP/1.0 401 Unauthorized');
if(rex_get('no_redirect','int') != 1)
{
rex_redirect($REX["ADDON"]["COMMUNITY_VARS"]["COM_PAGE_LOGIN_ID"],'', $params = array('get_file'=>rex_get('get_file','string'),'no_redirect'=>1));
}
}
}
Und im nächsten Schritt sorgen wir dafür, dass beim aufruf von index.php?get_file= auch wirkliche eine Datei geliefert wird. Hierzu steht im Template bei mir:
Code: Alles auswählen
/* Wenn get_file gesetzt, Datei Streamen */
if(rex_get('get_file','string') != '')
rex_com_sendFile(rex_get('get_file','string'));
Was im weiteren vielleicht noch interessant wäre ist mein angepastes Loginscript, da ich bei einem versuchten Zugriff auf eine Geschützte Seite / Datei ein Formular zeige. Gelingt dann ein Login, wird man zur ursprünglich angefragten Seite / Date redirected. Ist für den User schön komfortabel.
Code: Alles auswählen
<?php
// USER AUTH
unset($REX['COM_USER']);
$pagekey = 'comrex'; // Frontendkey, muss sich unterscheiden, damit frontend und backend sich nicht schneiden.
$login_name = rex_request("login_name","string");
$login_psw = rex_request("login_psw","string");
$logout = rex_request("logout","int");
$get_file = rex_get('get_file','string');
$redirect_to = rex_get('redirect_to','int');
// ----- session start
session_start();
if ((isset($_SESSION[$pagekey]['UID']) && $_SESSION[$pagekey]['UID'] != "") or $login_name != "" or $login_psw != "")
{
$user_id = (int) $_SESSION[$pagekey]['UID'];
$GLOBALS["I18N"] = rex_create_lang("de");
$REX['COM_USER'] = new rex_login();
$REX['COM_USER']->setSqlDb(1);
$REX['COM_USER']->setSysID($pagekey);
$REX['COM_USER']->setSessiontime(3600);
$REX['COM_USER']->setLogin($login_name,sha1($login_psw));
if ($logout == 1) { $REX['COM_USER']->setLogout(true); }
$REX['COM_USER']->setUserID("rex_com_user.id");
$REX['COM_USER']->setUserquery("select * from rex_com_user where id='USR_UID' and status>0");
$REX['COM_USER']->setLoginquery("select * from rex_com_user where login='USR_LOGIN' and password='USR_PSW' and status>0");
if ($REX['COM_USER']->checkLogin())
{
// ----- Login gelungen
if ($login_name != "")
{
// ----- Login gelungen und gerade erst eingeloggt
$REX['COM_LOGIN_MSG'] = 'Du hast dich erfolgreich eingelogt!';
$COM_USER_SAVE = new rex_sql();
$COM_USER_SAVE->setTable('rex_com_user');
$COM_USER_SAVE->setValue('last_login_time',time());
$COM_USER_SAVE->setWhere('id='.$REX['COM_USER']->getValue('rex_com_user.id'));
$COM_USER_SAVE->update();
if($redirect_to != 0)
{
header('Location:'.rex_getUrl($redirect_to));
exit;
}
else
{
header('Location:'.rex_getUrl($REX["ADDON"]["COMMUNITY_VARS"]["COM_PAGE_PROFIL_ID"]).'?get_file='.$get_file);
exit;
}
}
if($REX['COM_USER']->getValue('rex_com_user.password_edited') == 0)
{
$REX['COM_INFO_MSG'] = 'Du hast dein Kennwort noch nie geändert! Bitte ändere Dein Passwort in ein sicheres Passwort.';
}
}
else
{
// ----- Login failed
$REX['COM_LOGIN_MSG'] = 'Der Login ist fehlgeschlagen. Bitte überprüfe deine Eingaben.';
if ($logout == 1) $REX['COM_LOGIN_MSG'] = 'Sie haben sich ausgeloggt';
unset($REX['COM_USER']);
}
}else
{
unset($REX['COM_USER']);
}
if($get_file != '')
$REX['COM_LOGIN_MSG'] = 'Du versuchst den Zugriff auf eine geschützte Datei. Dazu musst du angemeldet sein und die nötigen Rechte besitzen.';
elseif($redirect_to != 0 && $redirect_to != $REX["ADDON"]["COMMUNITY_VARS"]["COM_PAGE_PROFIL_ID"])
$REX['COM_LOGIN_MSG'] = 'Du versuchst den Zugriff auf eine geschützte Seite. Dazu musst du angemeldet sein und die nötigen Rechte besitzen.';
?>
So. Ich hoffe das ist ausführlich genug - kann aber auch sein, dass ich was vergessen habe