Newsgroup: it.comp.lang.delphi
Titolo: Gestione files su server

Ciao a tutti,
ho la necessità di creare un mini gestore di files con accesso da
client su un server Win2003 solo Lan.
Quello che vorrei fare è far gestire al software tutte le operazioni
dei files a seconda del login fatto dal mio software con criteri che
non sono gestibili con l'active directory.
Secondo voi come è meglio approcciare il problema?
Un web service sul server oppure gestire un
'ImpersonateLoggedOnUser' (o qualcosa del genere) sul client?
Matteo

> Secondo voi come è meglio approcciare il problema?
Tu hai la CERTEZZA che AD non fa cio che ti serve?
Magari qualche esempio specifico, anche per capire cosa devi
realizzare a prescindere dal "come"...
A.

 non sono gestibili con l'active directory.
Non capisco la richiesta, in quanto la tua descrizione e' talmente 
generica da combaciare con un tipico uso di explorer su cartella di 
rete, oppure di un ftp client su file system, ecc... insomma non 
capisco cosa debbano fare gli utenti di diverso rispetto a explorer.
Spiega meglio cosa vorresti ottenere, e perchè vorresti nello specifico 
ogni particolare funzionalità.
-- 
Morde

 realizzare a prescindere dal "come"...
Ok.
Quello che voglio fare è far gestire al gestionale il 'locking' e
l'update dei files della commessa.
In pratica il risultato di ogni commessa è una serie di files che
vengono compattati e copiati all'interno di una cartella nel server.
In fase di modifica successiva devono essere copiati in locale sul pc
della persona che li userà, i files aggiornati andranno poi a
sostituire i files vecchi.
Il problema nasce dal fatto che:
1- L'accesso dei files non deve essere lasciato libero a tutti gli
utenti autorizzati, in pratica dovrei fare autorizzazioni temporanee a
seconda di chi ci lavora. Questo a livello AD è quantomeno poco
pratico.
2- Devo gestire l'update dei files. Per questo pensavo di spostare il
file vecchio in una apposita cartella appena prima dell'update.
3- Voglio evitare le cancellazioni accidentali, non darò quindi
l'accesso via SO a nessuno (tranne ovviamente administrators, backup
users ecc.)
4- Varie ed eventuali che mi verranno in mente durante lo sviluppo
(tipo la gestione del 'naming' dei files, ecc.)
Ieri stavo verificando i TCPServer e TCPClient di Indy che forse
potrebbero fare al mio caso. La mia idea attuale è quella di creare un
agente che possiede tutti i diritti, da mettere sul server in attesa
di comandi dai vari client i quali, dopo opportuna identificazione,
potranno fare le operazioni necessarie.
Questo approccio mi sembra preferibile rispetto
all'ImpersonateLoggedOnUser.
Da notare che prevedo l'uso esclusivo via LAN, utenti esterni
accederanno solo via VPN.
Sono aperto a tutte le idee o le critiche del caso!
Matteo

 Sono aperto a tutte le idee o le critiche del caso!
Io valuterei seriamente di passare ad un database che supporti i blob, 
posto ideale per memorizzare i documenti, estrarli modificarli e 
salvarli di nuovo, senza antrare nel ginepraio di "quel file e' lockato 
da quell'utente", ecc... (inoltre avresti anche il versionamento per 
ogni singolo documento pratica)
In altre parole, io utilizzarei un paradigma diverso. Il tuo dato da 
manipolare e' il documento, e la modellizzazione si presta bene ad 
essere fatta su un database.
Ciao
-- 
Morde

