Möglichkeit, den Standard-Client festzulegen

Fragen zur Installation von CONTENIDO 4.9? Probleme bei der Konfiguration? Hinweise oder Fragen zur Entwicklung des Systemes oder zur Sicherheit?
Antworten
HerrB
Beiträge: 6935
Registriert: Do 22. Mai 2003, 12:44
Wohnort: Berlin
Kontaktdaten:

Möglichkeit, den Standard-Client festzulegen

Beitrag von HerrB »

Diese Änderung sollte zum einen das Login beschleunigen und ermöglicht zum anderen, dass für einen Nutzer ein bestimmer Client als Standard-Client nach dem Login ausgewählt ist.

Ich würde mich über Tests und Feedback freuen, ob man das zum Einbau vorschlagen sollte.

Ersetzt wird die Funktion auth_loglogin in conlib/local.php.

Alter Code (aus V4.6.15-Beta):

Code: Alles auswählen

function auth_loglogin($uid)
  {
        global $cfg, $client, $lang, $auth, $sess, $saveLoginTime;
        
        $perm = new Contenido_Perm;
        
        $storeLoginTime = "true";
        $lastentry = $this->db->nextid($cfg["tab"]["actionlog"]);

        $timestamp = date("Y-m-d H:i:s");
        $idcatart = "0";

        /* Extract clients */
        $sql = "SELECT idclient FROM ".$cfg["tab"]["clients"]." ORDER BY idclient ASC";
        $this->db->query($sql);
        
        $clients = array();
        
        while ($this->db->next_record())
        {
        	array_push ($clients, $this->db->f("idclient"));
        }

		$found = 0;
		
		foreach ($clients as $key=>$value)
		{
			/* Extract languages */
	        $sql = "SELECT idlang FROM ".$cfg["tab"]["clients_lang"]." WHERE idclient = '".$value."' ORDER BY idlang";
	        $this->db->query($sql);
	        
	        while ($this->db->next_record())
	        {
		        $qlang = $this->db->f("idlang");  
	
				if ($found != 1)
				{
					$client = $value;
				}
				
	        	if ($perm->have_perm_client_lang($value, $qlang) && $found == 0)
	        	{
		        	$client = $value;
	        		$lang = $qlang;
	        		$found = 1;
	        	}
	        }
		}

        
        
        if (isset($idcat) && isset($idart))
        {
            $sql = "SELECT idcatart
                        FROM
                       ". $cfg["tab"]["cat_art"] ."
                    WHERE
                        idcat = $idcat AND
                        idart = $idart";
    
            $this->db->query($sql);
    
            $this->db->next_record();
            $idcatart = $this->db->f("idcatart");
    
        }
   
        if (!is_numeric($client)) { return; }
        if (!is_numeric($lang)) { return;  }

		$idaction = $perm->getIDForAction("login");
		
        $sql = "INSERT INTO
                    ". $cfg["tab"]["actionlog"]."
                SET
                    idlog = $lastentry,
                    user_id = '" . $uid . "',
                    idclient = $client,
                    idlang = $lang,
                    idaction = $idaction,
                    idcatart = $idcatart,
                    logtimestamp = '$timestamp'";
                    
        $this->db->query($sql);
        
        $sess->register("saveLoginTime");
        
        $saveLoginTime = true;
        
    }
Neuer Code:

Code: Alles auswählen

