Vlastní autorizátor má problém s pohledem (MySQL View)

theacastus
Člen | 81
+
0
-

Zdravím,

jak již nadpis napovídá, musím tahat místo z tabulky s primárním klíčem z pohledu, kde mám přes union spojené 2 tabulky a každá má vlastní id (primary key).

V tuto chvíli to vypadá takto:

tabulka A:
id | username | password

tabulka B:
id | username | password

VIEW:
SELECT id,username,password from tabulkaA UNION SELECT id,username,password FROM tabulkaB

Kvůli unionu nejde mít přímo ke každému uživateli roli, (protože každá tabulka se stará o něco jiného a stavět aplikaci na základu z roku 2008… – nemůžu to přepsat, protože je na to pozdě a DDM to nezaplatí, nemaj na to…)

Takže když Authenticator sáhne do pohledu, nenajde primární klíč a má problém při vytvoření identity…

I když mám všude vyjímky, nic mi nikde nevyhodí, \Tracy\Debugger::dump taky nepomohl.

To že hesla jsou v MD5 pro zaměstnance a pro karty vůbec je jen sladká tečka navrh… neomluvě o současné databázi v MySQL 5.2 a PHP 5.3…

Jsem z toho na prášky, jsem student co do DDM chodí 7 let, poslední rok jsem tu učil informatiku a protože prázdniny nejsou nekončený i když maturitní tak jsem nechtěl dělat kompletně celý web… a teď na to doplácím.

Nevím si s tím rady, celý den tu nad tím visím… zkouším upravovat DB i kód a nic.

Prosím pomoc, díky každému.

Odkaz na gist: https://gist.github.com/…ef022cbf467e

Jsem rád za každou radu…

CZechBoY
Člen | 3608
+
0
-

Jakou mas verzi Nette a jakou presne chybu ti to hazi?

theacastus
Člen | 81
+
0
-

Nette 2.4, vše testuju v PHP 7.0 a MySQL 5.6 – to co jsem psal o 5.2 a 5.3 je na produkčním serveru.

Chybu mi to nehází, dám odeslat formulář, proběhne vše ok. Ale žádný redirect, žádný flash message ani tracy debug. A debug panel nic nepíše

David Matějka
Moderator | 6445
+
0
-

a kam az se to dostane? do signInFormSucceeded? nekam dal?

theacastus
Člen | 81
+
0
-

David Matějka napsal(a):

a kam az se to dostane? do signInFormSucceeded? nekam dal?

To právě nevím, nikde mi totiž autentizace neumře v chybě (tracy nic nezachytí) a ani žádný error flash message který tam je nevyskočí.

Teď jdu spát, ráno uvidím co půjde – odpočatý mozek si s tím poradí lépe :D

David Matějka
Moderator | 6445
+
0
-

tak si tam dej aspon nejake echo 1;exit;

theacastus
Člen | 81
+
0
-

Dal jsem si tam log do tracy, zkusil jsem flashMessage – jdu na echo

Podle SQL dotazá v Authenticatoru jsem zjistil že to dojde až k vrácení identity, ale myslím že pak s tím je nějaký problém asi

Jen teda pokud tu novou identitu co si vracím z authenticate() nemám setnout někam do DI. Nikde jsem to nešnašel…

Tím myslím něco jako:

$user = $this->getUser();

try {
	$identity = $this->auth->authenticate([$username,$password]);
} catch (Nette\Security\AuthenticationException $e) {
	//something
}

$user->setIdentity($identity);

Editoval theacastus (27. 6. 2017 9:05)

theacastus
Člen | 81
+
0
-

Tak dojede mi to až k signInFormSucceeded(UI\Form $form) v komponentě, kde to projde ifem – přihlášení prošlo.

Jak tak na to koukám, asi si přepisuju onSuccess a onFormSuccess – dělá to to samé, jen když to je v komponentě, je to lepší protože nemusím psát co se stane v každém presenteru kde komponentu použiju. Ale nevím jestli je to tím

CZechBoY
Člen | 3608
+
0
-

Použij $user->login($identity), je tam menší rozdíl v tom, že se uživatel nastaví jako autentizovaný.

theacastus
Člen | 81
+
0
-

Jak předám (spíš kde), Nette\Security\User authenticator ?

Mělo by to stačit v configu ne ?

services:
	authenticator: App\Model\Authenticator
theacastus
Člen | 81
+
0
-