In un volume NTFS, hai 2 problemi:
1) Se il numero di files presenti in una cartella supera i 255, ler
performance degradano pesantemente
2) ntfs gestisce i files la cui dimensione è inferiore ai 2k (non
ricordo il limite preciso..potrei sbagliarmi..) in modo diverso
rispetto a quelli oltre tale dimensione. Tu mo dici "che me ne
fotte??"...Il problema è la frammentazione generata dai files piccoli
sulla quale il defrag standard di windows non lavora. Tocca usare uno
dei tools di sysinternals.
Se usi i blob, tutti i problemi relativi la sicurezza li elimini
immediatamente.
Questo comporta un delegare al db delle cose che altrimenti dovrebbero
altri.
Questi "altri" sono oggetti software di qualche tipo che probabilmente
dovresti sviluppare tu, aumentando le righe di codice
e le possibilità di bug...
A costo di sembrare pedante sottolineo che, come tante cose, l'uso dei
blob da tanti viene presentato come facile,
ma non è cosi.....
1) va scelta con attenzione la dimensione delo blocco.
2) occorre lameno PORSI il problema della compressione dei dati con
annessi e connessi, tipo se lavori in unicode...
3) va stabilito quanto tempo i dati devono restare persistenti nel
database
4) va stabilita la RILEVANZA del dato blob...Se è non è VITALE, va
eslcuso dai meccansimi di recovery, in modo da non appesantire la mole
di dati che questi sistemi dovranno gestire...
5) va pianificata e messa in piedi una procedura batch da eseguire nei
tempi morti per la riorganizzazione del database, in modo da ridurre
la frammentazione eventualmente generata da numerosi insert e delete
di records con campi blob
Queste 5 cose non sono ALTERNATIVE e andrebbero TUTTE prese in
considerazione.
Pax vobiscum
A.

 fatta su un database.
Amplio il mio discorso, accennandoti che la problematica che hai 
descritto tu , e che io interpreto come un caso di "document 
management" ,viene implementata anche mediante i CMS, che sono per loro 
stessa natura portati all'utilizzo in rete e modellizzabili a 
piacimento.
se guardi ad esempio qui:
http://plone.org/
vedrai che questo CMS ha anche dei moduli per la gestione propria dei 
documenti.
Verifica anche questo percorso: perchè mettersi a reinventare la ruota 
in delphi quando qualcuno l'ha gia' costruita e ce l'hai a costo zero?
Ciao
-- 
Morde

 se guardi ad esempio qui:
http://plone.org/
Si, ci avevo pensato al CMS. Il problema che vedo io è quello
dell'integrazione al sistema. Non ho trovato nessun CMS in delphi,
inoltre ad occhio e croce sono sistemi molto più complessi di quello
che avevo pensato io. Non ho esperienza in merito e anche in questo
caso devo approfondire.
Io intanto sto facendo qualche mini-esperimento di passaggio di dati
tramite TCPServer e TCPClient di Indy che mi sembra interessante.
Matteo

 tramite TCPServer e TCPClient di Indy che mi sembra interessante.
Secondo me, sei totalmente fuori strada.  Poi vedi tu
A.

 Secondo me, sei totalmente fuori strada.  Poi vedi tu
Volevo comunque puntualizzare il fatto che sto comunque seriamente
prendendo in considerazione quello che mi avete proposto, anche se
allo stato attuale mi sembra più semplice e più appropriato la mia
idea iniziale, quantomeno per la realtà nella quale devo applicare la
soluzione.
Apprezzo molto le idee che mi state proponendo e soprattutto apprezzo
il fatto che mi state portando con tanta forza motivi validi per
considerarli.
Matteo

 considerarli.
Il fatto e' noi vorremo aiutarti, ma da quello che vedo manca 
effettivamente l'analisi completa di quello che vuoi ottenere.
Si capisce vagamente dai post quello che vuoi fare, ma i dettagli e i 
casi d'uso non sono spiegati.
Spiega bene che cosa deve fare l'utente/utenti, qual'è lo scenario, che 
cosa vuoi ottenere con la tua soluzione (sia essa db, file, socket, 
cms, ecc) a prescindere dai dettagli.
descrivi le funzionalità della soluzione che ti hanno chiesto.
Dacci tutte le info possibili.
Ciao
-- 
Morde

 richiede conoscenze non da utente finale,
