ugrás a tartalomhoz

Szoros csatolás kód és adat között

inf · 2017. Nov. 1. (Sze), 00.18
Egy ideje már van egy zsigeri rossz érzésem azzal kapcsolatban, ha kitüntetett adatok vannak az adatbázisban, amelyeknek speciális jelentésük van a kódban. Talán a leggyakoribb ilyen dolog, amikor beleégetik a felhasználói csoportok azonosítóját a kódba, aztán egy init script a rendszer fellövésekor feltölti az adatbázist ezekkel a csoportokkal a megadott id-kkel. Ebben az esetben a csoport id megváltozása az adatbázisban komoly következményekkel járna jogosultság ellenőrzés szempontjából, és elsőre nem feltétlen lenne nyilvánvaló, hogy hol kell keresni a hiba okát. Létezik erre a problémára bármiféle best practice, áttervezés, ami esetleg lazítana a csatoláson?
 
1

A mostani esetem egyébként

inf · 2017. Nov. 1. (Sze), 00.25
A mostani esetem egyébként még érdekesebb, mert egyrészt a domain-nek része a "nyelv" típus, másrészt meg egy gráf adatbázisban is szerepelni fog, mint "fogalom" példány, és a kettőt kellene valahogy összekötnöm, hogy tudja a rendszer, hogy azonosak, és ki tudja keresni a gráf adatbázisból a nyelvek listáját. SQL-nél ez nyilván úgy nézne ki, hogy van egy "nyelvek" tábla, és abban keresgélünk. Végülis ha belegondolok ez a szoros csatolás az SQL-nél is jelen van, csak kevésbé jellemző, hogy táblanevek véletlenül megváltozzanak, és abban az esetben hibaüzenetet kapunk, ha nem találja az adatbázis a táblát.

Ami nekem kimondottan zavaró, hogy előre meg kell szabni egy-egy dolog id-jét az adatbázisban, amikor legtöbbször azt egy generátor hozza létre, és semmi köze nincs hozzá a kódnak, hogy mi legyen. Jobb szeretnék valami olyan rendszert, amiben először berakom az adatot az adatbázisba, aztán kötöm valamilyen konfig fájlhoz a generált id-t, amit esetleg később akár meg is változtathatok, ha okom van rá, anélkül hogy bele kéne túrnom a kódba hozzá.
2

Igen

janoszen · 2017. Nov. 1. (Sze), 00.36
Igen, ez egy ismert problema, ennek feloldasakent szokas azt csinalni, hogy a jogosultsagkezelest pl. csoport-alapon valositod meg, es a DB-ben pedig az egyes csoportokra jellemzo globalis jogosultsagok flagekkent vannak beallitva.

De egyebkent azzal sincs semmi baj sztem ha az alkalmazas minden deploykor megnezi hogy a megfelelo jogosultsagok adatmezoi leteznek-e a DB-ben es ha nem, letrehozza oket, szal nem kell feltetlen oszlopokkent hozzaadni oket.
3

Van egyébként ennek a tünet

inf · 2017. Nov. 1. (Sze), 00.38
Van egyébként ennek a tünet együttesnek valamilyen neve a szaknyelvben? Szívesen utána keresnék.

szerk:

Találtam egy jó topicot a témában: link. Data and code separation-nek hívják.

Az is kiderült miért jön zsigerből, hogyha sérül, akkor valami baj van:

A big technical reason for separating code and data is to not have to recompile the code when the data changes.


Ehhez még kapásból hozzá lehet tenni, hogyha valami változik, akkor bele kell nyúlni a kódba, és ott átírni az id-ket, vagy ha többféle változat létezik az adadtstruktúrából, akkor folyamatosan bővíteni kell a kódot, amikor hozzáadunk egy új változatot (pl amikor egy új nyelvet adunk hozzá a nyelvek listájához), és így tovább. Nyilván ezért akar bizonyos adatokat az ember adatbázisban vagy config fájlban tárolni a kód helyett.

Szvsz teljesen automatikus init script helyett valamilyen félautomatikus megoldás kellene, esetleg más elveken felépülő. pl a jogosultságnál az init script csinálhatna valami ilyesmit:

var admin = new Group(new GroupId(), "administrator");
GroupRepo.add(admin); 
//...
var config = ConfigRepo.find();
config.setAdmin(admin.id);
ConfigRepo.save(config);
Így az id nem lenne beégetve a kódba, és a konfigon is lehetne változtatni később a megfelelő webes felülettel valami superadmin accounttal esetleg. Lehetne akár manuálisan is hozzákötni az admin csoportot a konfig-hoz webes felületről ugyanezzel az accounttal induláskor, nem muszáj teljesen automatizálni, a lényeg, hogy a konfig tudjon róla, hogy az inithez szükség van bizonyos paraméterekre, és addig ne menjen tovább, amíg azok nincsenek megadva.