function auth_loglogin($uid)
  {
        global $cfg, $client, $lang, $auth, $sess, $saveLoginTime;
        
        $perm = new Contenido_Perm;
        
        $storeLoginTime = "true";
        $lastentry = $this->db->nextid($cfg["tab"]["actionlog"]);

        $timestamp = date("Y-m-d H:i:s");
        $idcatart = "0";

        /* Extract clients */
        $bFound = false;
        
        // Get user settings for default client
        $sql = "SELECT value FROM ".$cfg["tab"]["user_prop"]." WHERE type = 'backend' AND ".
        	   "name = 'default_idclient' AND user_id = '".$uid."'";
        $this->db->query($sql);
        
        if ($this->db->next_record())
        {
        	$iTmpClient = $this->db->f("value");
        	
        	if (is_numeric($iTmpClient))
        	{
	        	// Check, if current user have right to access a language of the client
	        	$sql = "SELECT tblClientLangs.idlang FROM ".
					   $cfg["tab"]["clients"]." AS tblClients, ".$cfg["tab"]["clients_lang"]." AS tblClientLangs ".
					   "WHERE tblClients.idclient = tblClientLangs.idclient AND tblClients.idclient = '".$iTmpClient."' ORDER BY idlang ASC";
	        	$this->db->query($sql);
	        	
				while ($this->db->next_record() && !$bFound)
				{
					$iTmpLang = $this->db->f("idlang");
					
					if ($perm->have_perm_client_lang($iTmpClient, $iTmpLang))
					{
						$client	= $iTmpClient;
						$lang	= $iTmpLang;
						$bFound = true;
					}
				}
        	}
        }
        
        if (!$bFound)
        {
        	// No default client specified for the user, find the first accessible client and language for the user
        	
			// All the needed information should be available in clients_lang - but the previous code was designed with a
			// reference to the clients table. Maybe fail-safe technology, who knows... 
        	$sql = "SELECT tblClientLangs.idclient, tblClientLangs.idlang FROM ".
        		   $cfg["tab"]["clients"]." AS tblClients, ".$cfg["tab"]["clients_lang"]." AS tblClientLangs ".
	        	   "WHERE tblClients.idclient = tblClientsLang.idclient ORDER BY idclient ASC, idlang ASC";
			$this->db->query($sql);
        	
        	while ($this->db->next_record() && !$bFound)
			{
				$iTmpClient	= $this->db->f("idclient");
				$iTmpLang	= $this->db->f("idlang");
				
				if ($perm->have_perm_client_lang($iTmpClient, $iTmpLang))
				{
					$client	= $iTmpClient;
					$lang	= $iTmpLang;
					$bFound = true;
				}
			}
		}
		
        if (isset($idcat) && isset($idart))
        {
            $sql = "SELECT idcatart
                        FROM
                       ". $cfg["tab"]["cat_art"] ."
                    WHERE
                        idcat = $idcat AND
                        idart = $idart";
    
            $this->db->query($sql);
    
            $this->db->next_record();
            $idcatart = $this->db->f("idcatart");
    
        }
   
        if (!is_numeric($client)) { return; }
        if (!is_numeric($lang)) { return;  }

		$idaction = $perm->getIDForAction("login");
		
        $sql = "INSERT INTO
                    ". $cfg["tab"]["actionlog"]."
                SET
                    idlog = $lastentry,
                    user_id = '" . $uid . "',
                    idclient = $client,
                    idlang = $lang,
                    idaction = $idaction,
                    idcatart = $idcatart,
                    logtimestamp = '$timestamp'";
                    
        $this->db->query($sql);
        
        $sess->register("saveLoginTime");
        
        $saveLoginTime = true;
	}
Die Nutzereinstellung (Administration -> Benutzer) lautet:
Area/Type: backend
Eigenschaft: default_idclient
Wert: ID des Standard-Clients

Haken: Aus Performance-Gründen wird nur die user_prop-Tabelle überprüft, Gruppen-Einstellungen werden ignoriert.

Gruß
HerrB
Bitte keine unaufgeforderten PMs oder E-Mails -> use da Forum!

Newsletter: V4.4.x | V4.6.0-15 (Module, Backend) | V4.6.22+
Standardartikelliste: V4.4.x | V4.6.x
http://www.contenido.org/forum/search.php | http://faq.contenido.org | http://www.communido.net
HerrB
Beiträge: 6935
Registriert: Do 22. Mai 2003, 12:44
Wohnort: Berlin
Kontaktdaten:

Beitrag von HerrB »

Cool, die Änderung hat den Bug wiederbelebt: http://www.contenido.org/forum/viewtopi ... 3486#13486

Tatsächlich war der Fix auch IMHO keiner:

Die have_perm_client_lang übergibt die Client-ID als Parameter:

Code: Alles auswählen

	function have_perm_client_lang($client, $lang)
	{
		return ($this->have_perm("client[$client],lang[$lang]"));

	}
Die have_perm prüft aber anhand des globalen $client, ob der Nutzer als Admin berechtigt ist:

Code: Alles auswählen

function have_perm($p = "x")
	{
		global $auth, $client;

		if (!isset ($auth->auth["perm"]))
		{
			$auth->auth["perm"] = "";
		}

		//split   the permissions of the user
		$userperm = split(",", $auth->auth["perm"]);

		//if User is sysadmin or admin at this client return true
		if (in_array("sysadmin", $userperm))
		{
			return true;
		}
		elseif (in_array("admin[$client]", $userperm))
		{
			return true;

			//else check rights for the client and the language
		} else ...
Ich wäre dafür, die have_perm_client_lang zu einer echten Funktion zu machen (das Setzen der globalen $client finde ich gerade nicht so prickelnd, schließlich ist die Funktion einfach fehlerhaft):

Code: Alles auswählen

function have_perm_client_lang($client, $lang)
	{		
		global $auth;

		if (!isset($auth->auth["perm"]))
		{
			$auth->auth["perm"] = "";
		}

		// Split the permissions of the user
		$userperm = split(",", $auth->auth["perm"]);

		if (in_array("sysadmin", $userperm))
		{
			return true; // User is sysadmin
		} elseif (in_array("admin[$client]", $userperm))
		{
			return true; // User is admin
		} else
		{
			// Check rights for the client and the language
			$pageperm = split(",", "client[$client],lang[$lang]");
			foreach ($pageperm as $value)
			{
				if (!in_array($value, $userperm))
				{
					return false;
				}
			}
		}
		return true;
	}
Feedback appreciated...

Gruß
HerrB
Bitte keine unaufgeforderten PMs oder E-Mails -> use da Forum!

Newsletter: V4.4.x | V4.6.0-15 (Module, Backend) | V4.6.22+
Standardartikelliste: V4.4.x | V4.6.x
http://www.contenido.org/forum/search.php | http://faq.contenido.org | http://www.communido.net
emergence
Beiträge: 10653
Registriert: Mo 28. Jul 2003, 12:49
Wohnort: Austria
Kontaktdaten:

Beitrag von emergence »

hmm...

hab mir den code jetzt nicht so genau angesehen... wie beschleunigt ?

ich hätte da ne andere lösung für das selbe feature (vorselektion des client)..

änderungen in der conlib/local.php oder in perm.inc sind dazu nicht notwendig... hab ich mal für einen kunden implementiert...

contenido/index.php

nach

Code: Alles auswählen

// change Client
if (isset($changeclient) && is_numeric($changeclient)){
     $client = $changeclient;
     unset($lang);
}
folgendes hinzufügen

Code: Alles auswählen

// Preselect client if definied
if (!$sess->is_registered("client")) { // only check at first login into backend
    $_client = getEffectiveSetting ("backend", "prefered_client", false);

    if ($_client && ($perm->have_perm_client("admin[".$_client."]") || $perm->have_perm_client("client[".$_client."]"))) {
		$client = $_client;
		unset($lang);
    }
    unset($_client);
}
die definition sieht etwas anders aus...

backend prefered_client CLIENTID

noch was zur ersten methode

die zeile

Code: Alles auswählen

$storeLoginTime = "true";
kann entfernt werden...
*** make your own tools (wishlist :: thx)
HerrB
Beiträge: 6935
Registriert: Do 22. Mai 2003, 12:44
Wohnort: Berlin
Kontaktdaten:

Beitrag von HerrB »

hab mir den code jetzt nicht so genau angesehen... wie beschleunigt ?
Der alte Code lädt mit einer Abfrage erstmal alle Clients in einen Array, geht dann das Array durch und lädt für jede Client-ID alle Sprachen dieses Clients. Für jede Client-ID/Sprach-ID wird geprüft, ob eine Berechtigung besteht - jedoch werden die Schleifen nicht agebrochen, wenn die erste zulässsige Client/Sprach-Kombination gefunden wurde (d.h. bei vielen Clients und Sprachen kostet das Zeit für das Login).

Der neue Code lädt alle Client/Sprach-Kombinationen mit einer Abfrage und hört auf, wenn die erste zulässige gefunden wurde.

Der Vorschlag hört sich gut an (ich hatte aus Performance-Gründen auf getEffectiveSetting verzichtet) - ich werde Deine Lösung für das Preferred nehmen, aber trotzdem die Korrekturen durchführen (die alte have_perm_client_lang funktioniert für admins definitiv nicht, wenn ein Client überprüft wird, der nicht dem aktuellen Client entspricht).

Mein Problem war, das $client hinter Change Client bereits definiert ist (eben aus der local.php), aber offensichtlich noch nicht in der Session registriert - thats a trick.

Wird dann getEffectiveSetting ("backend", "preferred_idclient", false); ... :wink:

Danke.

Gruß
HerrB
Bitte keine unaufgeforderten PMs oder E-Mails -> use da Forum!

Newsletter: V4.4.x | V4.6.0-15 (Module, Backend) | V4.6.22+
Standardartikelliste: V4.4.x | V4.6.x
http://www.contenido.org/forum/search.php | http://faq.contenido.org | http://www.communido.net
emergence
Beiträge: 10653
Registriert: Mo 28. Jul 2003, 12:49
Wohnort: Austria
Kontaktdaten:

Beitrag von emergence »

preferred_idclient klingt gut... ;-)

