Italian community of Lazarus and Free Pascal

Programmazione => Generale => Topic aperto da: giacomarko - Dicembre 21, 2024, 04:56:24 pm

Titolo: [RISOLTO] Utilizzo form di utilità generica, in programmi DB oriented, diversi
Inserito da: giacomarko - Dicembre 21, 2024, 04:56:24 pm
Pongo un quesito che che di per se non è un vero problema (e per alcuni potrà anche sembrare stupido), in quanto non ho problemi di funzionamento in nessuna delle due soluzioni che ho sperimentato,

ma sono curioso ci capire quale possa essere il miglior approccio, e perchè,

mi spiego meglio;

Partiamo da una applicazione standard (non ha importanza di cosa si occupi), chiaramente utilizza una serie di Form dedicate a gestire i dati, immaginiamo la classica applicazione clienti, fornitori, commessse ... quindi una serie di Form costruiti ad hoc, e tutti residenti nella stessa cartella (o un'altra) ma dedicati a questa applicazione, niente di strano,

Immaginiamo anche che sia necessario una dialog di login, bene, quest'ultima potrebbe essere anche lei dedicata all'applicazione, quindi con i dati di accesso inseriti direttamente nel componente, o come sono solito fare a runtime o in una unit Init che sia negli Uses,

però è anche vero che, meno di particolari casi che non mi ne vengono in mente, si potrebbe pensare di tenerla in una cartella Utilities e usarla (sempre la stessa) per più programmi, e questa è la soluzione che credo sia la più corretta, o almeno io faccio così,

quindi si può dire che se il processo di check del login, è comune a tutte le applicazioni, certamente non lo è il DB utilizzato, la posizione ...

spero fin quì di essere stato sufficientemente chiaro, ora viene il quesito:

dato che l'oggetto/form TLogin non può contenere i dati di accesso al DB, perchè cambiano a seconda del programma che lo chiama, vedo due possibili soluzioni (probabilmente non ci vedo bene ;-)

a. inizializzo dal programma principale una connessione ad DB, la passo come parametro all'oggetto che la usa per il check di cui sopra, mi restituisce il risultato ( ok puoi entrare, oppure no) e poi distruggo la connessione,
es:

Codice: [Seleziona]
  
....
try
    try
      // Create DB connection ...
      dbConn:= TZConnection.Create(self);
      // with relevant DB parameters inside function, tests and returns connection data   
      dbConn:= GetUserDBConnection;         
      // call Login form ...
      LogIn:= TLogIn.Create(Application);
      LogIn.SetDBConnection( dbConn);         // Provide connection to Login Dialog
      LogIn.ShowModal;
     // assign User data to global var
      if LogIn.GetLoginResult then LogIn.GetLoginInfo(USER_KEY, USER_NAME, USER_FULL, USER_PASS, USER_PROF);

      // handle generic error !
    except
      on E: Exception do MessageDlg( 'There was an error: ' + E.Message, mtError, [mbOK], 0);
    end;
  finally
    LogIn.Free;
    dbConn.Free;
  end;

b. al posto di passare un oggetto TZConnection come parametro al metodo SetDBConnection, potrei modificarlo e passare i parametri Protocol e Database necessari, affinche la connessione venga inizializzata all'interno dell'oggetto TLogin stesso.
non ho un codice da postare per questo esempio (io utilizzo il primo), ma non è difficile immaginarlo.

ora, personalmente non vedo una grande differenza tra le due soluzioni, passare un oggetto già inizializato come parametro, oppure passare dei parametri affinchè questo avvenga inizializzato da un'altra parte ... cosa cambia ?  :-\

appunto vi chiedo:
.. cambia qualche cosa ?
.. e dal punto formale quale soluzione sarebbe la più "corretta" ?
.. oppure esiste un'altra soluzione che lo sarebbe ancora di più

scusate il post "fiume"  :)

M
Titolo: Re:Utilizzo di form di utilità generica, in programmi DB oriented, diversi
Inserito da: DragoRosso - Dicembre 21, 2024, 07:01:38 pm
L'approccio varia a seconda di cosa stai usando e come lo stai o lo vuoi usare.

Il login, di qualunque tipologia o complessità stiamo parlando, solitamente viene usato per accreditarsi presso un servizio.

In questo caso tu in realtà hai due servizi:

1) Il programma,

2) Il Database.

Se i dati di login li tieni nel database, o come dati di qualche tabella tipo "USER" o come  integrato il livello di login del server (tipo SQL Server), comunque dovresti presentarli prima dell'accesso alla tabella.

Quindi, concettualmente, prima presenti la Form  di login, poi con i dati verifichi la connessione e/o la tua tabella user. Questo lo puoi fare come modulo comune (tipo unità ULogin.pas) a cui passi i dati del database (tipo, login , etc ...) e da li effettui la connessione e la verifica.

Ovviamente ciò presuppone che costruisci tu in toto i tuoi applicativi con i DB progettati da te, altrimenti le varianti sono almeno un milione.

Dalla form di Login, poi chiudi la connessione e continui con il tuo programma.

Altri modi ce ne sono, ma dipende cosa devi fare e che dati tratti.

Io ad esempio tratto normalmente dati industriali, dove non ci sono problemi particolari di sicurezza e quindi il motore DB non ha una password di accesso (o ne ha una standard). All'interno c'è una tabella "Utenti" con i dati cripati con un chiper (chiave simmetrica).

