» »

Izdelava svojega "dropboxa"

Boomerang ::

Lp,

Zanima me, kako bi izdelal svoj dropbox, ki bi ga potem uporabljal znotraj domačega omrežja - sčasoma pa mogoče tudi v internetu (razvijam za izobraževalne namene).
Celotno spletno storitev sem se odločil izdelati v ASP.NET in zaenkrat lepo napreduje, trenutno imam narejen preprost brskalnik datotek in formo za upload novih datotek. Trenutno pa se ukvarjam z downloadom in se mi je pojavilo vprašanje kako poskrbeti za datoteke, da bodo varne.

Zaenkrat imam za vsakega uporabnika določeno svojo mapo, ki jo sistem izdela ob registraciji. Potem se v uporabniško mapo shranjujejo datoteke, ki jih uporabnik uploada. V "brskalniku datotek" se ob datotekah ustvari samo link do datoteke. Tu pa je problem, saj tako datoteke niso zaščitene in jih vidijo vsi uporabniki - to pomeni, če nekdo pozna nek drugi username (ime mape) in točno ime datoteke, lahko v svoj brskalnik vpiše URL do datoteke in že nekomu ukrade datoteko. Vprašanje: Kako to drugače implementirati, da bo vsak uporabnik videl samo svoje in samo svoje lahko downloadal?

Gwanaroth ::

Za inspiracijo poglej kako je tole narejeno: http://owncloud.org/
Lights often keep secret hypnosis..

Boomerang ::

Sem pogledal, ampak še vedno ne razumem sistema delovanja. Kako bi na strežniku shranjeval datoteke, da bi uporabnik imel dostop le do določenih datotek. Recimo tale izmišljen primer: Uporabnik bi v brskalnik lahko vpisal na primer: http:/moj_dropbox.net/uporabnik1_mapa/datoteka.txt in bi mu odprlo datoteko, čeprav do nje ne sme imeti dostopa, saj ni v njegovi mapi. Kako rešiti ta problem?

Raptor F16 ::

Ti bi zdaj rad naredil svoj cloud strežnik, no big deal. En komp s spodobnim procesorjem, veliko prostora za shranjevanje, daš vse datoteke v share z računalniki v domači skupini in et viola!

Zgodovina sprememb…

ZaphodBB ::

Tukaj prideta v upoštev dva koncepta. Avtentikacija in avtorizacija. Avtentikacija pomeni: Dokaži, da si kdor praviš da si. Avtorizacija pa pomeni: Ali ima uporabnik X pravico videti vsebino Y.

Oba lahko implementiraš na N načinov.

misek ::

Naj se uporabnik najprej logira v sistem in potem ima dostop do svojih datotek. V nasprotnem primeru pa nima dostopa do nobene datoteke.
Ali pa narediš dvonivojski dostop - vsak uporabnik ima eno mapo imenovano "skupna" in iz te mape lahko prenaša poljubna oseba kljub temu, da ni logirana v sistem.

kunigunda ::

Ce bos dinamicne linke uporabljal, potem imas lahko zeljeno kontrolo, sicer pa ne.

Boomerang ::

Se mi zdi, da sem našel boljši način: namesto neposredno na disk, se bodo datoteke shranjevale v podatkovno bazo (priporočilo z nekega drugega foruma). Nisem se spomnil na to možnost. Zdej moram samo testirat kako to dejansko deluje, glede na to, da so datoteke lahko različnih formatov.... od TXT do EXE.
Potem pa pride v poštev avtentikacija in avtorizacija: če ima logirani uporabnik pravico (ID_user = ID_file_owner), potem se datoteka prebere z baze.

RockyS ::

Shranjevanje datotek v bazo ni nikoli pametna ideja, vsaj ne v tem primeru.

kunigunda ::

Ne kompliciraj.

Prenos naredi preko xx.php

datoteke shranjuj npr na /files kjer uporabniki nimajo direktnega dostopa

request za fajl naj bo npr xx.php?file=/files/aaaa.exe

v xx.php preveris ali mu dovolis ali ne, odpres fajl in postas vsebino na out

Content-type: mime
Content-length: size of file in bytes

kjhkhkjdfhkdfhkdfhfdkdf ---- file vsebina, kakrsna je

[mime] bos moral glede na koncnico datoteke sam pisati.

Boomerang ::

Hvala vsem za pomoč. Na koncu sem naredil tako kot je predlagal @kunigunda zadeva že dela, vsaj osnovne stvari: registracija, prijava/odjava, upload/download, brskanje po datotekah. Kar zadeva podatkovno bazo, sem ustvaril samo 1 tabelo, kjer imam shranjeno:
RACUN[id, uporabnisko_ime, geslo, mail].

