Fejlesztési dokumentáció - adamk90/PictoGraphy GitHub Wiki

A fejlesztési dokumentációt a rendszer mélyéről kezdjük el bemutatni. Az adatbázis ismereteire építve áttérünk a backend működésére, és végül a webes frontend fog következni. Az egyes egységeken belül a top-down elvet követjük az ismeretek átadásához.

Adatbázis

Adatbázisnak MongoDB-t használtunk annak egyszerűsége és könnyű implementációja miatt. 5 adatbázis táblát definiáltunk, ezekre később kitérünk. A táblákat a lehető legegyszerűbbre terveztük a redundancia elkerülése és a fejlesztési bonyolultság elkerülése végett.

Adatbázis táblák

Felhasználók (user.js)

Ebben a táblában menedzseljük a Userek összes releváns adatát. Az egyedi String típusú Néven és Email címen kívül ide tartozik még a jelszó, és az hogy az adott felhasználó Admin-e. A jelszavakat sózzuk és hasheljük, majd az így kapott értéket a következő módon tároljuk String-ként: Hash(Password, salt) + salt. A salt 16 bájtos. A jelszó követelményekre a későbbiekben térünk ki. Az Adminok megkülönböztetésére egy Boolean változót tartunk fenn. Az Admin előre kézzel beégetett Usert jelent, tehát új User nem tud Adminként regisztrálni, és a rendszeren keresztül létrehozni sem.

Kommentek (comment.js)

Ebben a táblában definiáltuk a kommentek szerkezetét. A komment tartalmát természetesen Stringként értelmezzük. Tároljuk továbbá a tulajdonosát User-ként, és Dátumát is Date-ként. Egyszerűség kedvéért, minimális redundancia árán, tároljuk mellé a User nevét is, hogy ne kelljen 2 táblából összeszedni a szükséges infókat. Inkább legyen egy helyen a szükséges infó, a kérés/keresés szempontjából.

CAFF (caff.js)

Ebben a táblában definiáltuk a CAFF fájlok tárolását. Magát a CAFF fájlt és az Előnézetet is Stringként tároljuk el, ahogy a CAFF fájl Megalkotóját is. A CAFF fájlban definiált Tag-eket egy String tömbként definiáltuk, hiszen ebből több is lehet. A Létrehozás dátumát Date típusként vettük fel a táblába. A Tulajdonos, avagy a user aki feltöltötte a CAFF-ot, eltérhet a Megalkotótól, így ezt egy külön User típusú mezőként tartjuk nyilván. A Kommenteket szintén a CAFF-ok mellett tároljuk el egy komment tömbként.

Tranzakciók (transaction.js)

Ebben a táblában a fizetéssel kapcsolatos Tranzakciókat realizáljuk. Tekintettel arra, hogy ezt a funkciót csak "szimulálni kell", nem is gondoltuk túl ezt a táblát. Egy User típusú Vevő és CAFF típusú Terméken kívül nem is tárolunk mást. Csupán arra használjuk, hogy tudjuk hogy melyik User melyik CAFF-ot "vette" már meg, vagyis töltheti le.

Logok (logs.js)

Ebben a táblában valósítjuk meg a Logolás intézményét. A Userek által végrehajtott műveleteket auditálás céljából logoljuk az adatbázisba. Egy log bejegyzésről tárolunk egy szöveges leírást az elvégzett Műveletről, illetve egy Időpontot is társítunk mellé, hogy tudjuk mikor történt a művelet végrehajtása. A "Ki hajtotta végre a műveletet?" kérdésre a User típusú user mező ad választ.

NodeJS alapú backend