die andere sache mit have_perm_client_lang kann ich mir momentan aus zeitgründen nicht ansehen...
*** make your own tools (wishlist :: thx)
emergence
Beiträge: 10653
Registriert: Mo 28. Jul 2003, 12:49
Wohnort: Austria
Kontaktdaten:

Beitrag von emergence »

hab jetzt doch kurz nachgesehen

alter code

Code: Alles auswählen

   function have_perm_client_lang($client, $lang) 
   { 
      return ($this->have_perm("client[$client],lang[$lang]")); 

   }
neuer code

Code: Alles auswählen

	function have_perm_client_lang($client, $lang) {
		return ($this->have_perm("client[$client],lang[$lang]") || $this->have_perm_client("admin[$client]")) ? true : false;
	}
sollte ohne weiteres den selben job erledigen...
Zuletzt geändert von emergence am Fr 27. Okt 2006, 15:38, insgesamt 1-mal geändert.
*** make your own tools (wishlist :: thx)
HerrB
Beiträge: 6935
Registriert: Do 22. Mai 2003, 12:44
Wohnort: Berlin
Kontaktdaten:

Beitrag von HerrB »

local.php:

Code: Alles auswählen

function auth_loglogin($uid)
  {
        global $cfg, $client, $lang, $auth, $sess, $saveLoginTime;
        
        $perm = new Contenido_Perm;
        
        $timestamp	= date("Y-m-d H:i:s");
        $idcatart	= "0";

    	/* Find the first accessible client and language for the user */
    	$sql = "SELECT tblClientLangs.idclient, tblClientLangs.idlang FROM ".
    		   $cfg["tab"]["clients"]." AS tblClients, ".$cfg["tab"]["clients_lang"]." AS tblClientLangs ".
        	   "WHERE tblClients.idclient = tblClientsLang.idclient ORDER BY idclient ASC, idlang ASC";
		$this->db->query($sql);
    	
    	$bFound = false;
    	while ($this->db->next_record() && !$bFound)
		{
			$iTmpClient	= $this->db->f("idclient");
			$iTmpLang	= $this->db->f("idlang");
			
			if ($perm->have_perm_client_lang($iTmpClient, $iTmpLang))
			{
				$client	= $iTmpClient;
				$lang	= $iTmpLang;
				$bFound = true;
			}
		}
		
        if (isset($idcat) && isset($idart))
        {
            $sql = "SELECT idcatart
                    FROM
                       ". $cfg["tab"]["cat_art"] ."
                    WHERE
                        idcat = $idcat AND
                        idart = $idart";
    
            $this->db->query($sql);
    
            $this->db->next_record();
            $idcatart = $this->db->f("idcatart");
        }
   
        if (!is_numeric($client)) { return; }
        if (!is_numeric($lang)) { return;  }

		$idaction	= $perm->getIDForAction("login");
		$lastentry	= $this->db->nextid($cfg["tab"]["actionlog"]);
		
        $sql = "INSERT INTO
                    ". $cfg["tab"]["actionlog"]."
                SET
                    idlog = $lastentry,
                    user_id = '" . $uid . "',
                    idclient = $client,
                    idlang = $lang,
                    idaction = $idaction,
                    idcatart = $idcatart,
                    logtimestamp = '$timestamp'";
                    
        $this->db->query($sql);
        
        $sess->register("saveLoginTime");
        
        $saveLoginTime = true;
	}
