Amice, ești idiot!

N-ai cu ce, mă! N-ai cu ce!
Published on January 21, 2020
2020 harangues

About 9 minutes of reading.


În loc de „nu știu alții cum sunt”, eu știu foarte bine cum sunt alții. Unii sunt proști, alții tolerabili, iar alții sunt buni - mai buni decât mine. De la cei din urmă - adică cei mai buni - vreau să învăț, să nu fac greșelile pe care le-au făcut ei, care va să zică să fiu eficient. Pentru că eficiența este o parte integrantă a legii conservării energiei, drept pentru care a fi ineficient reprezintă - în capul meu - a fi împotriva curentului.

O poveste mai veche

În vară am reușit să intru într-un așa zis conflict datorat unei probleme de securitate.

Ca să descriu în limbaj trivial, în momentul în care un client (persoană fizică sau server) se adresează unui server cu o cerere, este necesar să facă dovada că el are dreptul să facă acea operațiune. În cazul nostru, a fost ales standardul ce poartă numele de JWT - nu o să expun motivele aici.

La autentificare, clientului i se înmânează o cheie (token) de către server, criptată cu un secret cunoscut doar de către server. În informația criptată se depozitează informații cum ar fi identificatorul unic al utilizatorului, pentru a evita cazurile de impersonare (de exemplu, mă autentific la bancă cu userul și parola mea, dar cererile de plată le fac cu o cheie care conține identificatorul unic al altcuiva - drept consecință, dacă serverul nu verifică impersonarea, apar fraude). În cazul din această poveste, pe lângă informația despre utilizator sunt prezente - cu titlul opțional - anumite informații despre context.

Ei, ce-au făcut „turiștii” care au lucrat la acest proiect:

Măsurile pe care le-am propus sunt simple:

  1. folosirea unei structuri unice pentru cheia JWT. Dacă există informații opționale, acestea pot avea valoari implicită - astfel, nu este nevoie să facem subspecii și putem deschide spre consum anumite microservicii fără a fi necesar să scriem cod suplimentar.

  2. cheia JWT se transmite către utilizatori în header-ul HTTP, acolo unde-i este locul. De ce? Păi în primul rând pentru respectarea standardelor. În al doilea rând pentru că răspunsul „utilizabil” trebuie să fie cât mai curat și cu informația cât mai condensată. Ce să mai spun: nu amestecăm capra cu varza și culoarea butonului…

  3. ca măsură de securitate, secretul cu care este criptată cheia se poate schimba automatizat (pentru absolut toți actorii participanți) la un interval de timp, așa cum este normal. În acest moment, cheile respective trebuie schimbate la mână și dacă ceva se schimbă în Matrix, atunci el trebuie schimbat și în Matrix II. Ce să vezi: Matrix II depinde de Matrix III care are o altă cheie și uite-așa ne împușcăm singurei în piciorușe.

  4. în timp, să se adauge verificare impersonării în locurile în care acest lucru este critic, ceea ce acum nu există. Și nu există pentru că suntem la Grădinița SRL, unde folosim id-uri din baza de date ca pe constante universale, alături de Bolzman și viteza luminii.

Răspunsul a fost „nu!”. Deși mi s-a dat dreptate, au motivat că e prea mult de lucru. Eu asta nu am înțeles niciodată: ce înseamnă prea mult de lucru? Când rezolvăm o gașcă atât de mare de probleme (poate nu le-am scris pe toate aici, dar sunt sigur că se văd multe dintre implicații), ce dracu’ înseamnă prea mult de lucru?

Acum o săptămână, episodul s-a repetat: mi-a fost cerut să adaptez codul „nou” - care ar fi trebuit să evite toate prostiile făcute în trecut - la codul „vechi”, adică ăla care e conform cu prostiile și amatorismele unor „turiști” cărora li s-a arătat unde să se pișe și s-au pișat. M-am opus din nou, făcând cunoscute argumentele de mai sus. Mi s-a dat iar dreptate (am saci întregi în balcon), fără însă să facem ce trebuie.

Amice…

Deși ar fi trebuit să-mi fie învățătură de minte, nu mă pot obișnui cu direcția în care îmi este indicat să merg. Și nu e o chestie personală. Și nici de orgoliu. Mie îmi pare o chestie de eficiență. Mai bine zis, de ineficiență. Am fost adus pe post de expert. Sunt folosit pe post de „turist”. Să-mi văd de treabă, să scriu cod… Whatever that means!