Io all'inizio dell'applicazione accedo al DB e lego gli utenti e poi presento un login standard comparando i dati in memoria (attenzione che questo modo non và bene se ci sono dati legati alla privacy).
Per quello che riguarda la sicurezza (mantenimento in memoria degli user), tengo sempre i dati cripati e li decripto sono alla momento della verifica del login, azzerando poi la memoria in modo che una scansione della memoria del programma non consenta di rilevare i dati in chiaro.

Livello basso di sicurezza ma per le mie attività và bene così.

Titolo: Re:Utilizzo di form di utilità generica, in programmi DB oriented, diversi
Inserito da: giacomarko - Dicembre 21, 2024, 11:59:32 pm
In effetti è come dici,

appena l'utente lancia il programma, il login è la prima dialog che gli si presenta, questo immette user e psw e se tutto ok, la dialog si chiude e si apre il programma,

dato che vorrei mantenere la dialog di login come utilità generale, ho la necessità di tenerla "staccata" dal DB, e come DB intendo le varie connessioni e tutto quello che segue, ma devo fare in modo in qualche modo di passargliele, di volta in volta a seconda del programma che vado a compilare

La mia domanda era più formale, intensa come più "elegante" come metodo di programmazione, ma mi rendo conto che non sono stato chiaro,

volendo mantenere la login più astratta possibile, pensi sia meglio istanziare da programma una connessione al DB e passarla alla dialog di login come parametro, e al ritorno chiuderla da programma principale

oppure passare come parametri tutte le info per collegarsi al DB alla dialog, lasciare che sia la dialog a inizializzare una connection e poi fargliela chiudere prima di ritornale il risultato del login al programma principale ?

Entrambe le possibilità funzionano, già verificato, diciamo che era solo una cosa "estetica"

M
Titolo: Re:Utilizzo di form di utilità generica, in programmi DB oriented, diversi
Inserito da: DragoRosso - Dicembre 23, 2024, 11:07:11 am
La mia domanda era più formale, intensa come più "elegante" come metodo di programmazione, ma mi rendo conto che non sono stato chiaro,
volendo mantenere la login più astratta possibile, pensi sia meglio istanziare da programma una connessione al DB e passarla alla dialog di login come parametro, e al ritorno chiuderla da programma principale
oppure passare come parametri tutte le info per collegarsi al DB alla dialog, lasciare che sia la dialog a inizializzare una connection e poi fargliela chiudere prima di ritornale il risultato del login al programma principale ?
Entrambe le possibilità funzionano, già verificato, diciamo che era solo una cosa "estetica"

Non è tanto un problema di "STILE", ma un problema funzionale e di quanta complessità vuoi caricare il tuo "LOGIN".

1) La tua applicazione deve partire comunque con una Form, che tendenzialmente è la tua Form principale che una volta istanziata rimane "li" per tutta l'esistenza del programma;

2) Il Login è un finestra diciamo aggiuntiva, a cui si può dare o meno capacità autonoma. Però per dare capacità autonoma devi decidere cosa devi fare con questa "finestra aggiuntiva";

3) Se il Login è una finestra autonoma condivisa con più applicazioni devi dotarla di interfacce (tendenzialmente metodi) che ti consentano di svolgere in maniera autonoma tutte le attività necessarie. Ciò molte volte vuol dire replicare (e quindi puoi mantenere) codice già presente nel tuo applicativo.

Detto ciò, io tendenzialmente sarei più propenso ad avere una finestra di login che usi dei riferimenti passati dal programma principale (ad esempio la ZConnection già impostata) e poi vada tentare di validare la connessione (nel caso generale di RDBMS) con username e password immesse dall'operatore.
Una volta avviata la connessione dal Login, questa semplicemente rimane attiva. Se per qualche motivo "cade", si effettua di nuovo la procedura di Login.

Se i dati username e password sono mantenuti in una tabella (ad esempio per DB più semplici come SQLite) e non sono relativi alla connessione, il LOGIN farà semplicemente accesso a quella tabella e validerà i dati, "troncando" la connessione con il DB nel caso non siano verificati. Quindi ti riporti allo stesso "funzionamento" del caso precedente.

Questo è un metodo generico che và bene per i DB standard gestiti da ZEOS. Se andiamo invece a connessioni più complesse con Active Directory o Azure o AWS o ..... allora le cose sono "leggermente" diverse, e quindi dovresti ripensare alla logica.

Ciao
Titolo: [RISOLTO] Utilizzo form di utilità generica, in programmi DB oriented, diversi
Inserito da: giacomarko - Dicembre 23, 2024, 08:12:37 pm
Perfetto !! allora è già così,  :)

.. l'applicazione principale si apre, ma mostra solamente il logo dell'azienda,
.. dopo qualche secondo, l'applicazione inizializza il form di Login e gli passa una TZConnection, che punta ad un DB che contiene una sola tabella USER,
.. in questo form c'è il codice per il check delle credenziali, che può essere, ed è, comune ad altre applicazioni (cambiano solo i parametri della TZConnection), effettua il controllo (incluso il cambio password se scaduta)
.. se tutto passa (utente e password), il form login si chiude e il controllo ritorna all'applicazione che chiude la Connection, la tabella USER verrà utilizzata ancora, solo quando l'utente esce per registrarne l'uscita,
.. a questo punto l'applicazione carica i menu e li rende visibili.

direi che ci siamo

Grazie !!