Azt hiszem ezzel meg is válaszoltam a kérdésem, lehetséges a laza csatolás elérése megfelelő init scripttel.
5

Messze

janoszen · 2017. Nov. 1. (Sze), 18.40
Messze nem akkora problema ez mint amilyennek elsore tunik, csak arrol kell gondoskodni, hogy:

a) azon adatokat soha ne akarja senki kezzel modositani. Tehat pl. az, hogy milyen csoportok vanank nem jo megoldas. Az viszont hogy milyen elemi permissionok vannak a rendszerben, az egy olyan dolog amihez kodmodositas kell.

b) a rendszer tartsa karban automatikusan az adatokat deploykor. Ne kelljen kezzel buheralni.

Es akkor mindjart nincs problema.
4

Én azt szoktam csinálni, hogy

smokey · 2017. Nov. 1. (Sze), 18.29
Én azt szoktam csinálni, hogy alkalmazás szinten permissionöket definiálok. Pl.: MANAGE_USERS, ACCSESS_PRODUCTS, UPLOAD_PRODUCT. Ezeket általában konstansok, amiket elérek alkalmazás szinten. Ezek a konstansok blokkolják/engedélyezik az egyes feature-öket.

Adatbázisban user role-okat definiálok. Minden role-hoz tartozik több permission, illetve minden userhez kapcsolódhat több role is. Előfordulhat, hogy egy user egy permissiont többször is megkap ez által, de ez nem probléma, mert unioban érkezik az adat.

Ezzel elértem azt, hogy adatbázis szinten osztok ki jogokat. Lekérem a felhasználóhoz tartozó roleokat, majd ez alapján az összes permissiont. Így kaptam egy felhasználóhoz rendelt permission listát. Ha egy funkciót el akar érni a user, ami csak egy bizonyos permission megléte mellett elérhető, akkor megvizsgálom, hogy hozzá van-e rendelve az a bizonyos permission, és ha ign, akkor tovább engedem, ha nem, akkor lekezelem megfelelő módon.

Ez kb ugyanaz, amit te csinálsz, viszont fordítva:
- a te esetedben az alkalmazás függ az adatbázistól
- az én esetben az adatbázis függ az alkalmazástól

Nekem ez a módszer bevált már sokszor, megspóroltam vele azt a szívást, amitől te is tartasz.
6

Amit leírtál az a klasszikus

inf · 2017. Nov. 3. (P), 04.20
Amit leírtál az a klasszikus RBAC (role based access control). Nem tudom, hogy még az eredeti kérdésre válaszoltál e, vagy amit utána írtam, így kontextus nélkül nehéz válaszolni. Egyelőre csak annyi körvonalazódott bennem, hogy az ilyen konstansoknál az értéket mindenképp jobb kiemelni a kódból máshová. Pl ha MANAGE_USERS=1, ACCSESS_PRODUCTS=2, UPLOAD_PRODUCT=3 a konstansok értékei, akkor kapásból egy rejtett invariánst tartasz fent kézzel, mert unique értékekről van szó, amit azzal próbálsz betartatni, hogy szekvenciát használsz az értékeknél. Ha véletlenül elírod, és ugyanazt az értéket osztod ki, akkor gond van. Ha ezeket az értékeket és nem a konstans neveket használod az adatbázisban, akkor szintén gond van, mert a kód módosítása eltöri az adatbázist, és migrációs kódot kell írnod rá. Ha a konstans nevek helyett szintén az értékeket használod valami miatt, mint Hidvégi úr, az eléggé error prone, és a rendszer ezt sajnos nem akadályozza, tehát egy kezdő kolléga megcsinálhatja hibaüzenet nélkül, mert pl rövidebb, ha számot használ a konstans neve helyett. Szóval ennek a módszernek azért vannak gyengeségei, ha általános értelemben konfigurálásról beszélünk. Én valami sokkal explicitebb, kifejezőbb módszert szeretnék, aminél ránézésre megmondható, hogy mit csinál a kód, mik az invariánsok, és nehezebben törik el. Egyelőre még agyalok rajta, hogy az eddigi képbe hogyan illik egy ilyen konfiguráció és hogyan tudnám nem túl overengineered módon megvalósítani. Mindenesetre látok benne fantáziát.