A backend moduláris felépítésének köszönhetően nagyon egyszerű megérteni a működését. Webshop lévén a Frontend és a Backend REST Api-n keresztül beszélget egymással, kérés-válasz módszertant követve. A kérések célpontjai a /backend/routes/routes.js fájlban találhatóak. A kommentezés elég egyértelműen leírja, hogy melyik endpoint mit vár. Ugyanakkor egy részletesebb leírás is megtalálható ezekről itt a Wiki-n a Backend endpoints oldalon, ezért itt nem is részletezem ezeket, mivel minden szükséges információ megtalálható ott, továbbá példákat biztosít tesztelési célokra is.

Route-ok

A route-ok alatt definiálva vannak a végrehajtandó kódblokkok, úgynevezett middleware-ek. Ezek a /backend/middlewares mappában találhatóak. A felhasználói műveletek nagy részénél JWT tokenekkel azonosítjuk a felhasználót, és autentikáljuk a kérését. A login esetében a felhasználót a felhasználónév:jelszó páros azonosítja. A sikeres bejelentkezés esetén legeneráljuk a felhasználónak a JWT tokent, melynek felhasználásával tud csak további műveleteket végrehajtani. Ez utóbbit ellenőrizzük is minden releváns kérés esetén. A felhasználó minden műveletét logoljuk a megfelelő adatbázis táblába. A JWT tokenek időben limitált érvényűek, lejáratuk 40 perc.

Hibaüzenetek

A felhasználótól érkezett kéréseket illetően általában illik valami hibaüzenetet visszaadni, hiszen tájékoztatni kell a felhasználót az esetleges hibáról. Ezt mi is megtesszük, azonban a lehető legkevesebb side-channel információ kiszívárogtatására törekedtünk. Valamennyi esetben ugyanazt a 400-as http hibakódot küldjük vissza. Ez egy támadónak nem mond sokat, aki például Postmannel vagy curl-hívásokkal próbálkozik, csak annyit, hogy valahol hiba csúszott a számításaiba, de azt nem fogja tudni, hogy hol. A Frontend azonban kontextus függő, így a felhasználó kaphat egy minimális képet arról, hogy melyik művelet nem működött, de itt is csak a hiba szövegesen megfogalmazott tényét közöljük a felhasználóval, a rendszer mélyére ebben az esetben sem kapunk betekintést. Ezzel az orákulum típusú támadásokat gyakorlatilag ellehetetlenítettük, hiszen a támadó nem kap olyan minőségű hibaüzenetet, amivel javíthatná támadásának minőségét. A válaszidő mérésén alapuló támadásokra nem fordítottunk figyelmet.

HTTPS

A kérések a publikus interneten természetesen HTTPS-en keresztül kerülnek továbbításra. Ehhez egy saját RSA kulcsot generáltunk amit az SSL titkosításhoz használunk. Ezt persze nehezményezi bármelyik mai böngésző, így kézzel kell letolni a torkán (importálni az elfogadott kulcsok közé). A HTTPS használata csak a lehallgatást teszi lehetővé, de a titkosítás megléte miatt ebből sem nyerhető releváns információ.

Adat validáció

A felhasználótól kapott adatok többségét itt a backendben validáljuk, például a jelszó szerkezetét is, melynek az alábbi követelményeknek kell megfelelniük: legyen legalább 8 karakter, illetve tartalmazzon kis betűt, nagy betűt, számot, speciális karaktert. Az email cím validálását annyiból elintéztük, hogy a '@' jel nem lehet első és utolsó karakter, tehát valahol a cím belsejében kell tartózkodnia. A felhasználónévnek legalább 3 karakter hosszúnak kell lennie.

Részletes backend security leírás található a "Backend Security" oldalon

Web alapú frontend

A frontendnek végül a Vue JavScript frameworköt választottuk, szintén egyszerűsége miatt, illetve ezzel volt tapasztalatunk. Ennek megfelelően készültek el az egyszerűbb stílusú felhasználóbarát oldalak. Az oldalak használata intuitív:a bejelentkezés olyan mint bárhol máshol, ezt követően meg lehet tekinteni a saját CAFF-okat, illetve lehet a keresés mezőben keresést kezdeményezni a CAFF-ok között. A frontend tároltat egy cookie-t a böngészővel. A cookie beállításai közt beállítottuk a secure tulajdonságot, így csak HTTP(S) kapcsolat fér ehhez hozzá, és kiküldése csak titkosítottan, HTTPS-en keresztül történhet. Az XSS védelem érdekében szükgés lenne még a httpOnly tulajdonságra is, ám ezt a nuxtjs auth modulja még nem támogatja.