Änderung in index.php wie angegeben. Die getEffectiveSetting neutralisiert natürlich den Peformance-Gewinn, nun ja.

Aus dieser Sicht wäre die Integration in der local.php vermutlich besser (wenn der Nutzer für eine Sprache des angegebenen Clients bereits berechtigt ist, muss nicht noch die erste gültige Kombination gesucht werden - so wird immer erst gesucht [local.php] und dann die gefundene Kombination übersteuert, um dann nochmal die erste gültige Sprache zu finden [index.php]), aber ich denke, aus Sicherheitsgründen und da zu dem sehr frühen Zeitpunkt der local.php vermutlich nicht alle Objekte zur Verfügung stehen, lasse ich das mal schön bleiben... :wink:

Gruß
HerrB
Bitte keine unaufgeforderten PMs oder E-Mails -> use da Forum!

Newsletter: V4.4.x | V4.6.0-15 (Module, Backend) | V4.6.22+
Standardartikelliste: V4.4.x | V4.6.x
http://www.contenido.org/forum/search.php | http://faq.contenido.org | http://www.communido.net
emergence
Beiträge: 10653
Registriert: Mo 28. Jul 2003, 12:49
Wohnort: Austria
Kontaktdaten:

Beitrag von emergence »

ähm da gibts nen bug

[29-Sep-2006 14:14:52] /contenido/index.php?contenido=ebc89ec5fb56ffd09571b20e50983c8c MySQL error 1109: Unknown table 'tblClientsLang' in where clause
SELECT tblClientLangs.idclient, tblClientLangs.idlang FROM con_clients AS tblClients, con_clients_lang AS tblClientLangs WHERE tblClients.idclient = tblClientsLang.idclient ORDER BY idclient ASC, idlang ASC
*** make your own tools (wishlist :: thx)
HerrB
Beiträge: 6935
Registriert: Do 22. Mai 2003, 12:44
Wohnort: Berlin
Kontaktdaten:

Beitrag von HerrB »

Ok, werde ich heute abend fixen (s an der falschen Stelle).

Gruß
HerrB
Bitte keine unaufgeforderten PMs oder E-Mails -> use da Forum!

Newsletter: V4.4.x | V4.6.0-15 (Module, Backend) | V4.6.22+
Standardartikelliste: V4.4.x | V4.6.x
http://www.contenido.org/forum/search.php | http://faq.contenido.org | http://www.communido.net
Antworten