Zdaj bi rad zadevo še nekoliko izpopolnil in spet rabim nasvet. Rad bi naredil, tako da uporabnik X lahko shera neko datoteko z določenimi uporabniki, na primer uporabnika Y in Z. Kako to najlažje implementirati? Moja ideja je, ustvariti še eno tabelo in jo ustrezno povezati z obstoječo tabelo. Tako bi imel na primer še tabelo: DATOTEKA[id, (pot)\ime_datoteke, lastnik, dovoljenja].
Atribut dovoljenja (string) bi vseboval seznam uporabniških ime, ki lahko dostopajo do datoteke v drugem računu. Kako se vam zdi ta ideja? Gre morda na lažji način?

Zgodovina sprememb…

  • spremenilo: Boomerang ()

carota ::

Boomerang je izjavil:

Zdaj bi rad zadevo še nekoliko izpopolnil in spet rabim nasvet. Rad bi naredil, tako da uporabnik X lahko shera neko datoteko z določenimi uporabniki, na primer uporabnika Y in Z. Kako to najlažje implementirati? Moja ideja je, ustvariti še eno tabelo in jo ustrezno povezati z obstoječo tabelo. Tako bi imel na primer še tabelo: DATOTEKA[id, (pot)\ime_datoteke, lastnik, dovoljenja].
Atribut dovoljenja (string) bi vseboval seznam uporabniških ime, ki lahko dostopajo do datoteke v drugem računu. Kako se vam zdi ta ideja? Gre morda na lažji način?

Tukaj bi moral narediti še eno tabelo, ki bi vsebovala stolpca "ID datoteke" in "ID uporabnika". Tako boš enostavneje dodajal in brisal pravice ter z enostavnim queryjem izpisoval kdo dostop do katerega fajla.

Sploh pa se mi zdi ideja, da bi uporabil "uporabniška imena" slaba. Tabele naj imajo numeričen key in tega se uporablja, da lahko narediš indexe pa take fore. :)

RockyS ::

Mene bolj zanima kako bi rešil sinhronizacijo, torej da imaš na desktopu mapo in se potem ta samodejno (vsebina) prenese na strežnik.

kunigunda ::

Osnovno tabelo itak moras imeti

datoteka
- id
- userid
- uploadtime
- modifytime

pol pa se naredi tabelo

share
- datotekaid
- userid
- sharetime
- share attribute (npr 1-read, 2-write, 4-delete, ...)

Ko nekdo hoce nekaj narediti z datoteko, pogledas najprej tabelo 'datoteka'. Ce je userid = tvojid, pomeni da si owner in imas vse pravice.
Ce userid ni tvojid, pol gles gledat share tabelo (kljuc je datotekaid+userid). Ce ni zapisa, nimas pravic do datoteke.
Ce imas zapis pa potem naprej glede na share attribute dovolis/nedovolis

misek ::

RockyS je izjavil:

kako bi rešil sinhronizacijo, torej da imaš na desktopu mapo in se potem ta samodejno (vsebina) prenese na strežnik.
Z aplikacijo, ki spremlja vsebino folderja - na Linux-u z inotify sistemom, na Windowsih pa odvisno od uporabljene platforme. Recimo z API-jem FindFirstChangeNotification. Ta aplikacija pa bi prenesla datoteke preko HTTP protokola, tako kot to naredi brskalnik.

Boomerang ::

@RockyS, sinhronizacija tudi mene še čaka, ampak to naj ostane za kasneje. Bom se lotil, ko bo spletna aplikacija kompletno izdelana.

@kunigunda, moja trenutna izvedba se nekoliko razlikuje:
- za datoteke nimam posebne tabele, pač pa jih hranim na posebni particiji v mapi /Users/[ime_uporabnika]. Ko želim prikazati naložene datoteke pa z funkcijami prelistam določeno mapo in za vsako datoteko preverim še kdaj je bila spremenjana --> datum spremembe bom kasneje rabil, ko bom delal sinhronizacijo z odjemalcem (namizna app).
- edino za share bom naredil tabelo --> za začetek bo datoteke možno samo ogledovat (morda bom kdaj kasneje realiziral še dodatne možnosti). Razmišljam pa, da bi raje v share dal kar celo mapo in so potem vse datoteke v mapi avtomatsko sharane (tako kot ima pravi dropbox), vendar s to razliko, da bi bilo možno sharat za več uporabnikov. Torej, če se bi datoteka pojavila v bazi, je sharana in pogledam še s kom jo delim. Če datoteke ni v bazi, potem ni sharana.