Tak když jsem si místo authenticátoru začal předávat Usera (do komponenty) a přepsal authenticate() na login(), vše běží jak má :)

Jen je problém, když login proběhne úspěšně, provede se redirect, ale nezobrazí se flash message že přihlášení proběhlo úspěšně. Je to sice detail, ale chci to mít hotové a odškrtnout to… :D

Fakt se k tomu vracet nechci :D

jiri.pudil
Nette Blogger | 1028
+
0
-

Jen je problém, když login proběhne úspěšně, provede se redirect, ale nezobrazí se flash message že přihlášení proběhlo úspěšně.

A vypisuješ někde v cílové šabloně ty flash message? :)

theacastus
Člen | 81
+
0
-

Flash message se vypisuje přes @layout.latte

<!DOCTYPE html>
<html>
<html lang="cs">
<head>
  <!-- Required meta tags -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  <!-- Twitter Bootstrap v4-alpha6 -->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
  <script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>

  <!-- Animate.css -->
  <link rel="stylesheet" href="/assets/css/animate.css">

  <!-- Font Awesome 4.7.0 -->
  <link rel="stylesheet" href="/assets/css/font-awesome.min.css">

  <!-- Custom CSS -->
  <link rel="stylesheet" href="/assets/css/@layout.css?v=0.1">
  <link rel="stylesheet" href="/assets/css/custom.css?v=0.1">

  <!-- Custom JS -->
  <script src="/assets/js/@main.js?v=1.1"></script>

  <title>{ifset title}{include title|stripHtml} | {/ifset}DDM Horní Počernice</title>

</head>

<body>
  <nav class="navbar navbar-toggleable-md navbar-light bg-white fixed-top animated" id="navbar" style="background-color: rgba(0,0,0,0.5)">
    <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarCollapsedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="container">
      <a class="navbar-brand nav-logo" n:href="Posts:">
        <img src="/assets/images/logo.png" alt="DDM-HP Logo">
      </a>

      <div class="collapse navbar-collapse" id="navbarCollapsedContent">
        <ul class="navbar-nav mr-auto intra-link">
          <li class="nav-item m-auto {ifCurrent Posts:*}active{/ifCurrent}">
            <a class="nav-link" n:href="Posts:">NOVINKY</span></a>
          </li>
          <li class="nav-item m-auto {ifCurrent Course:*}active{/ifCurrent}">
            <a class="nav-link" n:href="Course:">KROUŽKY</span></a>
          </li>
          <li class="nav-item m-auto {ifCurrent Workshops:*}active{/ifCurrent}">
            <a class="nav-link" n:href="Workshops:">DÍLNIČKY</a>
          </li>
          <li class="nav-item m-auto {ifCurrent Camp:*}active{/ifCurrent}">
            <a class="nav-link" n:href="Camp:">TÁBORY</a>
          </li>
          <li class="nav-item m-auto {ifCurrent Gallery:*}active{/ifCurrent}">
            <a class="nav-link" n:href="Gallery:">GALERIE</a>
          </li>
          <li class="nav-item m-auto {ifCurrent About:*}active{/ifCurrent}">
            <a class="nav-link" n:href="About:">INFORMACE</a>
          </li>
        </ul>
        <ul class="navbar-nav ml-auto">
          <li class="nav-item">
            <a class="nav-link" href="https://www.facebook.com/ddmhp/" target="_blank">
                  <span class="fa-stack">
                    <i class="fa fa-circle fa-stack-2x text-primary"></i>
                    <i class="fa fa-facebook fa-stack-1x text-white"></i>
                  </span>
            </a>
          </li>
        </ul>
      </div>
    </div>
  </nav>
  {snippet flashes}
    <div class="container flash">
        {foreach $flashes as $flash}
          <div class="card card-inverse card-{$flash->type} mb3 text-center">
            <div class="flash-block">
              <p class="card-text text-white">
                  {switch $flash->type}
                      {case success}
                    <i class="fa fa-check" aria-hidden="true"></i>

                  {case danger}
                    <i class="fa fa-times" aria-hidden="true"></i>

                  {case warning}
                    <i class="fa fa-exclamation-triangle" aria-hidden="true"></i>

                  {case info}
                    <i class="fa fa-info" aria-hidden="true"></i>

                  {/switch}
                  {$flash->message}
              </p>
            </div>
          </div>
            {if count($flashes) > 1}
              <div class="flash-spacing"></div>
            {/if}
        {/foreach}
    </div>
  {/snippet}
  <div class="wrap">
      {include content}
  </div>

  <footer class="bg-white">
      <div class="container">
          <h5 class="d-flex justify-content-center align-items-center">Copyright &copy; Dům dětí a mládeže Horní Počernice, Praha 20</h5>
            <p class="d-flex justify-content-center align-items-center text-muted m-auto">Všechna práva vyhrazena.</p>
            <br>
      </div>
  </footer>
  <div class="scrollToTop animated invisible" onclick="scrollToTop()">
    <button role="button" class="btn btn-ddm-g" id="goTop" title="Zpět nahoru"><i class="fa fa-arrow-up fa-2x" aria-hidden="true"></i></button>
  </div>
  <script src="https://nette.github.io/resources/js/netteForms.min.js"></script>
  <script src="/assets/js/ajaxRequest.js"></script>
  <script>
      $(function () {
          $.nette.init();
      });
  </script>
  {ifset scripts}{include scripts}{/ifset}
