Spiritul Aplicațiilor

Daţi-mi o pârghie destul de lungă şi un punct de sprijin şi voi răsturna întreaga lume cu o singură mână.

 

Arhimede, 212  î.Hr.

 

M-am gândit să fac o postare mai “tehnică”, dedicată celor din branșă, în cazul in care sunt sunt interesați de ce decizii am luat în dezvoltarea nu numai a aplicației, ci a întregii platforme.

Într-un proiect de acest gen sunt implicate mai multe aspecte: infrastructura (serverul, bazele de date, routing-ul și stocarea datelor), limbajul de programare, frameworkul și tehnologia atât pe partea de backend cât și de front-end.

În ceea ce privește partea de backend lucrurile au mers cam așa.

Totul a început cu achiziționarea unui mic server local, pe care să instalez un repository Git, un server MySQL și alte servicii de care aș fi avut nevoie pentru dezvoltarea întregii platforme. Asta pentru a putea mai întâi dezvoltă totul în local fără să consum inutil resurse pe un server remote. Dar totuși, trebuia să știu de la început ce voi folosi și în faza de producție, că să creez un ambient asemănător în local. Alegerea pentru providerul remote a fost relativ simplă. Aveam deja un cont pe AWS (Amazon Web Services), și Free-Tier-ul mai dura pe atunci șase luni, deci de ce să nu merg înainte cu AWS? Până la urmă e un serviciu de clasa întâi, dacă sunt atent nici costurile nu se vor ridică prea mult o dată ce se termină Free-Tier-ul. Știu că Amazon Linux 2, cel instalat pe instanțele de Amazon EC2 din Free-Tier e bazat pe CentOS, așa că tot CentOS mi-am și local. Pentru baza de date alesesem deja MySQL, cu care știu să lucrez, și cu motorul InnoDB am tot ce îmi trebuie, asta pe AWS se traduce într-un RDS tot cu MySQL instalat pe el, deci ușor.

Dar eram conștient că a realiza o rețea de socializare făcută cu o baza de date relațională, nu iese tocmai bine, nu e suficient de scalabila, și nici dinamicile unei rețele de socializare (small-world) nu se leagă prea bine de modul de funcționare unei astfel de bază de date. Aș fi avut probleme într-o zi îndepărtată în query-uri de o anumită adâncime când vine vorba de conexiuni, de exemplu. Nu numai din punct de vedere al construcția acestor query-uri, ci și în eficienta din punct de vedere al vitezei query-urilor. Să trec totul deci pe o baza de date de tip Graph? Totuși alte lucruri se pretează mai bine pe o baza de date relațională, cum ar fi setările utilizatorilor, și nu numai, chiar și înregistrarea lor e mult mai comodă pe o astfel de baza de date.

Sigur, puteam să fac o căutare, sau mai multe, să văd cum a rezolvat Facebook, sau alte rețele de socializare această problema, dacă a fost o problema și pentru ei. Dar am preferat să fac cum am simțit eu că e cel mai bine. Așa că am decis să folosesc ambele feluri de baze de date. În felul asta aș fi putut și să despart nu numai conceptual, dar și fizic informațiile utilizatorilor, adăugând un strat de securitate.

Bun deci am instalat, pe lângă serviciul MySQL, și cel de GraphDB.

Am terminat?

Nu. Știam de la început că voi avea nevoie și de un chat în timp real.

Ce să fac, să merg pe WebSocket de la zero, deci să-mi creez propiul protocol de comunicare, sau să merg pe o soluție deja existența. Am decis să mă duc pe a două cale. Aveam deja experiență cu XMPP, una plăcută. E ușor de configurat, merge pe SSL, și are multe module opționale pe care le voi putea integra eventual în viitor, adaptând infrastructură. Așa că am instalat și un serviciu XMPP. 

Următoarea alegere a fost legată de ce limbaj și framework să folosesc. Am fost foarte tentat să mă folosesc de acest proiect pentru a aprofunda Node.js. Dar m-am gândit să nu fac experimente cu un proiect de genul ăsta, să merg pe ceva în care am mai multă experiență, cod de refolosit, și o comunitate mai mare. Așa că am ales PHP, și alegerea framework-ului a venit de la sine: Lravel. Există o librărie care îmi permite o integrare cu Eloquent pentru ceea ce privește GraphDB, îl cunosc bine și mă mișc repede, are comunitate mare dacă și când o să am probleme. Uite așa după câteva ajustări, câteva cron joburi puse la punct, și, recunosc, câteva înjuraturi, aveam un server: Goliath.

Partea de front-end acum.