Zdaj pa sem se domislil, da bi uporabil še neke vrste "Koš". S tem mislim, da datotek ne bi takoj izbrisal, ampak samo označil za brisanje. Tako označene datoteke se v brskalniku ne bi pokazale, ampak bi izdelal posebno opcijo, kjer bi imel uporabnik 2 možnosti: dokončno izbriši, obnovi. Seveda bi potem potreboval še eno tabelo, kjer bi shranjeval še "izbrisane" datoteke - podobno kot za share.

misek ::

Boomerang, možnost starih kopij je vsekakor opcija, ki bi jo moral realizirati. Tako kot ima to urejeno dropbox, kjer lahko restavriraš starejše verzije datotek.

NeMeTko ::

@Boomerang
Ne dolgo nazaj, sem za nekaj podobnega spraševal v neki drugi temi, le da se je nanašalo na email.

Zadeva, ki jo postavljaš, sicer ne gre čisto v isto smer, kot sem jaz tuhtal, je pa že kar blizu.

Če pogledaš dropbox, yousendit in podobna 'odlagališča', vsi že ponujajo nekakšen outlook plugin, ki ti omogoča pošiljanje maila z veeeliko priponko, ki se avtomatično shrani na njihovem strežniku, naslovnik pa dejansko dobi dostavljen le link, s pomočjo katerega si k sebi prenese to priponko z njihovega strežnika.

Če hočeš kaj podobnega implementirati na kakšnemu lastnemu strežniku, takoj naletiš na problem, ker se najdejo le plugin-i za konkretni servis, ne pa tudi za npr. lastni ftp strežnik (tvoja rešitev bi se dala lepo dopolniti z sftp strežnikom). Edino, kar takemu pluginu pride kolikortoliko blizu (kar mi je uspelo najti), bi bil open source projekt 'Memba Veldoc Outlook Add-In', ki pa je očitno projekt, ki je umrl, še predenj je prešel beta stadij.
Morda kdo pozna kakšen ekvivalenten odprt plugin, ki omogoča shranjevanje outlook priponk na strežnike po lastni izbiri?

Če bi se nekako spentljalo tisti username v php še z email naslovom uporabnika, lahko zadeva postane še veliko bolj uporabna, kot izgleda na prvi pogled. Zakaj bi velike datoteke pošiljal na yousendit in jim plačeval, če to lahko rešiš na lastnem strežniku? Največja prednost pri tem je ta, da na lastni lokalni strežnik mimogrede odložiš datoteko, medtem ko pri cloud servisih čakaš in čakaš, kdaj se bo prenos že enkrat končal.

Sicer pri temu še obstaja 'manjši problemček', kako za nek nov email naslov avtomatično kreirati novega uporabnika in temu potem posredovati podatke za prijavo.

Obstaja kar nekaj komercialnih rešitev, ki te reči obvladajo v nulo, vendar je njihova cena takoj tam okoli 20k€. Od tod moj interes za to, kaj se da od tega rešiti z odprto kodo in koliko blizu se da priti.

kunigunda ::

Ce bi imel posebno tabelo tudi za uporabniske datoteke, ne bi rabil kreirati uporabniske strukture po diskih, poleg tega ce jih zbrises,
avtomatsko samo v tabeli popravis da je zbrisana in cas brisanja, tko potem ni vec dostopna (razen ce naredi undelete), pol pa samo status popravis. pac samo nasvet, bos ze sam videl kako bos rabil v prihodnosti.

Boomerang ::

@kunigunda, če prav razumem, potem sva na isti "valovni dolžini". Ob "brisanju" datoteke bom v tabelo shranil par podatkov o datoteki in njen status (izbrisana). Če uporabnik datoteko obnovi se bo vnos izbrisal iz tabele oz. se samo popravi status. Če pa bo uporabnik dokončno izbrisal datoteko, sledi fizično brisanje na disku.
Na isti princip se bi dalo rešit sharane datoteke, le da gre za drugi status - sharana ali private. Če je sharana, pa potrebujem še dodatne podatke - kdo lahko vidi.

@NeMeTko, jaz imam zdaj narejeno tako, da ob registraciji uporabnik dobi potrditveni mail (ki še ni popolnoma urejen). V tabelo RACUN se shrani mail in čas kreiranja. Na podlagi zabeleženega časa lahko potem ugotovim ali je potrditveni mail še veljaven ali je treba poslati novega.