....il developer di oracle o qualche suo alter ego è l'unico modo che
conosci per mostrare il contenuto di un blob ad un utente???
A.

 casi d'uso non sono spiegati.
Si forse hai ragione, provo a spiegare nuovamente dall'inizio.
Scenario:
Azienda il cui prodotto finale è una serie di files (fate conto che
siano disegni tecnici) che poi vengono consegnati all'utente finale.
Prima del mio arrivo i files venivano compressi e messi all'interno di
una cartella in condivisione in un computer con XP. La rete era un
workgroup.
Con il mio arrivo ho avuto il mandato di sviluppare il gestionale in
delphi su base oracle per la gestione delle commesse, planning
compreso, oltre ovviamente a offerte, ordini, conto terzi ecc. ma in
questo caso direi che non c'entra... Il gestionale è attualmente in
fase beta avanzata.
Adesso inoltre siamo passati ad un dominio Win2003. Ho spostato
razionalizzandoli tutti i files nel server. Razionalizzandoli
significa semplicemente che ogni lavoro ha un file ZIP con all'interno
tutti i relativi files, inoltre ho generato una cartella per ogni anno
e all'interno mettiamo i lavori relativi a quell'anno,
Attualmente tutte le cartelle contententi questi files sono in lettura/
scrittura per ogni utente che può lavorare i files (quindi
praticamente tutti tranne l'amministrazione!)
Contemporaneamente l'azienda sta ingrandendo e aprendo filiali nuove.
Sto quindi intanto mettendo VPN in giro per l'italia.
Questo ovviamente aumenta il problema della sicurezza e della
integrità dei files. Sia per evitare che qualcuno possa accedere
impunemente a tutti i files che gli pare e farne un uso improprio, sia
perchè aumentano le probabilità che succedano casini sui files (chiamo
il file in maniera sbagliata e sovrascrivo un file che non dovrei,
cancello un file che non mi compete ecc..)
Come fare ad ovviare a questo problema?
La soluzione che mi è sembrata giusta è delegare la gestione delle
varie cartelle (e quindi dei files) al gestionale che sto completando
(sarà una beta che non avrà fine!!).
Ovvero eliminare l'accesso a livello AD a tutti gli utenti ed
assegnarlo al nuovo utente 'gestionaleDiMatteo'
Per completare il mio prolisso scenario, dovete sapere che devo dare
ad alcune persone (attualmente 2) i diritti di 'gestionaleDiMatteo'
per potergli far accedere direttamente ai files tramite SO perchè
possano agevolmente andare a recuperare alcune documentazioni che gli
possono servire.
Dovrò inoltre creare i diritti di sola lettura per altri utenti per
fare in modo che possano fare delle ricerche all'interno dei files ZIP
(da XP in poi la funzione 'cerca' va anche all'interno degli ZIP)
Da qui nasceva la mia domanda iniziale, se dare al client
temporaneamente i diritti da 'gestionaleDiMatteo' per accedere e fare
le operazioni del caso oppure creare un agente sul server con i
diritti 'gestionaleDiMatteo' .
L'idea del CMS, come dicevo, va bene se riesco ad integrarlo
all'interno del gestionale.
L'idea di passare la gestione dei files ad oracle tramite i blob mi
piace, ma mi sembra più complessa da applicare. Considerate che i
files sono pochi (siamo sotto i 3000) e sono pochi anche gli utenti
(attualmente una quindicina).
Spero di aver detto tutto!
Matteo

 DENTRO IL BLOB?
Riguardo a questo... Io voglio evitare di fare una gestione
documentale almeno per adesso, sono certo che poi nel prossimo futuro
ci arriveremo ma per ora preferisco far partire tutto nella maniera
più veloce (ma corretta!) e poi andrò a modificare le zone del sw che
sarà più giusto e che risolverà più problemi.
Matteo

 Per rispondere a queste due ti dico:
Grazie per le spiegazioni. L'approccio migliore, per stare in linea con 
quello da te adottatto sin d'ora, consiste nel permettere da gestionale 
di accedere ai file della commessa, lavorarci e reinserirli 
nell'archivio relativo sul server.
Il tuo client potrebbe fare queste cose:
1) aprire il file archivio, ed estrarre in un folder locale i file 
della commessa
2) marcare un flag sul database che indica che quella commessa e' in 
modifica e quindi nessun altro puo' modificarla a sua volta
3) a modifiche ultimate, l'utente decide di salvare la commessa, e il 
software riapre l'archivio remoto sul server e lo aggiorna 
aggiungendogli i file locali.
Avrai già capito cosa intendo fare, non mi dilungo sui dettagli.
Un'altra cosa molto interessante, e che dovresti valutare, è che Oracle 
(ma non specifichi quale versione state usando) permette la gestione 
dei datatype BFILE, che sono di fatto dei puntatori a file nel 
filesystem ;-) Questa cosa potrebbe darti un validissimo aiuto, anche 
nel modellizzare il rapporto pratica->file della pratica, di tipo 1->n.
Hai tutte le conoscenze per poter già implementare la soluzione, in 
fondo il database dovrebbe solo contenere e aggregare tutte le 
informazioni relative a utenti, pratiche e file di pratica (in questo 
modo potresti determinare anche in base all'utente i permessi di 
accesso alle pratiche).
Con delphi, reperire un file dalla rete, copiarselo in locale e 
riupparlo in un server non e' poi cosi' complicato, magari utilizzando 
solo le api di windows (es. copyfile) visto che stai in una LAN 
aziendale. Scarta il socket a meno che non ti trovi costretto a 
trasferire tutti i file attraverso la rete (client-server, ma a che ti 
serve in intranet?). windows e' sempre piu' veloce se fa un copyfile di 
z:\pratica\pratica0001.zip
La mia soluzione cerca di riutilizzare tutte le componenti 
semplificando il carico di ognuna di esse, e cercando di isolare le 
responsabilità.
PS:
Ci sarebbero anche altri aspetti che andrebbero esplorati, quali ad 
esempio le possibilità di accedere direttamente ai file da parte degli 
utenti e non solo del tuo programma: il tuo programma delphi, per 
windows avrà dei permessi di accesso che sono quelli dell'utente che lo 
ha lanciato. Tu potresti bloccare tutti gli accessi alle pratiche, 
ammettendo solo il tuo programma: ma devi essere in dominio per farlo, 
e utilizzare un'utenza di dominio per lanciare il programma.
Io ho realizzato un servizio di spooling che fa proprio questo, e per 
accedere ai file di tutti i computer lo faceva in quanto lanciato come 
utente di dominio.
PPS: stai sul semplice, e non ingarbugliare troppo le logiche: potresti 
non essere più in grado di far evolvere il tuo gestionale con facilità 
e rapidità.
-- 
Morde

 e rapidità.