Este o dovadă de incongruență, să-i spui unui om că este cea mai experimentată resursă într-un domeniu și-api să-i ignori toate propunerile pe care le are. Și când spun toate, adică toate. Deși ulterior, se conving că am dreptate, de obicei e prea târziu: munca necesară să aduci totul la nivelul la care putea să fie dacă propunerea era acceptată, este consistentă. Mai rău este că dau dovadă de prostie, uitând că de fapt ceea ce adoptă a fost propus cu ceva timp în urmă.

… ești idiot

Astăzi, deschid emailul și ce să vezi…

Un pic de preambul: interfețele în Go sunt dificil de înțeles. Ele nu sunt un contract, așa cum sunt în alte limbaje. Sunt mai degrabă definiția a ceea ce „cineva” poate să facă. Motivul care a stat la baza acestui design e simplu: nu e nevoie să declari că „cineva” implementează interfețele X, Y și Z. Este suficient ca acel „cineva” să aibă semnătura corectă.

Acest „feature” al interfețelor în Go te ajută să te concentrezi la ce ai de făcut, nu la legăturile - de obicei restrictive - dintre componente. Este ca și cum ai spune, „dacă ceva poate face asta, atunci el poate fi folosit aici”, fără să știi toate detaliile despre acel cineva. Am văzut de multe ori declarații de interfețe largi în Go: se cunoaște de la o poștă că programatorul respectiv are un mind-set diferit - vine din Java, PHP sau Python - pentru că dorința asta de over-engineering (class all the things) nu poate veni din altă parte. Știu asta : am fost acolo.

Poate ar trebui să scriu o întreagă poveste despre asta - Be conservative with what you do, be liberal with you accept - într-o postare separată.

Înapoi la emailurile noastre: mi-a fost refuzat un pull-request pentru un client care ședea lângă server-ul său, pe motivele următoare:

Respectivul mesaj se încheia cu: „dacă ai chef de vorbă pe subiectul ăsta, adresează-te lui cutărică.”

Pam-pam!

Care va să zică, mon cher: dacă definești clientul unui server, în locul în care definești și serverul obții următoarele lucruri:

Dacă e de neglijat or ba, rămâne de văzut.

Oricum, „clienții pot fi scriși în orice limbaj, drept pentru care clientul pentru Go nu furnizează un beneficiu pentru orice consumator al server-ului respectiv” nici măcar nu e un argument. E o bășină pe post de argument. Despre versionare, numai de bine: mă bucur că avem așa instrucțiuni de implementare - nu înseamnă altceva decât că o să avem de lucru continuu. Pentru orice adăugare de funcționalități va trebui să scriem de două ori mai mult cod, să facem două deployment-uri, să vedem cum se pupă între ele și alte chestiuni de proces de dezvoltare de software.

Păi ce să mă mai adresez lui cutărică, când decizia a fost luată? Nici măcar n-am fost întrebat, deși am vorbit despre tema asta neîntrebat. La ce dracu’ mai spui că știu cel mai bine Go, dacă tu nu mă lași să-mi fac treaba de consultant?

În loc de concluzie

Bineînțeles că m-am supărat!

Știam de foarte mult timp că sunt la „Grădinița SRL”.

Mi s-a cerut răbdare. Am avut!

Mi s-a cerut să contribui cu idei, standarde și propuneri. Am făcut-o!

Suntem însă pe același drum, unul al imposturii și al prostiei la rang de arhitectură. Mai bine zis „arhite-n-gură”.

Mi-am propus să nu mai contribui. De niciun fel! Dar n-o să pot, pentru că nu-mi place direcția în care duce acest lucru. Renunțarea la principii nu e ceva care se poate face cu ușurință, la o apăsare de buton. O să-mi rămână, așadar să înjur aici, în continuare, fiind o metodă de descărcare, până reușim să mai concediem din impostori.

Nu-mi plac impostorii dintr-un motiv organic: ajung curând să mă îndoiesc de ceea ce știu că știu.

De asta spun: „Amice, ești idiot!”

comments powered by Disqus