</body>
</html>
CZechBoY
Člen | 3608
+
0
-

Nedáváš flashky do šablony komponenty?
btw. ještě jedna věc se mi nelíbí a to, že sice používáš továrnu na komponentu, ale stejně přes create metodu předáváš nějaký závislosti. Co se toho zbavit a mít create metodu bez parametrů?

class SignInForm extends UI\Control
{
    public function __construct(\App\Model\Authenticator $authenticator)
interface ISignInFormFactory
{
    /**
     * @return SignInForm
     */
    public function create();
}
theacastus
Člen | 81
+
0
-

Tak vím proč se to děje,

v komponentě mám:

public function createComponentSignInForm()
    {
        $form = new UI\Form;

        $form->addText('username','Přijímení a jméno')
            ->setRequired('Zadejte prosím přijímení a jméno')
            ->setAttribute('required')
            ->setAttribute('placeholder', 'Novák Jan');

        $form->addPassword('password','Heslo')
            ->setRequired('Zadejte prosím vaše heslo')
            ->setAttribute('required');;

        $form->addSubmit('submit','Přihlásit se');

        $form->onSuccess[] = [$this, 'signInFormSucceeded'];

        return $form;
    }

    public function signInFormSucceeded(UI\Form $form)
    {
        $values = $form->getValues();

        try {

            $this->user->login($values['username'], $values['password']);

        } catch (Exception $exception) {
            $this->flashMessage("Špatné příjmení a jméno nebo heslo.", "danger");
        }
    }

Takže request skončí tady a v presenteru do:

public function createComponentSignInForm()
    {
        $form = $this->SignInFormFactory->create($this->user);

        $form->onSuccess[] = function ()
        {
            echo 1;

            $this->flashMessage("Přihlášení proběhlo úspěšně", "success");
            $this->redirect('this');

            /*
            if ($this->isAjax())
            {
                global $form;
                $this->redrawControl('SignInForm');
                $form->setValues([], TRUE);
            }
            else
            {
                $this->redirect('Posts:');
            }
            */
        };

        return $form;
    }

už to nedojde, co s tím ? jak z toho ven? Dalo by se to dá do komponenty do signInFormSucceeded, ale když tam dám redirect dělá to bordel a nevím jak to opravit, nebo použít v redirectu místo cesty přes presentery absolutní cestu (místo ‚Homepage:default‘, ‚/‘)?

jiri.pudil
Nette Blogger | 1028
+
0
-

Ten $form v presenteru ale není formulář, nýbrž SignInForm, který ten formulář obaluje, takže potřebuješ navěsit ten handler ještě o jednu úroveň hlouběji:

$form['signInForm']->onSuccess[] = function () {};
CZechBoY
Člen | 3608
+
0
-

btw toho uživatele si taky nemusíš předávat :-) všechno zařídí DI :-)

theacastus
Člen | 81
+
0
-

CZechBoY napsal(a):

btw toho uživatele si taky nemusíš předávat :-) všechno zařídí DI :-)

Ok, super – díky :-)

jiri.pudil napsal(a):

Ten $form v presenteru ale není formulář, nýbrž SignInForm, který ten formulář obaluje, takže potřebuješ navěsit ten handler ještě o jednu úroveň hlouběji:

$form['signInForm']->onSuccess[] = function () {};

Paráda, funguje to jak má!!! Díky moc!

Editoval theacastus (27. 6. 2017 20:54)