;) Ci provo, ma lavorando come interno è normale che le specifiche ti
cambiano sotto i piedi.
Grazie mille!
Matteo

 file, giusto?
Intendo dire che sarà il gestionale ad occuparsi delle autorizzazioni, 
perchè il gestionale dal database ricava i privilegi per l'utente 
loggatosi. (parlo di utente e privilegi da gestionale, non di windows).
In questo modo, il gestionale deve poter accedere ai files, e per farlo 
quei files dovranno essere condivisi a tutti.
Il gestionale, in base alle credenziali dell'utente loggato, mostra e 
permette la modifica solo delle pratiche opportune. Se l'utente sceglie 
di aprire in modifica una pratica, il gestioanle aggiorna il database 
indicando che quella pratica e' in modifica per conto dell'utente 
"pippo", poi preleva il file archivio dal server (QUI parlo di account 
di accesso windows ai file), lo copia in locale, lo scompatta e per ora 
ha finito li.
Nel frattempo tutti gli altri utenti che vogliono accedere alla 
pratica, lo possono fare solo in readonly (sempre da gestioanle)
Quando "pippo" ha finito di modificare i file pratica, va nel 
gestionale e salva la pratica: il gestionale reimpacchetta i file, 
ricopia via rete la pratica sovrascrivendo la vecchia (o backuppando 
prima la vecchia, cosi' hai anche il versionamento) e sbloccando la 
pratica sul database.
In altre parole, e' il gestionale che si occupa degli accessi.
Ovviamente se uno si inventa di andare sul server con l'utenza windows 
a fare cagate... beh a questo punto e' lui che si assume la 
responsabilità delle sue azioni, SAPENDO che non deve accedere alle 
pratiche manualmente.
Può andare come scenario?
Ciao
-- 
Morde

 Ciao
Può andare, ma cosi devi comunque lasciare libero accesso a tutti gli
utenti che utilizzano i files.
Poi magari non gli fornisci la mappatura in rete e gli complichi un
pochino la faccenda, ma comunque l'accesso è possibile.
Questo significa che se io sono un utente un pochino sveglio e voglio
fregare un po di codici, lo posso fare.
Io invece voglio di partenza inibire l'accesso a tutti, non devono
neanche vedere la cartella dei files.
Il gestionale dovrebbe quindi aprire una connessione come utente
privilegiato per il tempo della copia e chiuderla immediatamente dopo.
Tralasciamo per ora i problemi di sicurezza dovuti al fatto che il
gestionale deve in questo modo sapere login e password per l'accesso,
che sebbene importanti, preferisco affrontarli dopo.
Per ora dalle prove che sto facendo non riesco ad elevare il
privilegio di copia del file.
Lo schema che sto usando è:
///////////////////////////////////////////////////
If Logonuser(PChar(Nome),PChar('dominio'),PChar(Pwd),
LOGON32_LOGON_NETWORK , LOGON32_PROVIDER_DEFAULT ,Token) then
      ShowMessage('OK')
    else
      ShowMessage('KO');
    if not ImpersonateLoggedOnUser(Token) then
      ShowMessage('Impersonate KO');
    ShowUser;
    if not CopyFile('c:\Matteo\filedacopiare.txt ', '\\Server
\dirbloccata\aa.txt', false) then
      ShowMessage('copyfile KO -> '+ IntToStr(GetLastError));
///////////////////////////////////////////////////
sul server, dirbloccata è una cartella che ho creato e nella quale io
non posso entrare, mentre invece può l'utente di prova che passo (le
variabili Nome e Pwd)
L' "impersonate" va a buon fine.
Lo showUser è una procedurina che mi visualizza l'utente attuale
(tramite GetUserName) e mi fornisce l'utente corretto
Il copyFile non va a buon fine e mi ritorna l'errore : Access is
denied.
C'è qualcosa che mi sfugge, vero??
Matteo

ALT!!!!!
con LOGON32_LOGON_INTERACTIVE al posto di LOGON32_LOGON_NETWORK
funziona.
Continuo le mie prove... ;)

 Continuo le mie prove... ;)
Sto considerando il fatto che non so se sei in dominio o lavori in 
workgroup.. ma se volessi toglierti i problemi riguardo l'environment 
ci sarebbe una possibile soluzione, facile e con poco costo: un server 
ftp.
premesso che la logica degli accessi la metti nel database, e quindi 
gli utenti obbediscono a questa logica, se tu metti un server ftp sul 
server, il tuo gestionale dovrà conosce le credenziali per questo 
server. cosi' facendo ti levi dalle scatole il problema di dover agire 
da codice delphi direttamente con l'ACL di winzozz.
la trasmissione rellenterebbe perchè cambi di fatto l'architettura, ma 
questo ti permette di avere gestionali che di fatto possono trovarsi 
ovunque, basta poter avere una connessione al database e una al server 
ftp.
valuta il peso dei files e quindi il relativo costo di trasmissione.
ciao
-- 
Morde