// login.cgi: applicazione per registrare l'ingresso nell'area // dei corsi. Modifica il template con i dati personali // dell'utente (percorso formativo con moduli disponibili) #include #include "applicat.h" class Login_Application : public Application { private: String _dbname; String _utente; // Utente corrente String _realname; String _moduli; // Moduli attivi per l'utente corrente PgEnv _environment; PgTransaction *_db; protected: virtual bool create(); virtual bool destroy(); virtual void main_func(); void login(); void print_access_error(); public: Login_Application() {_db = NULL;} virtual ~Login_Application() {}; }; void Login_Application::print_access_error() { cout << "

Accesso al corso



" << endl; cout << "

Si prega di effettuare regolarmente l'accesso al corso, fornendo le indicazioni
"; cout << "di utente e password in vostro possesso.


" << endl; } bool Login_Application::create() { _dbname = POSTGRES_DB; _environment.Port(POSTGRES_PORT); _environment.Host(POSTGRES_HOST); print_header("Accesso all'area corsi"); _utente = getenv("REMOTE_USER"); return TRUE; } bool Login_Application::destroy() { print_footer(); return TRUE; } void Login_Application::login() { // Controlla se l'utente fornito č' un utente valido String command; // Compone la stringa di selezione utente. command = "SELECT * FROM UTENTI WHERE loginname='"; command += _utente; command += "'"; // Esegue il comando SQL, dovrebbe venir ritornata una sola tupla // al limite se ne vengono ritornate piu' di una verranno ignorate _db->ExecCommandOk(command); const int tuples = _db->Tuples(); if (tuples > 0) { // Cosa deve fare: // Sistema le informazioni di logging dell'utente (anche sulla tabella ACCESSI) // Carica il percorso formativo (campo modules) e compone la pagina const bool logged = (_db->GetValue(0, "logged"))[0] == 't'; _realname = _db->GetValue(0, "realname"); _moduli = _db->GetValue(0, "modules"); // Aggiorna le informazioni di logging if (!logged){ // Prende il progressivo per il logging sulla tabella accessi long progressivo = 0L; command = "LOCK PROGRESSIVI"; // Blocca la tabell all'interno di questa transazione per evitare sovrapposizioni _db->ExecCommandOk(command); // Verrā automaticamente sbloccata al termine della transazione command = "SELECT * FROM PROGRESSIVI"; // In caso il CGI si pianti la transazione viene abortita dal server, e di fatto non verrā fatto nessun aggiornamento alle tabelle if (_db->ExecTuplesOk(command) && _db->Tuples() > 0){ progressivo = atol(_db->GetValue(0, "progaccessi")); } else { // Se non c'č nessuna riga viene aggiunta command = "INSERT INTO PROGRESSIVI VALUES(0,0)"; _db->ExecCommandOk(command); } progressivo++; command = "UPDATE PROGRESSIVI SET progaccessi=progaccessi+1"; // Incrementa il progressivo _db->ExecCommandOk(command); // Aggiorna la tabella relativa command = "UPDATE UTENTI SET logged=1, logindate=current_timestamp, "; command += "progaccesso="; command += ltoa(progressivo); command += " WHERE loginname='"; command += _utente; command += "'"; _db->ExecCommandOk(command); // Aggiorna la tabella utenti command = "INSERT INTO ACCESSI VALUES ("; command += ltoa(progressivo); command += ",'"; command += _utente; command += "',current_timestamp, null)"; _db->ExecCommandOk(command); // Aggiunge un record alla tabella accessi } // Seleziona i moduli abilitati command = "SELECT * FROM MODULI ORDER BY modulenum"; _db->ExecCommandOk(command); cout << "

Percorso formativo



" << endl; cout << "

Benvenuto/a, " << _realname << ".

" << endl; cout << "

Ecco l'elenco dei moduli disponibili, clicca sull'immagine relativa al modulo per entrare nell'area di formazione prescelta. Si ricorda che i moduli contraddistinti da una piccola spirale fanno parte delle lezioni avanzate.

" << endl; const int nt = _db->Tuples(); if (nt > 0) { // Seleziona i moduli abilitati per costui cout << "
" << endl; int curr_module=0; for (int i=0; iGetValue(i, "modulenum"))-1; const char *mod_name = _db->GetValue(i, "modulename"); bool cafe; cafe = (strncmp(mod_name,"cafe",4)==0); if (_moduli.length() > mod_num+1 && _moduli[mod_num] == 'X' && (!cafe)) { // Se il modulo e' abilitato e non rappresenta una class cafe visualizza le icone relative const bool new_row = curr_module % 2 == 0; curr_module++; if (new_row) cout << "" << endl; cout << "" << endl; if (!new_row || i == nt - 1) // Se non č nuova riga o č l'ultimo elemento cout << "" << endl; } } cout << "
"; cout << ""; cout << "GetValue(i, "modulename") << "\" BORDER=0>"; cout << "
" << endl; } cout << "

" << endl; } else { // Se non trova i dati dell'utente indicato (con il percorso formativo) // visualizza la mancanza di informazioni per completare la pagina. cout << "

Mancanza di informazioni



" << endl; cout << "

Impossibile reperire le informazioni relative al percorso formativo dell'utente " << _utente << ".

"; cout << "

Controllare l'esattezza delle informazioni inserite.


"; } return; } void Login_Application::main_func() { // Controllo utente: se il CGI viene chiamato senza indicazioni d'utente (impossibile o quasi) // Allora mostra un avvertimento if (_utente.empty()) { print_access_error(); return; } // Se e' stato impostato l'utente, effettua la login() // Inizia la transazione _db = new PgTransaction(_environment, _dbname); if ( _db->ConnectionBad() ) print_database_error(); else login(); delete _db; // Termina la transazione return; } int main(int argc, char* argv[]) { Login_Application* a = new Login_Application(); a->run(argc, argv); delete a; exit(0); }