Tesztelés

A websop-hoz nem írtunk explicit futtatható teszteket, elégségesnek éreztük a kézi tesztelés elvégzését, tekintettel a komplexitás csekély mértékére. A kézi tesztelés kitért minden frontend komponensre és felhasználói use-case-re. Ezek elvégzésére egy webböngészőt (Firefox vagy Chrome) használtuk.

Teszt forgatókönyvek és eredmények

Minden forgatókönyv esetén úgy tekintjük, hogy ha egy User képes a saját dolgait kezelni, akkor egy Admin is, hiszen ő is egy user. A különbség annyi, hogy a nem saját dolgokra indított műveletek is sikeresen lefutnak Admin esetében.

Teszt 1: Regisztráció

Regisztráció

Teszt 2a: Login, helyes adatokkal

A helyes adatokkal történő bejelentkezés esetén nem érkezik hibaüzenet. A sikeres bejelentkezést követően CAFF-ok egész világa tárulhat a felhasználó szeme elé.

Sikeres bejelentkezés

Teszt 2b: Login, de rossz felhasználónév

Rossz felhasználónév esetén tájékoztatjuk a felhasználót a hiba esetleges forrásának okáról.

Rossz felhasználónévvel

Teszt 2c: Login, de rossz jelszó

Rossz jelszó esetén tájékoztatjuk a felhasználót a hiba esetleges forrásának okáról. A hiba ugyanaz, mint a "rossz felhasználónév" esetben.

Rossz jelszóval

Teszt 3: Saját komment készítése

Egy lelkes felhasználó sikeresen posztolta első kommentjét egy CAFF alá.

Első komment

Teszt 4: Saját komment törlése

Zsolt2 felhasználó létrehozott egy kommentet, de rájött hogy nem illik oda, ezért szeretné eltávolítani. Ezt sikerül is megtennie.

Komment törlés, megerősítés A kommentje eltűnt. Komment törlés

Teszt 5: Nem saját komment törlése (Csak Admin esetén sikeres)

A felhasználó lehetőséget sem kap arra, hogy egy másik felhasználó kommentjét törölje (kis kuka ikon).

Másik user komment törlése

Ugyanakkor az Admin jogosultásgú személy képes ezt megtenni.

Admin mindent tud törölni

Teszt 6a: Helyes CAFF feltöltése

CAFF fájl feltöltése

Teszt 7b: Hibás CAFF feltöltése

CAFF feltöltése közben felmerülő hibáról tájékoztatjuk a felhasználót. Valószínűleg a CAFF lehetett hibás.

Hibás CAFF fájl feltöltése

Teszt 8: Saját CAFF letöltése

CAFF letöltése

Teszt 9a: CAFF keresés TAG alapján

Keresés mezőbe írt kulcsszóval alapján fog a TAG-ek között keresni.

CAFF keresés

Teszt 9b: Összes CAFF listázása

Üresen hagyott keresés mező esetén minden CAFF megjelenik.

CAFF keresés

Teszt 10: Nem saját CAFF törlése (Csak Admin esetén sikeres)

A felhasználó képtelen egy másik felhasználó CAFF fájlját törölni.

CAFF törlése

De egy Admin természetesen képes rá.

CAFF törlése

Teszt 11: Nem saját CAFF "vásárlása" és letöltése

Sikeres vásárlás esetén letölthetővé válik a CAFF fájl.

CAFF vásárlás
⚠️ **GitHub.com Fallback** ⚠️