@misek, a to misliš, da bi datoteko najprej nekam arhiviral (naredim kopijo), original pa zamenjal z novejšo verzijo? Sem prav razumel? Če je tako, potem mi je najboljša možnost, da arhive premaknem v neko drugo mapo - tako se imena datotek ne bi podvajala.

Kar pa zadeva samo shranjevanje datotek, bo v uporabnik lahko v svoji uporabniški mapi kreiral nove mape in znotraj teh spet druge (drevesna struktura). V bazi nameravam shranjevati samo "posebne datoteke" t.j. sharane ali izbrisane - tako bi bila podatkovna baza manjša in na disku ostane več prostora za shranjevanje datotek. To je zaenkrat samo ideja, kakšna bo dejanska izvedba, je pa odvisno od morebitnih problemov na katere lahko naletim.

misek ::

Boomerang, moral bi imeti več kopij istih datotek in uporabnik bi kasneje imel možnost uporabiti kakšno staro. Za verzije datotek bi lahko imel na koncu imena .1, .2, ... Še boljše pa bi bilo shranjevati samo razlike med datotekami, saj bi s tem prihranil na prostoru.

kunigunda ::

V tabelo mail si shrani se nakljucno generirano kodo, po mailu pa potem posljes link

http://mojserver/activate?mail=janez.no...

to dvoje mora biti v bazi in ga enejblas pri aktivaciji.

Boomerang ::

Ja, to moram še dopolnit. Kot rečeno, potrditveni mail še ni popoln.

Zanima pa me še nekaj:
Dokler je zadeva za domačo uporabo in izobraževalne namene je vse lepo in prav. Recimo, da bi svoj cloud dal nekam na internet in bi ga uporabniki začeli uporabljat. Sčasoma bi se nabralo dovolj uporabnikov in bi bila baza nonstop v uporabi/obremenjena. Razmišljal sem, da bi v tem primeru malo spremenil strategijo: naredim podatkovno zbirko in ob logiranju noter shranim podatke z baze, ali pa vsaj podatke o trenutnem uporabniku. Potem bi namesto do baze uporabljal samo podatkovno zbirko. To bi nekoliko razbremenilo bazo, vendar se sprašujem kako učinkovito bi bilo. Na kratko: za shranjevanje bi uporabil bazo, za obdelavo podatkov pa podatkovno zbiro. Kako se zdi ta ideja? Bi šlo ali ni dobra zamisel?

NeMeTko ::

@Boomerang - če boš zadevo hotel kasneje naresti nekoliko bolj 'profi', ti priporočam, da razmišljaš tudi o nekakšnem 'dnevniku prenosov', kjer bi lahko uporabnik imel vpogled v transakcije na svojem accountu.

Če pa se zadeva uporablja kot nekakšna nadgradnja za mail, da preko nje pošiljaš velike datoteke drugemu uporabniku, pa mora biti na voljo tudi nekakšen dnevnik, v katerem lahko pošiljatelj vidi, če si je naslovnik že prenesel datoteko.

Zgolj toliko, da boš imel v mislih možnosti za morebitne kasnejše razširitve....

kunigunda ::

