Nette\Security\Identity doplneni hodnot k registraci uzivatele

vlkodlak
Člen | 160
+
0
-

Zdravím, narazil jsem, pro mně zapeklitý, problém.

Používám standartní knihovnu pro přihlášení uživatele doplněno o vyhledaní uživatele v LDAP adresáři, ale nedaří se mi doplnit o údaje k registraci uživatele, které bych rád požil později

<?php

declare(strict_types=1);

namespace App\Model;

use Nette;
use Nette\Application\UI\Form;
use Nette\Security\Passwords;

/**
 * Users management.
 */
final class UserManager implements Nette\Security\IAuthenticator
{

   use Nette\SmartObject;

   /** web config file */
   private $webparam = array();

   public function __construct($param = array())
   {
      $this->webparam = $param;
   }

   /**
    * Performs an authentication.
    * @throws Nette\Security\AuthenticationException
    */
   public function authenticate(array $credentials): Nette\Security\IIdentity
   {
      [$username, $password] = $credentials;

      if ($this->authUserAD($username, $password, $this->webparam['ldap']['ldap_server'], $this->webparam['ldap']['ldap_server']))
      {
		 $arr = array('LDAP' => 'overeny', 'number' => '123456789');


      unset($arr[self::COLUMN_PASSWORD_HASH]);
      return new Nette\Security\Identity($username, 'user', $arr);
   }

   function authUserAD($username, $password, $ldap_server = "ldap://192.168.0.1")
   {
	 .... zde provedu dohledani uživatele v LDAP ...
   }
}

po provedeni se mi správně vytvoří přihlášeny uživatel

Nette\Security\Identity
id private => "vladimir"
roles private => array
	0 => "user"
data private => array
	LDAP => "overeny"
	number => "123456789"

a potřeboval bych rozšířit data privat o další hodnoty, ale narážím na následující:

  1. u Nette\Security\Identity mohu jen getovat … což na jednu stranu chápu jako bezpečnost, ale jinou možnost jsem nenašel
  2. když se pokusím injektovat knihovnu, která umí dohledat potřebné informace
/** @var \App\Model\MyHash @inject */
public $myhash;

a následně provedu například inicializaci pomoci pole

$myhash-> init ( array(....));

tak mi to zahlásí „Call to a member function init() on null“, přičemž v HomePresenteru stejný zápis s inicializaci funguje

3. pokud „odhodlaně“ registruji ručně knihovnu, aby mi dohledala doplňující data k uživateli dřív než registrují uživatele pomoci

new Nette\Security\Identity($username, 'user', $arr);

pomoci přikážu NEW

...
$arr = array('LDAP' => 'overeny', 'number' => '123456789');
...
  $this->myhash = new myhash( array('hodnota1'=>'1', 'hodnota2'=>'2') );
...
unset($arr[self::COLUMN_PASSWORD_HASH]);
...

tak mi zas při použiti předané hodnoty1 v knihovně napíše Undefined array key „hodnoty1“

a co mě mate v tomto případě nejvíc pokud v knihovně myhash nechám vypsat

bdump(hodnota1);
...
nebo
...
dump(hodnota1);

tak jí vypíše správně

Editoval vlkodlak (2. 4. 2021 12:10)

Ondřej Kubíček
Člen | 494
+
+2
-

ad 2) @inject je by default povolen jen v presenterech, když se ti vyhodí chyby volání init na null, tak je snad jasný, že ta proměnná je null, protože se ti nevytvořila instance. Měl by sis tu třídu předávat přes constructor. @inject se dá povolit v services.neon

Marek Bartoš
Nette Blogger | 1171
+
+2
-

Identitu si můžeš naimplementovat sám, jesliže ji chceš měnit. Stačí implementovat interface IIdentity. Dá se však obejít i bez toho, cokoli krom id uživatele a rolí můžeš ukládat jinam a získávat na základě id uživatele.

Inject funguje by-default jen v presenterech a pro jiné třídy je potřeba jej povolit, jak zmínil @OndřejKubíček. Je lepší však volit konstruktor, jelikož je inject specifický pro nette/di a o DI by třída neměla nic vědět. Výjimkou jsou presentery kvůli čistě praktickému hledisku – abstraktní base presenter má závislostí příliš a tak by přetěžování konstruktoru bylo moc ukecané.
V případě tříd vytvářených přes new však DI nefunguje vůbec, ani přes konstruktor. Třídu vytváříš ty, ne container, a tak do ní nemůže předat závislosti.

vlkodlak
Člen | 160
+
0
-

pánové @Mabar, @OndřejKubíček děkuji za tipy, nakonec jsem to vyřešil třetím způsobem v kroku ověřování, byť rozumím, že to možná není zcela podle DI