Aici mi-ar fi plăcut foarte mult să merg pe SwiftUI pe iOS, și Kotlin pe Android, de ceva timp mă îndepărtasem de programarea nativă pe mobile. De un an jumate, dacă nu doi, lucrasem numai pe cross-platform, mai precis cu React Native. Totuși, nu îmi puteam permite să scriu cod pentru două platforme, trebuia să mă îndrept către cross-platfrom, că să pot face un deploy cu un singur code-base pentru ambele sisteme deodată. M-am gândit la Flutter, însă, iarăși, comunitatea mai mare disponibilă pentru React Native, și cod reutilizabil pe care îl aveam pentru anumite funcționalități, m-au făcut să rămân pe librăria inventată de Facebook, ironia sorții.

Toate instrumentele de lucru pentru server și client erau definitivate. Puteam sa mă apuc de partea care îmi place cel mai mult, proiectarea software.

Cuvântul cheie trebuia să fie scalabilitatea, normal.

Nu o să întru în detaliile proiectării, că și transparență are o limita.

Însă ce pot spune e că am decis de la bun început să modific un pic câteva clase din Query Builder-ul din Laravel (de fapt să extind clasele respective) pentru a introduce un sistem de criptare de care să nu mă mai preocup în viitor. M-am gândit să fac în așa fel încât să fie practic imposibil, în nefericitul caz în care cineva pune mâna pe bazele de date ale platformei (cea relațională și cea graph), să poată extrage date sensibile ale utilizatorilor. Evident, parolele oricum ar fi fost criptate, însă am mers mai departe, practic toate datele sunt criptate. De la URL-urile link-urilor media (avatar, imagini din postări și mesaje etc.), până la nume, prenume, email, telefon, și, desigur, datele personale stocate. Cum să fac însă cât mai grea decriptarea bazei de date? 

Am ales cel mai sigur algoritm posibil la dispoziția mea, AES-256.

Că să adaug un strat în plus, am decis și să folosesc chei de criptare diferite pentru diferite câmpuri din baza de date. Asta face imposibilă, sau extrem de grea, decriptarea datelor în totalitatea lor.

Restul a început să vină de la sine. Utilizatorii nu sunt identificați în sistem prin e-mailul lor, deci să scot acest mecanism din procesul de înregistrare a fost floare la ureche, pur și simplu nu aveam nevoie de informația respectivă.

Multe alte lucruri au fost mai simple decât in mod normal, pentru că efectiv nu mă interesează datele utilizatorilor, prezența sau absența lor. E că o povoară de care am scăpat, din punct de vedere al proiectării.

Comunicarea trece prin SSL, standardul să zicem așa.

Un singur lucru nu e standard, ba poate fi considerat chiar bad practice. Sistemul nu foloseste Soft Delete, și nu va folosi vreodată. Când un utilizator vrea să șteargă un dat personal de pe sistem, acel dat se șterge pentru totdeauna. Evident, backup-uri există din motive de maintanance, dar nu există nimic pentru recuperarea “ușoară” a unui dat legat de un utilizator.

Încă până azi rămâne însă o ultimă problema.

Da, există mai multe (20+) chei de criptare pentru diferite date, dar ele sunt în sistemul meu, proiectat și programat de mine. Cum pot da garanția utilizatorilor că nu mă voi folosi de ele pentru  profit? Codul sursă e capabil să decripteze datele, și evident face asta pentru a furniza date lizibile aplicației. Deci cum pot eu garanta utilizatorilor, fără nicio îndoială că nu-mi voi genera o platforma “paralelă” care să-mi furnizeze toate datele lor decriptate. Sigur, pot spune că efortul și timpul pentru asta ar fi cam peste mâna, dar e un argument slab. Sigur, am termeni si conditii, si Privacy Policy, si există GDPR. Dar tot nu mi se pare suficient.

M-am gândit la diferite soluții, dar încă nu am găsit una definitivă, dar va fi una, garantez, și va fi publică până laversiunea finală a aplicației.

În  plus, altă soluție legată de transparență va fi un sistem public, un concept asemănător cu Monitorului Oficial ce există în stat. Un fel de mare log în care să fie vizibilă orice acțiune a oricui în interiorul sistemului, desigur menținând anonimitatea, cu ID-uri “fake”, dar persistente, de exemplu.

Pentru moment, cam atât din punct de vedere tehnic. Critici (constructive), sugestii și orice fel de remarcă sunt mai mult decât bine venite!

Vă voi ține la curent în continuare pe parcurs ce evoluează platforma!

 

https://www.youtube.com/watch?v=HgzGwKwLmgM

Adaugă un comentariu
Numele tau *
Email *
Mesajul tău