Ne razumem cist dobro kaj si predstavljas pod podatkovno zbirko (ker to je tud baza :P), mislis zgolj raw file ?
Potem je bolje bazo uporabljati, ker uporablja tudi caching in je hitreje (seveda bos pri velikem stevilu dostopov nujno moral uporabljati particije na bazi,
lahko preveris se za kaksnimi real-time bazami, sploh ce ne bos sparal s spominom.
Od trenutno prijavljenega uporabnika ti je dovolj njegovo uporabnisko ime in session id, ce bos prenos imel preko http(s), uporabis cookije.

Boomerang ::

S podatkovno zbirko (collection) sem mislil kakšne vektorje, Liste in podobno. Tako bi ob logiranju iz baze prebral podatke ter jih shranil v collection. Res je, da ob morebitni spremembi spremembi baze (s strani drugega userja) spremembe ne bi bile opazne, vendar je uporaba zbirk bistveno hitrejša od izvajanja poizvedb nad podatkovno bazo. Ali pa vsaj kakšna zrna (beans) bi lahko uporabil.

Prijavo imam narejeno s cookiji. Če se vpisano geslo oz. njegov SHA-1 odtis ujema z tistim v bazi in če je username pravi, potem ustvarim cookie, kamor shranim id računa. Ko uporabnik odpre neko drugo stran, tam najprej preverim cookie in takoj vidim za katerega userja gre.

Trenutno pa se posvečam omejitvam clouda - koliko prostora lahko zasedejo uporabnikove datoteke na strežniku. Ker je nastavitev enaka za vse račune, nima smisla shranjevat v bazo, ali pač? Boljša se mi zdi izvedba s posebno datoteko, kjer bi bile zabeležene takšne nastavitve.

kunigunda ::

Samo ID racuna ni dovolj. Cookie se da ukrast, in ko ga enkrat imas bos imel vedno dostop kot ta user. Vedno moras vsaj paru delati, se pravi userid in sessionid (ki se zgenerira vsakic nov, ko cookie potece), sploh za take obcutljive stvari, jest bi clo dal se IP notri v session in definiral rok veljavnosti cookija. Tako nekomu drugemu tudi ce cookie ukrade ne bo ratalo videti fajlov.

Boomerang ::

Sedaj imam spletno aplikacijo skoraj končano (ostane le še kakšna izboljšava, oblikovanje itd). Lotil sem se izdelave desktop aplikacije, ki bo skrbela za sinhronizacijo. Celotna spletna aplikacija je izdelana z ASP-jem (C#), zato bi rad tudi aplikacijo napisal v C#. Rabim pa par nasvetov kako se tega lotiti.

Za začetek bi rad rešil problem nalaganja na strežnik. Postopek v spletni aplikaciji je sledeč:
S klikom na gumb "Naloži datoteko" je uporabnik preusmerjen na Nalozi.aspx. Tukaj najprej preverim piškotke (če niso pravi, sledi preusmeritev na Vpis.aspx). Če so piškotki OK, sledi branje podatkov iz podatkovne baze (podatki o uporabniku, da vem kam shranit). Šele potem se prikaže forma, kjer uporabnik izbere datoteko in jo naloži na strežnik.
Kako napisati program v C#, ki bi opravil tole delo - piškotki, podatkovna baza, nalaganje datoteke? Rabim nasvet, ker ne vem kam pogledat.

Boomerang ::

A res nihče ne ve, kako v C# (desktop application) nastaviti cookie, da bom imel dostop do spletne strani ASP, ki preverja cookie?

kunigunda ::

Ja lej, zastavil si si projekt, mal se pa mors potrudit. Google knows everything...

carota ::

Boomerang je izjavil:

Kako napisati program v C#, ki bi opravil tole delo - piškotki, podatkovna baza, nalaganje datoteke? Rabim nasvet, ker ne vem kam pogledat.

Ker ne boš v C# napisal svojega browserja, temveč samo specializiranega odjemalca, boš moral te funkionalnosti implementirati sam. Lokalno imaš lahko tudi podatkovno bazo, npr. SQLite, ki je shranjena v enem fajlu. Ne bi pa fajle vanjo shranjeval.

Preberi si malo o WebDAV (Wikipedia).

Pet minut razmišljanja ti lahko prihrani eno uro dela. :)

Grizzly ::

Zdravo!

Da ne odpiram nove teme, bom kar tukaj zastavil vprašanje.
Pri seminarski nalogi moram raziskat takšne storitve, kot so Dropbox, SugarSync, OnLive Desktop itd... torej nekam shraniš svoje datoteke in do njih imaš dostop kadarkoli od koderkoli. Najprej me zanima, kako bi takim storitvam rekel z "eno besedo"? Rabim čim več gradiva, a ne vem kako bi temu rekel, da bi v Googlu dobil ustrezno gradivo.

OmegaBlue ::

cloud storage.
Never attribute to malice that which can be adequately explained by stupidity.

kunigunda ::

Bolj primerno je File hosting, ker ne operirajo vsi s cloud tehnologijo.

techfreak :) ::

Moderni ponudniki sinhronizacije datotek med računalniki načeloma vsi do neke mere uporabljajo cloud tehnlogijo. Sicer cloud je bolj kot ne moderna beseda za strežnike; pač lepše se sliši reči da imaš podatke v oblaku kot pa na strežnikih.

Sicer pa pod file hosting spada vsak FTP ponudnik, med tem ko pri oblaku (za končne uporabnike) pričakuješ možnost sinhroniziranja med napravami in podobno.


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Enolični identifikator datoteke

Oddelek: Programiranje
9463 (172) Ericssony
»

Izdelava družbenega omrežja

Oddelek: Izdelava spletišč
10991 (298) Mesar
»

php - galerija slik

Oddelek: Izdelava spletišč
14737 (465) t3hn0
»

xml dnevni uvoz v bazo

Oddelek: Programiranje
10607 (360) keworkian
»

[PHP] Prijava uporabnika(forum)

Oddelek: Programiranje
11975 (744) rokpok

Več podobnih tem