[{"data":1,"prerenderedAt":2735},["ShallowReactive",2],{"navigation_docs_hu":3,"-hu-auth-policy":442,"-hu-auth-policy-surround":2730},[4,45,60,81,112,129,146,173,197,213,242,280,357,373,385,404,430],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":44},"Kezdő lépések","i-lucide-rocket","\u002Fhu\u002Fgetting-started","hu\u002F1.getting-started",[10,15,20,24,29,34,39],{"title":11,"path":12,"stem":13,"icon":14},"Bevezetés","\u002Fhu\u002Fgetting-started\u002Fintroduction","hu\u002F1.getting-started\u002F1.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Laravelből érkezőknek","\u002Fhu\u002Fgetting-started\u002Fcoming-from-laravel","hu\u002F1.getting-started\u002F2.coming-from-laravel","i-lucide-arrow-right-left",{"title":21,"path":22,"stem":23,"icon":19},"Symfonyból érkezőknek","\u002Fhu\u002Fgetting-started\u002Fcoming-from-symfony","hu\u002F1.getting-started\u002F3.coming-from-symfony",{"title":25,"path":26,"stem":27,"icon":28},"Telepítés","\u002Fhu\u002Fgetting-started\u002Finstallation","hu\u002F1.getting-started\u002F4.installation","i-lucide-download",{"title":30,"path":31,"stem":32,"icon":33},"Az első modulod","\u002Fhu\u002Fgetting-started\u002Ffirst-module","hu\u002F1.getting-started\u002F5.first-module","i-lucide-package-plus",{"title":35,"path":36,"stem":37,"icon":38},"Projektstruktúra","\u002Fhu\u002Fgetting-started\u002Fproject-structure","hu\u002F1.getting-started\u002F6.project-structure","i-lucide-folder-tree",{"title":40,"path":41,"stem":42,"icon":43},"A shop mintaalkalmazás","\u002Fhu\u002Fgetting-started\u002Fsample-app","hu\u002F1.getting-started\u002F7.sample-app","i-lucide-shopping-cart",false,{"title":46,"icon":47,"path":48,"stem":49,"children":50,"page":44},"queue","i-lucide-layers","\u002Fhu\u002Fqueue","hu\u002F10.queue",[51,56],{"title":52,"path":53,"stem":54,"icon":55},"Áttekintés","\u002Fhu\u002Fqueue\u002Foverview","hu\u002F10.queue\u002F1.overview","i-lucide-list-ordered",{"title":57,"path":58,"stem":59,"icon":47},"Taskok","\u002Fhu\u002Fqueue\u002Ftasks","hu\u002F10.queue\u002F2.tasks",{"title":61,"icon":62,"path":63,"stem":64,"children":65,"page":44},"events","i-lucide-workflow","\u002Fhu\u002Fevents","hu\u002F11.events",[66,71,76],{"title":67,"path":68,"stem":69,"icon":70},"Események","\u002Fhu\u002Fevents\u002Foverview","hu\u002F11.events\u002F1.overview","i-lucide-radio",{"title":72,"path":73,"stem":74,"icon":75},"Outbox","\u002Fhu\u002Fevents\u002Foutbox","hu\u002F11.events\u002F2.outbox","i-lucide-inbox",{"title":77,"path":78,"stem":79,"icon":80},"Ütemezés","\u002Fhu\u002Fevents\u002Fscheduler","hu\u002F11.events\u002F3.scheduler","i-lucide-calendar-clock",{"title":82,"icon":83,"path":84,"stem":85,"children":86,"page":44},"auth","i-lucide-shield-check","\u002Fhu\u002Fauth","hu\u002F12.auth",[87,92,97,102,107],{"title":88,"path":89,"stem":90,"icon":91},"Autentikáció","\u002Fhu\u002Fauth\u002Foverview","hu\u002F12.auth\u002F1.overview","i-lucide-key-round",{"title":93,"path":94,"stem":95,"icon":96},"RBAC","\u002Fhu\u002Fauth\u002Frbac","hu\u002F12.auth\u002F2.rbac","i-lucide-users",{"title":98,"path":99,"stem":100,"icon":101},"Policy-k","\u002Fhu\u002Fauth\u002Fpolicy","hu\u002F12.auth\u002F3.policy","i-lucide-gavel",{"title":103,"path":104,"stem":105,"icon":106},"Az auth önálló használata","\u002Fhu\u002Fauth\u002Fstandalone","hu\u002F12.auth\u002F4.standalone","i-lucide-plug",{"title":108,"path":109,"stem":110,"icon":111},"Social login goth-tal, önállóan","\u002Fhu\u002Fauth\u002Fsocial-standalone","hu\u002F12.auth\u002F5.social-standalone","i-lucide-log-in",{"title":113,"icon":114,"path":115,"stem":116,"children":117,"page":44},"mail","i-lucide-mail","\u002Fhu\u002Fmail","hu\u002F13.mail",[118,121,125],{"title":52,"path":119,"stem":120,"icon":114},"\u002Fhu\u002Fmail\u002Foverview","hu\u002F13.mail\u002F1.overview",{"title":122,"path":123,"stem":124,"icon":114},"SMTP","\u002Fhu\u002Fmail\u002Fsmtp","hu\u002F13.mail\u002F2.smtp",{"title":126,"path":127,"stem":128,"icon":114},"MJML","\u002Fhu\u002Fmail\u002Fmjml","hu\u002F13.mail\u002F3.mjml",{"title":130,"icon":131,"path":132,"stem":133,"children":134,"page":44},"notify","i-lucide-bell","\u002Fhu\u002Fnotify","hu\u002F14.notify",[135,138,142],{"title":52,"path":136,"stem":137,"icon":131},"\u002Fhu\u002Fnotify\u002Foverview","hu\u002F14.notify\u002F1.overview",{"title":139,"path":140,"stem":141,"icon":131},"Database csatorna","\u002Fhu\u002Fnotify\u002Fdatabase","hu\u002F14.notify\u002F2.database",{"title":143,"path":144,"stem":145,"icon":131},"Broadcast csatorna","\u002Fhu\u002Fnotify\u002Fbroadcast","hu\u002F14.notify\u002F3.broadcast",{"title":147,"icon":148,"path":149,"stem":150,"children":151,"page":44},"storage","i-lucide-hard-drive","\u002Fhu\u002Fstorage","hu\u002F15.storage",[152,155,159,163,168],{"title":52,"path":153,"stem":154,"icon":148},"\u002Fhu\u002Fstorage\u002Foverview","hu\u002F15.storage\u002F1.overview",{"title":156,"path":157,"stem":158},"Disk API","\u002Fhu\u002Fstorage\u002Fdisk-api","hu\u002F15.storage\u002F2.disk-api",{"title":160,"path":161,"stem":162,"icon":148},"Memória és helyi lemez","\u002Fhu\u002Fstorage\u002Flocal","hu\u002F15.storage\u002F3.local",{"title":164,"path":165,"stem":166,"icon":167},"S3","\u002Fhu\u002Fstorage\u002Fs3","hu\u002F15.storage\u002F4.s3","i-lucide-cloud",{"title":169,"path":170,"stem":171,"icon":172},"Tesztelés","\u002Fhu\u002Fstorage\u002Ftesting","hu\u002F15.storage\u002F5.testing","i-lucide-flask-conical",{"title":174,"icon":175,"path":176,"stem":177,"children":178,"page":44},"telemetry","i-lucide-activity","\u002Fhu\u002Ftelemetry","hu\u002F16.telemetry",[179,182,187,192],{"title":52,"path":180,"stem":181,"icon":175},"\u002Fhu\u002Ftelemetry\u002Foverview","hu\u002F16.telemetry\u002F1.overview",{"title":183,"path":184,"stem":185,"icon":186},"Logolás","\u002Fhu\u002Ftelemetry\u002Flogging","hu\u002F16.telemetry\u002F2.logging","i-lucide-scroll-text",{"title":188,"path":189,"stem":190,"icon":191},"OpenTelemetry","\u002Fhu\u002Ftelemetry\u002Fopentelemetry","hu\u002F16.telemetry\u002F3.opentelemetry","i-lucide-radar",{"title":193,"path":194,"stem":195,"icon":196},"Sentry","\u002Fhu\u002Ftelemetry\u002Fsentry","hu\u002F16.telemetry\u002F4.sentry","i-lucide-bug",{"title":198,"icon":199,"path":200,"stem":201,"children":202,"page":44},"Referencia","i-lucide-book-open","\u002Fhu\u002Freference","hu\u002F17.reference",[203,208],{"title":204,"path":205,"stem":206,"icon":207},"Konfiguráció","\u002Fhu\u002Freference\u002Fconfiguration","hu\u002F17.reference\u002F1.configuration","i-lucide-settings",{"title":209,"path":210,"stem":211,"icon":212},"Külső függőségek","\u002Fhu\u002Freference\u002Fdependencies","hu\u002F17.reference\u002F2.dependencies","i-lucide-package",{"title":214,"icon":215,"path":216,"stem":217,"children":218,"page":44},"Koncepciók","i-lucide-lightbulb","\u002Fhu\u002Fconcepts","hu\u002F2.concepts",[219,223,228,232,237],{"title":220,"path":221,"stem":222,"icon":47},"Architektúra","\u002Fhu\u002Fconcepts\u002Farchitecture","hu\u002F2.concepts\u002F1.architecture",{"title":224,"path":225,"stem":226,"icon":227},"Hibamodell","\u002Fhu\u002Fconcepts\u002Ferror-model","hu\u002F2.concepts\u002F2.error-model","i-lucide-shield-alert",{"title":204,"path":229,"stem":230,"icon":231},"\u002Fhu\u002Fconcepts\u002Fconfiguration","hu\u002F2.concepts\u002F3.configuration","i-lucide-settings-2",{"title":233,"path":234,"stem":235,"icon":236},"Codegen pipeline","\u002Fhu\u002Fconcepts\u002Fcodegen-pipeline","hu\u002F2.concepts\u002F4.codegen-pipeline","i-lucide-file-json",{"title":238,"path":239,"stem":240,"icon":241},"Design patternek","\u002Fhu\u002Fconcepts\u002Fdesign-patterns","hu\u002F2.concepts\u002F5.design-patterns","i-lucide-puzzle",{"title":243,"icon":244,"path":245,"stem":246,"children":247,"page":44},"A kit","i-lucide-box","\u002Fhu\u002Fkit","hu\u002F3.kit",[248,252,257,262,267,271,276],{"title":249,"path":250,"stem":251,"icon":244},"A kit áttekintése","\u002Fhu\u002Fkit\u002Foverview","hu\u002F3.kit\u002F1.overview",{"title":253,"path":254,"stem":255,"icon":256},"Alkalmazás-életciklus","\u002Fhu\u002Fkit\u002Fapp","hu\u002F3.kit\u002F2.app","i-lucide-power",{"title":258,"path":259,"stem":260,"icon":261},"Szerver","\u002Fhu\u002Fkit\u002Fserver","hu\u002F3.kit\u002F3.server","i-lucide-server",{"title":263,"path":264,"stem":265,"icon":266},"Worker","\u002Fhu\u002Fkit\u002Fworker","hu\u002F3.kit\u002F4.worker","i-lucide-cog",{"title":268,"path":269,"stem":270,"icon":70},"Realtime","\u002Fhu\u002Fkit\u002Frealtime","hu\u002F3.kit\u002F5.realtime",{"title":272,"path":273,"stem":274,"icon":275},"Migrációk","\u002Fhu\u002Fkit\u002Fmigrations","hu\u002F3.kit\u002F6.migrations","i-lucide-file-stack",{"title":277,"path":278,"stem":279,"icon":111},"Social login","\u002Fhu\u002Fkit\u002Fsocial-login","hu\u002F3.kit\u002F7.social-login",{"title":281,"icon":282,"path":283,"stem":284,"children":285,"page":44},"CLI referencia","i-lucide-terminal","\u002Fhu\u002Fcli","hu\u002F4.cli",[286,289,294,299,304,309,314,319,324,329,334,338,343,348,352],{"title":52,"path":287,"stem":288,"icon":282},"\u002Fhu\u002Fcli\u002Foverview","hu\u002F4.cli\u002F1.overview",{"title":290,"path":291,"stem":292,"icon":293},"add db","\u002Fhu\u002Fcli\u002Fadd-db","hu\u002F4.cli\u002F10.add-db","i-lucide-database-zap",{"title":295,"path":296,"stem":297,"icon":298},"add compose \u002F add docker","\u002Fhu\u002Fcli\u002Fadd-compose","hu\u002F4.cli\u002F11.add-compose","i-lucide-container",{"title":300,"path":301,"stem":302,"icon":303},"add mail","\u002Fhu\u002Fcli\u002Fadd-mail","hu\u002F4.cli\u002F12.add-mail","i-lucide-mail-plus",{"title":305,"path":306,"stem":307,"icon":308},"add notification","\u002Fhu\u002Fcli\u002Fadd-notification","hu\u002F4.cli\u002F13.add-notification","i-lucide-bell-plus",{"title":310,"path":311,"stem":312,"icon":313},"add realtime","\u002Fhu\u002Fcli\u002Fadd-realtime","hu\u002F4.cli\u002F14.add-realtime","i-lucide-radio-tower",{"title":315,"path":316,"stem":317,"icon":318},"add seeder","\u002Fhu\u002Fcli\u002Fadd-seeder","hu\u002F4.cli\u002F15.add-seeder","i-lucide-sprout",{"title":320,"path":321,"stem":322,"icon":323},"new project","\u002Fhu\u002Fcli\u002Fnew-project","hu\u002F4.cli\u002F2.new-project","i-lucide-folder-plus",{"title":325,"path":326,"stem":327,"icon":328},"new module","\u002Fhu\u002Fcli\u002Fnew-module","hu\u002F4.cli\u002F3.new-module","i-lucide-blocks",{"title":330,"path":331,"stem":332,"icon":333},"add surface","\u002Fhu\u002Fcli\u002Fadd-surface","hu\u002F4.cli\u002F4.add-surface","i-lucide-layers-2",{"title":335,"path":336,"stem":337,"icon":244},"add core","\u002Fhu\u002Fcli\u002Fadd-core","hu\u002F4.cli\u002F5.add-core",{"title":339,"path":340,"stem":341,"icon":342},"add handler","\u002Fhu\u002Fcli\u002Fadd-handler","hu\u002F4.cli\u002F6.add-handler","i-lucide-webhook",{"title":344,"path":345,"stem":346,"icon":347},"new migration","\u002Fhu\u002Fcli\u002Fnew-migration","hu\u002F4.cli\u002F7.new-migration","i-lucide-file-plus",{"title":349,"path":350,"stem":351,"icon":266},"worker generátorok","\u002Fhu\u002Fcli\u002Fworker-generators","hu\u002F4.cli\u002F8.worker-generators",{"title":353,"path":354,"stem":355,"icon":356},"upgrade templates","\u002Fhu\u002Fcli\u002Fupgrade-templates","hu\u002F4.cli\u002F9.upgrade-templates","i-lucide-refresh-cw",{"title":358,"icon":227,"path":359,"stem":360,"children":361,"page":44},"errs","\u002Fhu\u002Ferrs","hu\u002F5.errs",[362,365,369],{"title":52,"path":363,"stem":364,"icon":227},"\u002Fhu\u002Ferrs\u002Foverview","hu\u002F5.errs\u002F1.overview",{"title":366,"path":367,"stem":368},"API","\u002Fhu\u002Ferrs\u002Fapi","hu\u002F5.errs\u002F2.api",{"title":370,"path":371,"stem":372,"icon":227},"Integráció","\u002Fhu\u002Ferrs\u002Fintegration","hu\u002F5.errs\u002F3.integration",{"title":374,"icon":231,"path":375,"stem":376,"children":377,"page":44},"envconf","\u002Fhu\u002Fenvconf","hu\u002F6.envconf",[378,381],{"title":52,"path":379,"stem":380,"icon":231},"\u002Fhu\u002Fenvconf\u002Foverview","hu\u002F6.envconf\u002F1.overview",{"title":382,"path":383,"stem":384},"Receptek","\u002Fhu\u002Fenvconf\u002Frecipes","hu\u002F6.envconf\u002F2.recipes",{"title":386,"icon":387,"path":388,"stem":389,"children":390,"page":44},"httperr","i-lucide-globe","\u002Fhu\u002Fhttperr","hu\u002F7.httperr",[391,394,399],{"title":52,"path":392,"stem":393,"icon":387},"\u002Fhu\u002Fhttperr\u002Foverview","hu\u002F7.httperr\u002F1.overview",{"title":395,"path":396,"stem":397,"icon":398},"Hibaválaszok","\u002Fhu\u002Fhttperr\u002Ferror-responses","hu\u002F7.httperr\u002F2.error-responses","i-lucide-octagon-alert",{"title":400,"path":401,"stem":402,"icon":403},"Validáció","\u002Fhu\u002Fhttperr\u002Fvalidation","hu\u002F7.httperr\u002F3.validation","i-lucide-badge-check",{"title":405,"icon":406,"path":407,"stem":408,"children":409,"page":44},"dbx","i-lucide-database","\u002Fhu\u002Fdbx","hu\u002F8.dbx",[410,413,417,421,426],{"title":52,"path":411,"stem":412,"icon":406},"\u002Fhu\u002Fdbx\u002Foverview","hu\u002F8.dbx\u002F1.overview",{"title":414,"path":415,"stem":416,"icon":106},"pgx","\u002Fhu\u002Fdbx\u002Fpg","hu\u002F8.dbx\u002F2.pg",{"title":418,"path":419,"stem":420,"icon":47},"bun","\u002Fhu\u002Fdbx\u002Fbunx","hu\u002F8.dbx\u002F3.bunx",{"title":422,"path":423,"stem":424,"icon":425},"Tranzakciók","\u002Fhu\u002Fdbx\u002Ftransactions","hu\u002F8.dbx\u002F4.transactions","i-lucide-git-merge",{"title":427,"path":428,"stem":429,"icon":318},"Seederek","\u002Fhu\u002Fdbx\u002Fseed","hu\u002F8.dbx\u002F5.seed",{"title":431,"icon":55,"path":432,"stem":433,"children":434,"page":44},"paginate","\u002Fhu\u002Fpaginate","hu\u002F9.paginate",[435,438],{"title":52,"path":436,"stem":437,"icon":55},"\u002Fhu\u002Fpaginate\u002Foverview","hu\u002F9.paginate\u002F1.overview",{"title":439,"path":440,"stem":441,"icon":19},"Cursor-lapozás","\u002Fhu\u002Fpaginate\u002Fcursor","hu\u002F9.paginate\u002F2.cursor",{"id":443,"title":98,"body":444,"description":2723,"extension":2724,"links":2725,"meta":2726,"navigation":2727,"path":99,"seo":2728,"stem":100,"__hash__":2729},"docs_hu\u002Fhu\u002F12.auth\u002F3.policy.md",{"type":445,"value":446,"toc":2716},"minimark",[447,456,485,519,522,527,534,595,648,804,811,890,905,909,912,976,983,990,1140,1146,1271,1281,1644,1661,1675,1697,1701,1704,1798,1809,1813,1835,2458,2476,2483,2592,2607,2611,2623,2695,2712],[448,449,450,451,455],"p",{},"Importáld a ",[452,453,454],"code",{},"policy"," alcsomagot, hogy kérésenkénti authorizációs ellenőrzéseket deklarálj:",[457,458,463],"pre",{"className":459,"code":460,"language":461,"meta":462,"style":462},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import \"github.com\u002Fgp-system\u002Fauth\u002Fpolicy\"\n","go","",[452,464,465],{"__ignoreMap":462},[466,467,470,474,478,482],"span",{"class":468,"line":469},"line",1,[466,471,473],{"class":472},"s7zQu","import",[466,475,477],{"class":476},"sMK4o"," \"",[466,479,481],{"class":480},"sBMFI","github.com\u002Fgp-system\u002Fauth\u002Fpolicy",[466,483,484],{"class":476},"\"\n",[448,486,487,488,490,491,493,494,497,498,502,503,506,507,510,511,514,515,518],{},"A ",[452,489,454],{}," az ",[452,492,82],{}," modul kérésenkénti authorizációs alcsomagja. Az ",[495,496,93],"a",{"href":94}," durva szemcséjű: azt mondja meg, a hívó ",[499,500,501],"em",{},"általában"," végrehajthatja-e a műveletet. A ",[504,505,454],"strong",{}," azt dönti el, hogy ",[499,508,509],{},"ezen a konkrét kérésen"," végrehajthatja-e (tulajdonos-e, egy tenantban vannak-e, megfelelő állapotban van-e a rekord). Erre a szerep nem elég: az, hogy valakinek van ",[452,512,513],{},"orders.view"," permissionje, nem mondja meg, hogy a ",[499,516,517],{},"42-es"," rendelést megnézheti-e.",[448,520,521],{},"A policy-t a TypeSpec-kontraktus rendeli a művelethez, és a generált enforcer-middleware kényszeríti ki: nem tudod kihagyni, és a hiányzó implementáció nem átenged, hanem hibázik (fail-closed).",[523,524,526],"h2",{"id":525},"a-policy-mint-függvény","A policy mint függvény",[448,528,529,530,533],{},"Egy policy egy nevesített ",[452,531,532],{},"Func",":",[457,535,537],{"className":459,"code":536,"language":461,"meta":462,"style":462},"type Func func(ctx context.Context, id *rbac.Identity, req any) error\n",[452,538,539],{"__ignoreMap":462},[466,540,541,544,547,550,554,557,560,563,566,569,572,575,577,580,582,585,588,591],{"class":468,"line":469},[466,542,543],{"class":476},"type",[466,545,546],{"class":480}," Func",[466,548,549],{"class":476}," func(",[466,551,553],{"class":552},"sHdIc","ctx",[466,555,556],{"class":480}," context",[466,558,559],{"class":476},".",[466,561,562],{"class":480},"Context",[466,564,565],{"class":476},",",[466,567,568],{"class":552}," id",[466,570,571],{"class":476}," *",[466,573,574],{"class":480},"rbac",[466,576,559],{"class":476},[466,578,579],{"class":480},"Identity",[466,581,565],{"class":476},[466,583,584],{"class":552}," req",[466,586,587],{"class":480}," any",[466,589,590],{"class":476},")",[466,592,594],{"class":593},"spNyl"," error\n",[448,596,597,598,603,604,607,608,611,612,615,616,619,620,623,624,627,628,631,632,635,636,639,640,643,644,647],{},"Megkapja a belépett hívót (",[495,599,600],{"href":94},[452,601,602],{},"*rbac.Identity",") és ",[452,605,606],{},"req","-ként a generált, ",[504,609,610],{},"teljesen bekötött"," ",[452,613,614],{},"\u003COp>Request"," structot (body, query- és path-paraméterek együtt), amit type-assertionnel bontasz ki. ",[452,617,618],{},"nil","-lel engedélyez, hibával tilt; a ",[452,621,622],{},"policy.Deny(detail)"," egy ",[452,625,626],{},"*policy.Denial","-t ad vissza, egy sima Go errort, amire ",[452,629,630],{},"errors.Is(err, rbac.ErrForbidden)"," igaz, és aminek a ",[452,633,634],{},"Detail","-je biztonságosan megmutatható a kliensnek. A kit ",[452,637,638],{},"server.WriteError","-ja ",[504,641,642],{},"403","-as ",[495,645,646],{"href":396},"problem","-ként rendereli, ezzel az üzenettel:",[457,649,651],{"className":459,"code":650,"language":461,"meta":462,"style":462},"func(ctx context.Context, id *rbac.Identity, req any) error {\n    r, ok := req.(shopapigen.GetOrderRequest)\n    if !ok {\n        return policy.Deny(\"unexpected request type\")\n    }\n    \u002F\u002F ... döntés r és id alapján\n    return nil \u002F\u002F engedélyezve\n}\n",[452,652,653,698,729,744,773,779,786,798],{"__ignoreMap":462},[466,654,655,658,661,664,666,668,670,673,676,678,680,682,684,687,690,692,695],{"class":468,"line":469},[466,656,657],{"class":476},"func(",[466,659,660],{"class":552},"ctx ",[466,662,663],{"class":480},"context",[466,665,559],{"class":476},[466,667,562],{"class":480},[466,669,565],{"class":476},[466,671,672],{"class":552}," id ",[466,674,675],{"class":476},"*",[466,677,574],{"class":480},[466,679,559],{"class":476},[466,681,579],{"class":480},[466,683,565],{"class":476},[466,685,686],{"class":552}," req ",[466,688,689],{"class":480},"any",[466,691,590],{"class":476},[466,693,694],{"class":593}," error",[466,696,697],{"class":476}," {\n",[466,699,701,705,707,710,713,715,718,721,723,726],{"class":468,"line":700},2,[466,702,704],{"class":703},"sTEyZ","    r",[466,706,565],{"class":476},[466,708,709],{"class":703}," ok ",[466,711,712],{"class":476},":=",[466,714,584],{"class":703},[466,716,717],{"class":476},".(",[466,719,720],{"class":480},"shopapigen",[466,722,559],{"class":476},[466,724,725],{"class":480},"GetOrderRequest",[466,727,728],{"class":476},")\n",[466,730,732,735,738,741],{"class":468,"line":731},3,[466,733,734],{"class":472},"    if",[466,736,737],{"class":476}," !",[466,739,740],{"class":703},"ok ",[466,742,743],{"class":476},"{\n",[466,745,747,750,753,755,759,762,765,769,771],{"class":468,"line":746},4,[466,748,749],{"class":472},"        return",[466,751,752],{"class":703}," policy",[466,754,559],{"class":476},[466,756,758],{"class":757},"s2Zo4","Deny",[466,760,761],{"class":476},"(",[466,763,764],{"class":476},"\"",[466,766,768],{"class":767},"sfazB","unexpected request type",[466,770,764],{"class":476},[466,772,728],{"class":476},[466,774,776],{"class":468,"line":775},5,[466,777,778],{"class":476},"    }\n",[466,780,782],{"class":468,"line":781},6,[466,783,785],{"class":784},"sHwdD","    \u002F\u002F ... döntés r és id alapján\n",[466,787,789,792,795],{"class":468,"line":788},7,[466,790,791],{"class":472},"    return",[466,793,794],{"class":476}," nil",[466,796,797],{"class":784}," \u002F\u002F engedélyezve\n",[466,799,801],{"class":468,"line":800},8,[466,802,803],{"class":476},"}\n",[448,805,806,807,810],{},"A policy-k név szerint egy ",[452,808,809],{},"Registry","-ben élnek:",[457,812,814],{"className":459,"code":813,"language":461,"meta":462,"style":462},"reg := policy.NewRegistry()\nreg.Register(\"orders.view\", ordersViewFn) \u002F\u002F ugyanarra a névre másodszor: panic\nfn, ok := reg.Get(\"orders.view\")\n",[452,815,816,833,861],{"__ignoreMap":462},[466,817,818,821,823,825,827,830],{"class":468,"line":469},[466,819,820],{"class":703},"reg ",[466,822,712],{"class":476},[466,824,752],{"class":703},[466,826,559],{"class":476},[466,828,829],{"class":757},"NewRegistry",[466,831,832],{"class":476},"()\n",[466,834,835,838,840,843,845,847,849,851,853,856,858],{"class":468,"line":700},[466,836,837],{"class":703},"reg",[466,839,559],{"class":476},[466,841,842],{"class":757},"Register",[466,844,761],{"class":476},[466,846,764],{"class":476},[466,848,513],{"class":767},[466,850,764],{"class":476},[466,852,565],{"class":476},[466,854,855],{"class":703}," ordersViewFn",[466,857,590],{"class":476},[466,859,860],{"class":784}," \u002F\u002F ugyanarra a névre másodszor: panic\n",[466,862,863,866,868,870,872,875,877,880,882,884,886,888],{"class":468,"line":731},[466,864,865],{"class":703},"fn",[466,867,565],{"class":476},[466,869,709],{"class":703},[466,871,712],{"class":476},[466,873,874],{"class":703}," reg",[466,876,559],{"class":476},[466,878,879],{"class":757},"Get",[466,881,761],{"class":476},[466,883,764],{"class":476},[466,885,513],{"class":767},[466,887,764],{"class":476},[466,889,728],{"class":476},[448,891,487,892,894,895,898,899,901,902,904],{},[452,893,842],{}," duplikált névre ",[504,896,897],{},"panickel",": az bekötési hiba, nem futásidejű állapot. A ",[452,900,879],{}," nil-receiver-biztos: egy nil ",[452,903,809],{}," minden nevet ismeretlennek jelent, ami a lenti szemantikával fail-closed alapértelmezést ad.",[523,906,908],{"id":907},"a-deklaratív-lánc-kontraktustól-az-enforcerig","A deklaratív lánc: kontraktustól az enforcerig",[448,910,911],{},"A policy-t nem a handlerben hívod, hanem a kontraktusban deklarálod, és négy lépésben jut el a futó middleware-ig:",[913,914,915,938,951,964],"ol",{},[916,917,918,921,922,925,926,929,930,933,934,937],"li",{},[504,919,920],{},"TypeSpec",": a ",[452,923,924],{},"@permission(\"...\")"," \u002F ",[452,927,928],{},"@policy(\"...\")"," dekorátorokat teszed a műveletre. A dekorátorokat a projekt-scaffold hozza (",[452,931,932],{},"spec\u002Ftypespec\u002Flib\u002Fpolicy.tsp",", a ",[452,935,936],{},"main.tsp"," importálja).",[916,939,940,943,944,925,947,950],{},[504,941,942],{},"OpenAPI",": az emitter ",[452,945,946],{},"x-permission",[452,948,949],{},"x-policy"," extensionként írja ki őket a spec-be.",[916,952,953,956,957,925,960,963],{},[504,954,955],{},"Generált kód",": az oapi-codegen sablonok műveletenként rögzítik őket a ",[452,958,959],{},"PermissionByOperation",[452,961,962],{},"PolicyByOperation"," mapekben.",[916,965,966,921,969,972,973,975],{},[504,967,968],{},"Futásidő",[452,970,971],{},"policy.Enforcer"," strict-middleware ezekből a mapekből dolgozik, és a ",[452,974,809],{},"-ből futtatja a nevesített policy-t.",[448,977,978,979,982],{},"Egy engine van és egy enforcer: az ",[452,980,981],{},"Enforcer"," chi\u002Fnet-http strict-middleware-ként fut, nincs engine-specifikus változat, amik közül választani kellene.",[448,984,985,986,989],{},"A shop ",[452,987,988],{},"api"," surface-ének rendelés-műveletei így vannak megjelölve:",[457,991,995],{"className":992,"code":993,"language":994,"meta":462,"style":462},"language-tsp shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F spec\u002Ftypespec\u002Fmodules\u002Fshop\u002Fapi.tsp\n@post\n@route(\"\u002Forders\")\n@operationId(\"PlaceOrder\")\n@permission(\"orders.place\")   \u002F\u002F durva szűrés: megvan-e a jog\n@policy(\"orders.place\")       \u002F\u002F finom szűrés: a saját nevében adja-e fel\nplaceOrder(@body body: PlaceOrderInput): Order | Unauthorized | Forbidden;\n\n@get\n@route(\"\u002Forders\u002F{orderId}\")\n@operationId(\"GetOrder\")\n@policy(\"orders.view\")        \u002F\u002F tulajdonos vagy admin\ngetOrder(@path orderId: string): Order | NotFound | Unauthorized | Forbidden;\n","tsp",[452,996,997,1002,1008,1020,1032,1047,1061,1075,1081,1087,1099,1111,1126],{"__ignoreMap":462},[466,998,999],{"class":468,"line":469},[466,1000,1001],{"class":784},"\u002F\u002F spec\u002Ftypespec\u002Fmodules\u002Fshop\u002Fapi.tsp\n",[466,1003,1004],{"class":468,"line":700},[466,1005,1007],{"class":1006},"swJcz","@post\n",[466,1009,1010,1013,1015,1018],{"class":468,"line":731},[466,1011,1012],{"class":1006},"@route",[466,1014,761],{"class":476},[466,1016,1017],{"class":767},"\"\u002Forders\"",[466,1019,728],{"class":476},[466,1021,1022,1025,1027,1030],{"class":468,"line":746},[466,1023,1024],{"class":1006},"@operationId",[466,1026,761],{"class":476},[466,1028,1029],{"class":767},"\"PlaceOrder\"",[466,1031,728],{"class":476},[466,1033,1034,1037,1039,1042,1044],{"class":468,"line":775},[466,1035,1036],{"class":1006},"@permission",[466,1038,761],{"class":476},[466,1040,1041],{"class":767},"\"orders.place\"",[466,1043,590],{"class":476},[466,1045,1046],{"class":784},"   \u002F\u002F durva szűrés: megvan-e a jog\n",[466,1048,1049,1052,1054,1056,1058],{"class":468,"line":781},[466,1050,1051],{"class":1006},"@policy",[466,1053,761],{"class":476},[466,1055,1041],{"class":767},[466,1057,590],{"class":476},[466,1059,1060],{"class":784},"       \u002F\u002F finom szűrés: a saját nevében adja-e fel\n",[466,1062,1063,1066,1069,1072],{"class":468,"line":788},[466,1064,1065],{"class":703},"placeOrder(",[466,1067,1068],{"class":1006},"@body",[466,1070,1071],{"class":703}," body: PlaceOrderInput): Order | Unauthorized | Forbidden",[466,1073,1074],{"class":476},";\n",[466,1076,1077],{"class":468,"line":800},[466,1078,1080],{"emptyLinePlaceholder":1079},true,"\n",[466,1082,1084],{"class":468,"line":1083},9,[466,1085,1086],{"class":1006},"@get\n",[466,1088,1090,1092,1094,1097],{"class":468,"line":1089},10,[466,1091,1012],{"class":1006},[466,1093,761],{"class":476},[466,1095,1096],{"class":767},"\"\u002Forders\u002F{orderId}\"",[466,1098,728],{"class":476},[466,1100,1102,1104,1106,1109],{"class":468,"line":1101},11,[466,1103,1024],{"class":1006},[466,1105,761],{"class":476},[466,1107,1108],{"class":767},"\"GetOrder\"",[466,1110,728],{"class":476},[466,1112,1114,1116,1118,1121,1123],{"class":468,"line":1113},12,[466,1115,1051],{"class":1006},[466,1117,761],{"class":476},[466,1119,1120],{"class":767},"\"orders.view\"",[466,1122,590],{"class":476},[466,1124,1125],{"class":784},"        \u002F\u002F tulajdonos vagy admin\n",[466,1127,1129,1132,1135,1138],{"class":468,"line":1128},13,[466,1130,1131],{"class":703},"getOrder(",[466,1133,1134],{"class":1006},"@path",[466,1136,1137],{"class":703}," orderId: string): Order | NotFound | Unauthorized | Forbidden",[466,1139,1074],{"class":476},[448,1141,1142,1145],{},[452,1143,1144],{},"mise run generate"," után a generált csomagban megjelennek a mapek:",[457,1147,1149],{"className":459,"code":1148,"language":461,"meta":462,"style":462},"\u002F\u002F internal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fapi\u002Fhttp\u002Fgen (generált, ne szerkeszd)\nvar PermissionByOperation = map[string]string{\n    \"PlaceOrder\": \"orders.place\",\n}\n\nvar PolicyByOperation = map[string]string{\n    \"PlaceOrder\": \"orders.place\",\n    \"GetOrder\":   \"orders.view\",\n}\n",[452,1150,1151,1156,1180,1202,1206,1210,1229,1247,1267],{"__ignoreMap":462},[466,1152,1153],{"class":468,"line":469},[466,1154,1155],{"class":784},"\u002F\u002F internal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fapi\u002Fhttp\u002Fgen (generált, ne szerkeszd)\n",[466,1157,1158,1161,1164,1167,1170,1173,1176,1178],{"class":468,"line":700},[466,1159,1160],{"class":476},"var",[466,1162,1163],{"class":703}," PermissionByOperation ",[466,1165,1166],{"class":476},"=",[466,1168,1169],{"class":476}," map[",[466,1171,1172],{"class":593},"string",[466,1174,1175],{"class":476},"]",[466,1177,1172],{"class":593},[466,1179,743],{"class":476},[466,1181,1182,1185,1188,1190,1192,1194,1197,1199],{"class":468,"line":731},[466,1183,1184],{"class":476},"    \"",[466,1186,1187],{"class":767},"PlaceOrder",[466,1189,764],{"class":476},[466,1191,533],{"class":476},[466,1193,477],{"class":476},[466,1195,1196],{"class":767},"orders.place",[466,1198,764],{"class":476},[466,1200,1201],{"class":476},",\n",[466,1203,1204],{"class":468,"line":746},[466,1205,803],{"class":476},[466,1207,1208],{"class":468,"line":775},[466,1209,1080],{"emptyLinePlaceholder":1079},[466,1211,1212,1214,1217,1219,1221,1223,1225,1227],{"class":468,"line":781},[466,1213,1160],{"class":476},[466,1215,1216],{"class":703}," PolicyByOperation ",[466,1218,1166],{"class":476},[466,1220,1169],{"class":476},[466,1222,1172],{"class":593},[466,1224,1175],{"class":476},[466,1226,1172],{"class":593},[466,1228,743],{"class":476},[466,1230,1231,1233,1235,1237,1239,1241,1243,1245],{"class":468,"line":788},[466,1232,1184],{"class":476},[466,1234,1187],{"class":767},[466,1236,764],{"class":476},[466,1238,533],{"class":476},[466,1240,477],{"class":476},[466,1242,1196],{"class":767},[466,1244,764],{"class":476},[466,1246,1201],{"class":476},[466,1248,1249,1251,1254,1256,1258,1261,1263,1265],{"class":468,"line":800},[466,1250,1184],{"class":476},[466,1252,1253],{"class":767},"GetOrder",[466,1255,764],{"class":476},[466,1257,533],{"class":476},[466,1259,1260],{"class":476},"   \"",[466,1262,513],{"class":767},[466,1264,764],{"class":476},[466,1266,1201],{"class":476},[466,1268,1269],{"class":468,"line":1083},[466,1270,803],{"class":476},[448,1272,1273,1274,1276,1277,1280],{},"Az enforcer bekötését az ",[495,1275,330],{"href":331}," generálja a ",[452,1278,1279],{},"Register\u003CSurface>"," függvénybe: kézzel semmit nem kell drótoznod.",[457,1282,1285],{"className":459,"code":1283,"filename":1284,"language":461,"meta":462,"style":462},"func RegisterApi(router chi.Router, deps Dependencies) {\n    apiSvc := apiservice.New()\n    apiHandler := apihttp.New(apiSvc)\n    apiPolicies := apipolicy.New()\n    router.Route(\"\u002Fshop\", func(r chi.Router) {\n        shopapigen.HandlerWithOptions(shopapigen.NewStrictHandlerWithOptions(\n            apiHandler,\n            []shopapigen.StrictMiddlewareFunc{\n                server.StrictValidator[shopapigen.StrictHandlerFunc](nil),\n                \u002F\u002F Az utolsó elem a legkülső: az authorizáció a validáció előtt fut.\n                kitpolicy.Enforcer[shopapigen.StrictHandlerFunc](apiPolicies, shopapigen.PermissionByOperation, shopapigen.PolicyByOperation),\n            },\n            shopapigen.StrictHTTPServerOptions{\n                RequestErrorHandlerFunc:  httperr.WriteBadRequest,\n                ResponseErrorHandlerFunc: server.WriteError,\n            },\n        ), shopapigen.ChiServerOptions{\n            BaseRouter:       r,\n            ErrorHandlerFunc: httperr.WriteBadRequest,\n        })\n    })\n}\n","internal\u002Fmodules\u002Fshop\u002Fregister.go",[452,1286,1287,1320,1337,1358,1374,1410,1432,1439,1453,1476,1481,1524,1529,1541,1559,1577,1582,1597,1610,1627,1633,1639],{"__ignoreMap":462},[466,1288,1289,1292,1295,1297,1300,1303,1305,1308,1310,1313,1316,1318],{"class":468,"line":469},[466,1290,1291],{"class":476},"func",[466,1293,1294],{"class":757}," RegisterApi",[466,1296,761],{"class":476},[466,1298,1299],{"class":552},"router",[466,1301,1302],{"class":480}," chi",[466,1304,559],{"class":476},[466,1306,1307],{"class":480},"Router",[466,1309,565],{"class":476},[466,1311,1312],{"class":552}," deps",[466,1314,1315],{"class":480}," Dependencies",[466,1317,590],{"class":476},[466,1319,697],{"class":476},[466,1321,1322,1325,1327,1330,1332,1335],{"class":468,"line":700},[466,1323,1324],{"class":703},"    apiSvc ",[466,1326,712],{"class":476},[466,1328,1329],{"class":703}," apiservice",[466,1331,559],{"class":476},[466,1333,1334],{"class":757},"New",[466,1336,832],{"class":476},[466,1338,1339,1342,1344,1347,1349,1351,1353,1356],{"class":468,"line":731},[466,1340,1341],{"class":703},"    apiHandler ",[466,1343,712],{"class":476},[466,1345,1346],{"class":703}," apihttp",[466,1348,559],{"class":476},[466,1350,1334],{"class":757},[466,1352,761],{"class":476},[466,1354,1355],{"class":703},"apiSvc",[466,1357,728],{"class":476},[466,1359,1360,1363,1365,1368,1370,1372],{"class":468,"line":746},[466,1361,1362],{"class":703},"    apiPolicies ",[466,1364,712],{"class":476},[466,1366,1367],{"class":703}," apipolicy",[466,1369,559],{"class":476},[466,1371,1334],{"class":757},[466,1373,832],{"class":476},[466,1375,1376,1379,1381,1384,1386,1388,1391,1393,1395,1397,1400,1402,1404,1406,1408],{"class":468,"line":775},[466,1377,1378],{"class":703},"    router",[466,1380,559],{"class":476},[466,1382,1383],{"class":757},"Route",[466,1385,761],{"class":476},[466,1387,764],{"class":476},[466,1389,1390],{"class":767},"\u002Fshop",[466,1392,764],{"class":476},[466,1394,565],{"class":476},[466,1396,549],{"class":476},[466,1398,1399],{"class":552},"r",[466,1401,1302],{"class":480},[466,1403,559],{"class":476},[466,1405,1307],{"class":480},[466,1407,590],{"class":476},[466,1409,697],{"class":476},[466,1411,1412,1415,1417,1420,1422,1424,1426,1429],{"class":468,"line":781},[466,1413,1414],{"class":703},"        shopapigen",[466,1416,559],{"class":476},[466,1418,1419],{"class":757},"HandlerWithOptions",[466,1421,761],{"class":476},[466,1423,720],{"class":703},[466,1425,559],{"class":476},[466,1427,1428],{"class":757},"NewStrictHandlerWithOptions",[466,1430,1431],{"class":476},"(\n",[466,1433,1434,1437],{"class":468,"line":788},[466,1435,1436],{"class":703},"            apiHandler",[466,1438,1201],{"class":476},[466,1440,1441,1444,1446,1448,1451],{"class":468,"line":800},[466,1442,1443],{"class":476},"            []",[466,1445,720],{"class":480},[466,1447,559],{"class":476},[466,1449,1450],{"class":480},"StrictMiddlewareFunc",[466,1452,743],{"class":476},[466,1454,1455,1458,1460,1463,1466,1468,1470,1473],{"class":468,"line":1083},[466,1456,1457],{"class":703},"                server",[466,1459,559],{"class":476},[466,1461,1462],{"class":757},"StrictValidator",[466,1464,1465],{"class":476},"[",[466,1467,720],{"class":480},[466,1469,559],{"class":476},[466,1471,1472],{"class":480},"StrictHandlerFunc",[466,1474,1475],{"class":476},"](nil),\n",[466,1477,1478],{"class":468,"line":1089},[466,1479,1480],{"class":784},"                \u002F\u002F Az utolsó elem a legkülső: az authorizáció a validáció előtt fut.\n",[466,1482,1483,1486,1488,1490,1492,1494,1496,1498,1501,1504,1506,1509,1511,1513,1515,1517,1519,1521],{"class":468,"line":1101},[466,1484,1485],{"class":703},"                kitpolicy",[466,1487,559],{"class":476},[466,1489,981],{"class":757},[466,1491,1465],{"class":476},[466,1493,720],{"class":480},[466,1495,559],{"class":476},[466,1497,1472],{"class":480},[466,1499,1500],{"class":476},"](",[466,1502,1503],{"class":703},"apiPolicies",[466,1505,565],{"class":476},[466,1507,1508],{"class":703}," shopapigen",[466,1510,559],{"class":476},[466,1512,959],{"class":703},[466,1514,565],{"class":476},[466,1516,1508],{"class":703},[466,1518,559],{"class":476},[466,1520,962],{"class":703},[466,1522,1523],{"class":476},"),\n",[466,1525,1526],{"class":468,"line":1113},[466,1527,1528],{"class":476},"            },\n",[466,1530,1531,1534,1536,1539],{"class":468,"line":1128},[466,1532,1533],{"class":480},"            shopapigen",[466,1535,559],{"class":476},[466,1537,1538],{"class":480},"StrictHTTPServerOptions",[466,1540,743],{"class":476},[466,1542,1544,1547,1549,1552,1554,1557],{"class":468,"line":1543},14,[466,1545,1546],{"class":703},"                RequestErrorHandlerFunc",[466,1548,533],{"class":476},[466,1550,1551],{"class":703},"  httperr",[466,1553,559],{"class":476},[466,1555,1556],{"class":703},"WriteBadRequest",[466,1558,1201],{"class":476},[466,1560,1562,1565,1567,1570,1572,1575],{"class":468,"line":1561},15,[466,1563,1564],{"class":703},"                ResponseErrorHandlerFunc",[466,1566,533],{"class":476},[466,1568,1569],{"class":703}," server",[466,1571,559],{"class":476},[466,1573,1574],{"class":703},"WriteError",[466,1576,1201],{"class":476},[466,1578,1580],{"class":468,"line":1579},16,[466,1581,1528],{"class":476},[466,1583,1585,1588,1590,1592,1595],{"class":468,"line":1584},17,[466,1586,1587],{"class":476},"        ),",[466,1589,1508],{"class":480},[466,1591,559],{"class":476},[466,1593,1594],{"class":480},"ChiServerOptions",[466,1596,743],{"class":476},[466,1598,1600,1603,1605,1608],{"class":468,"line":1599},18,[466,1601,1602],{"class":703},"            BaseRouter",[466,1604,533],{"class":476},[466,1606,1607],{"class":703},"       r",[466,1609,1201],{"class":476},[466,1611,1613,1616,1618,1621,1623,1625],{"class":468,"line":1612},19,[466,1614,1615],{"class":703},"            ErrorHandlerFunc",[466,1617,533],{"class":476},[466,1619,1620],{"class":703}," httperr",[466,1622,559],{"class":476},[466,1624,1556],{"class":703},[466,1626,1201],{"class":476},[466,1628,1630],{"class":468,"line":1629},20,[466,1631,1632],{"class":476},"        })\n",[466,1634,1636],{"class":468,"line":1635},21,[466,1637,1638],{"class":476},"    })\n",[466,1640,1642],{"class":468,"line":1641},22,[466,1643,803],{"class":476},[448,1645,1646,1647,1650,1651,1653,1654,1657,1658,1660],{},"(A ",[452,1648,1649],{},"kitpolicy"," itt a ",[452,1652,481],{}," aliasa: a surface-en belüli generált ",[452,1655,1656],{},"policy\u002F"," csomag maga is ",[452,1659,454],{}," névre hallgat, ezért a modul-importnak más lokális név kell az ütközés elkerüléséhez.)",[448,1662,1663,1664,1667,1668,1671,1672,1674],{},"A strict-middleware szeletben az ",[504,1665,1666],{},"utolsó elem a legkülső",", ezért az enforcer a validátorok előtt fut: a 401\u002F403 megelőzi a body-validációt, a policy tehát dekódolt, de még nem ",[495,1669,1670],{"href":401},"validált"," body-t lát. (A generikus típusparaméter azért kell, mert az oapi-codegen generált csomagonként definiálja a ",[452,1673,1472],{}," típust.)",[1676,1677,1678,1679,1682,1683,490,1686,1689,1690,1692,1693,1696],"note",{},"Az enforcer csak ",[499,1680,1681],{},"ellenőrzi"," az identityt: ",[499,1684,1685],{},"előállítani",[495,1687,1688],{"href":89},"auth middleware"," állítja elő a Bearer tokenből. Vegyes surface-nél (publikus + védett műveletek, mint a shop ",[452,1691,988],{},"-ja) a token-parseolást tedd feltételessé, a mintát az ",[495,1694,1695],{"href":89},"autentikáció"," oldal mutatja; a taggelt műveletek identity nélkül itt, az enforcerben kapnak 401-et.",[523,1698,1700],{"id":1699},"szemantika-pontosan","Szemantika, pontosan",[448,1702,1703],{},"Az enforcer műveletenként a következők szerint dönt:",[1705,1706,1707,1720],"table",{},[1708,1709,1710],"thead",{},[1711,1712,1713,1717],"tr",{},[1714,1715,1716],"th",{},"Helyzet",[1714,1718,1719],{},"Eredmény",[1721,1722,1723,1737,1750,1764,1780],"tbody",{},[1711,1724,1725,1734],{},[1726,1727,1728,1729,1731,1732],"td",{},"a műveleten nincs se ",[452,1730,1036],{},", se ",[452,1733,1051],{},[1726,1735,1736],{},"átengedés, identity sem kell",[1711,1738,1739,1742],{},[1726,1740,1741],{},"taggelt művelet, nincs identity a contextben",[1726,1743,1744,611,1747],{},[504,1745,1746],{},"401",[452,1748,1749],{},"authentication required",[1711,1751,1752,1757],{},[1726,1753,1754,1756],{},[452,1755,1036],{}," van, de a user nem birtokolja",[1726,1758,1759,611,1761],{},[504,1760,642],{},[452,1762,1763],{},"insufficient privileges",[1711,1765,1766,1772],{},[1726,1767,1768,1769,590],{},"a policy hibát ad (tipikusan ",[452,1770,1771],{},"policy.Deny(...)",[1726,1773,1774,1775,611,1777,1779],{},"az a hiba megy ki (a ",[452,1776,758],{},[504,1778,642],{},", a detail üzenettel)",[1711,1781,1782,1788],{},[1726,1783,1784,1785,1787],{},"a ",[452,1786,1051],{}," név nincs regisztrálva a Registry-ben",[1726,1789,1790,1793,1794,1797],{},[504,1791,1792],{},"fail-closed",": sima error → ",[504,1795,1796],{},"500"," (szerver-félrekonfiguráció, nem kliens-hiba)",[448,1799,1800,1801,1804,1805,1808],{},"Ha mindkét tag rajta van a műveleten, a ",[504,1802,1803],{},"permission fut előbb",": a policy már csak akkor, ha a jog megvan. A regisztrálatlan policy nem 403: az nem a hívó hibája, hanem a tiéd, és 500-ként (stackkel, ",[495,1806,1807],{"href":194},"Sentry-riasztással",") akarod észrevenni, nem néma tiltásként.",[523,1810,1812],{"id":1811},"a-shop-orderpolicy-végigjátszva","A shop OrderPolicy végigjátszva",[448,1814,1815,1816,1818,1819,1821,1822,1824,1825,1828,1829,1831,1832,1834],{},"Az ",[452,1817,330],{}," minden surface-hez scaffoldol egy ",[452,1820,1656],{}," csomagot registry-stubbal: neked csak a ",[452,1823,842],{}," hívásokat kell megírnod a ",[452,1826,1827],{},"gpsystem:policies"," anchornál. A shop ",[452,1830,513],{}," policy-je a tulajdonos-vagy-admin szabály; az ",[452,1833,1196],{}," azt zárja ki, hogy valaki más nevében adj fel rendelést:",[457,1836,1838],{"className":459,"code":1837,"language":461,"meta":462,"style":462},"\u002F\u002F internal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fapi\u002Fpolicy\u002Fpolicy.go\npackage policy\n\nimport (\n    \"context\"\n\n    kitpolicy \"github.com\u002Fgp-system\u002Fauth\u002Fpolicy\"\n    \"github.com\u002Fgp-system\u002Fauth\u002Frbac\"\n\n    gen \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fapi\u002Fhttp\u002Fgen\"\n    \"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Frepository\"\n)\n\nfunc New(orders *repository.OrderRepo) *kitpolicy.Registry {\n    reg := kitpolicy.NewRegistry()\n    \u002F\u002F gpsystem:policies\n    reg.Register(\"orders.view\", func(ctx context.Context, id *rbac.Identity, req any) error {\n        if id.HasRole(\"admin\") {\n            return nil\n        }\n        r, ok := req.(gen.GetOrderRequest)\n        if !ok {\n            return kitpolicy.Deny(\"unexpected request type\")\n        }\n        order, err := orders.GetByID(ctx, r.OrderId) \u002F\u002F DB-hozzáférés closure-rel\n        if err != nil {\n            return err\n        }\n        if order.UserID != id.Subject {\n            return kitpolicy.Deny(\"You can only view your own orders.\")\n        }\n        return nil\n    })\n    reg.Register(\"orders.place\", func(ctx context.Context, id *rbac.Identity, req any) error {\n        r, ok := req.(gen.PlaceOrderRequest)\n        if !ok {\n            return kitpolicy.Deny(\"unexpected request type\")\n        }\n        if r.Body.CustomerId != id.Subject {\n            return kitpolicy.Deny(\"You can only place orders on your own behalf.\")\n        }\n        return nil\n    })\n    return reg\n}\n",[452,1839,1840,1845,1853,1857,1864,1872,1876,1887,1896,1900,1912,1921,1925,1929,1963,1979,1984,2037,2062,2070,2075,2099,2109,2130,2135,2175,2189,2197,2202,2226,2248,2253,2260,2265,2318,2342,2353,2374,2379,2406,2428,2433,2440,2445,2453],{"__ignoreMap":462},[466,1841,1842],{"class":468,"line":469},[466,1843,1844],{"class":784},"\u002F\u002F internal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fapi\u002Fpolicy\u002Fpolicy.go\n",[466,1846,1847,1850],{"class":468,"line":700},[466,1848,1849],{"class":476},"package",[466,1851,1852],{"class":480}," policy\n",[466,1854,1855],{"class":468,"line":731},[466,1856,1080],{"emptyLinePlaceholder":1079},[466,1858,1859,1861],{"class":468,"line":746},[466,1860,473],{"class":472},[466,1862,1863],{"class":476}," (\n",[466,1865,1866,1868,1870],{"class":468,"line":775},[466,1867,1184],{"class":476},[466,1869,663],{"class":480},[466,1871,484],{"class":476},[466,1873,1874],{"class":468,"line":781},[466,1875,1080],{"emptyLinePlaceholder":1079},[466,1877,1878,1881,1883,1885],{"class":468,"line":788},[466,1879,1880],{"class":703},"    kitpolicy ",[466,1882,764],{"class":476},[466,1884,481],{"class":480},[466,1886,484],{"class":476},[466,1888,1889,1891,1894],{"class":468,"line":800},[466,1890,1184],{"class":476},[466,1892,1893],{"class":480},"github.com\u002Fgp-system\u002Fauth\u002Frbac",[466,1895,484],{"class":476},[466,1897,1898],{"class":468,"line":1083},[466,1899,1080],{"emptyLinePlaceholder":1079},[466,1901,1902,1905,1907,1910],{"class":468,"line":1089},[466,1903,1904],{"class":703},"    gen ",[466,1906,764],{"class":476},[466,1908,1909],{"class":480},"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fapi\u002Fhttp\u002Fgen",[466,1911,484],{"class":476},[466,1913,1914,1916,1919],{"class":468,"line":1101},[466,1915,1184],{"class":476},[466,1917,1918],{"class":480},"github.com\u002Facme\u002Fshop\u002Finternal\u002Fmodules\u002Fshop\u002Frepository",[466,1920,484],{"class":476},[466,1922,1923],{"class":468,"line":1113},[466,1924,728],{"class":476},[466,1926,1927],{"class":468,"line":1128},[466,1928,1080],{"emptyLinePlaceholder":1079},[466,1930,1931,1933,1936,1938,1941,1943,1946,1948,1951,1953,1955,1957,1959,1961],{"class":468,"line":1543},[466,1932,1291],{"class":476},[466,1934,1935],{"class":757}," New",[466,1937,761],{"class":476},[466,1939,1940],{"class":552},"orders",[466,1942,571],{"class":476},[466,1944,1945],{"class":480},"repository",[466,1947,559],{"class":476},[466,1949,1950],{"class":480},"OrderRepo",[466,1952,590],{"class":476},[466,1954,571],{"class":476},[466,1956,1649],{"class":480},[466,1958,559],{"class":476},[466,1960,809],{"class":480},[466,1962,697],{"class":476},[466,1964,1965,1968,1970,1973,1975,1977],{"class":468,"line":1561},[466,1966,1967],{"class":703},"    reg ",[466,1969,712],{"class":476},[466,1971,1972],{"class":703}," kitpolicy",[466,1974,559],{"class":476},[466,1976,829],{"class":757},[466,1978,832],{"class":476},[466,1980,1981],{"class":468,"line":1579},[466,1982,1983],{"class":784},"    \u002F\u002F gpsystem:policies\n",[466,1985,1986,1989,1991,1993,1995,1997,1999,2001,2003,2005,2007,2009,2011,2013,2015,2017,2019,2021,2023,2025,2027,2029,2031,2033,2035],{"class":468,"line":1584},[466,1987,1988],{"class":703},"    reg",[466,1990,559],{"class":476},[466,1992,842],{"class":757},[466,1994,761],{"class":476},[466,1996,764],{"class":476},[466,1998,513],{"class":767},[466,2000,764],{"class":476},[466,2002,565],{"class":476},[466,2004,549],{"class":476},[466,2006,553],{"class":552},[466,2008,556],{"class":480},[466,2010,559],{"class":476},[466,2012,562],{"class":480},[466,2014,565],{"class":476},[466,2016,568],{"class":552},[466,2018,571],{"class":476},[466,2020,574],{"class":480},[466,2022,559],{"class":476},[466,2024,579],{"class":480},[466,2026,565],{"class":476},[466,2028,584],{"class":552},[466,2030,587],{"class":480},[466,2032,590],{"class":476},[466,2034,694],{"class":593},[466,2036,697],{"class":476},[466,2038,2039,2042,2044,2046,2049,2051,2053,2056,2058,2060],{"class":468,"line":1599},[466,2040,2041],{"class":472},"        if",[466,2043,568],{"class":703},[466,2045,559],{"class":476},[466,2047,2048],{"class":757},"HasRole",[466,2050,761],{"class":476},[466,2052,764],{"class":476},[466,2054,2055],{"class":767},"admin",[466,2057,764],{"class":476},[466,2059,590],{"class":476},[466,2061,697],{"class":476},[466,2063,2064,2067],{"class":468,"line":1612},[466,2065,2066],{"class":472},"            return",[466,2068,2069],{"class":476}," nil\n",[466,2071,2072],{"class":468,"line":1629},[466,2073,2074],{"class":476},"        }\n",[466,2076,2077,2080,2082,2084,2086,2088,2090,2093,2095,2097],{"class":468,"line":1635},[466,2078,2079],{"class":703},"        r",[466,2081,565],{"class":476},[466,2083,709],{"class":703},[466,2085,712],{"class":476},[466,2087,584],{"class":703},[466,2089,717],{"class":476},[466,2091,2092],{"class":480},"gen",[466,2094,559],{"class":476},[466,2096,725],{"class":480},[466,2098,728],{"class":476},[466,2100,2101,2103,2105,2107],{"class":468,"line":1641},[466,2102,2041],{"class":472},[466,2104,737],{"class":476},[466,2106,740],{"class":703},[466,2108,743],{"class":476},[466,2110,2112,2114,2116,2118,2120,2122,2124,2126,2128],{"class":468,"line":2111},23,[466,2113,2066],{"class":472},[466,2115,1972],{"class":703},[466,2117,559],{"class":476},[466,2119,758],{"class":757},[466,2121,761],{"class":476},[466,2123,764],{"class":476},[466,2125,768],{"class":767},[466,2127,764],{"class":476},[466,2129,728],{"class":476},[466,2131,2133],{"class":468,"line":2132},24,[466,2134,2074],{"class":476},[466,2136,2138,2141,2143,2146,2148,2151,2153,2156,2158,2160,2162,2165,2167,2170,2172],{"class":468,"line":2137},25,[466,2139,2140],{"class":703},"        order",[466,2142,565],{"class":476},[466,2144,2145],{"class":703}," err ",[466,2147,712],{"class":476},[466,2149,2150],{"class":703}," orders",[466,2152,559],{"class":476},[466,2154,2155],{"class":757},"GetByID",[466,2157,761],{"class":476},[466,2159,553],{"class":703},[466,2161,565],{"class":476},[466,2163,2164],{"class":703}," r",[466,2166,559],{"class":476},[466,2168,2169],{"class":703},"OrderId",[466,2171,590],{"class":476},[466,2173,2174],{"class":784}," \u002F\u002F DB-hozzáférés closure-rel\n",[466,2176,2178,2180,2182,2185,2187],{"class":468,"line":2177},26,[466,2179,2041],{"class":472},[466,2181,2145],{"class":703},[466,2183,2184],{"class":476},"!=",[466,2186,794],{"class":476},[466,2188,697],{"class":476},[466,2190,2192,2194],{"class":468,"line":2191},27,[466,2193,2066],{"class":472},[466,2195,2196],{"class":703}," err\n",[466,2198,2200],{"class":468,"line":2199},28,[466,2201,2074],{"class":476},[466,2203,2205,2207,2210,2212,2215,2217,2219,2221,2224],{"class":468,"line":2204},29,[466,2206,2041],{"class":472},[466,2208,2209],{"class":703}," order",[466,2211,559],{"class":476},[466,2213,2214],{"class":703},"UserID ",[466,2216,2184],{"class":476},[466,2218,568],{"class":703},[466,2220,559],{"class":476},[466,2222,2223],{"class":703},"Subject ",[466,2225,743],{"class":476},[466,2227,2229,2231,2233,2235,2237,2239,2241,2244,2246],{"class":468,"line":2228},30,[466,2230,2066],{"class":472},[466,2232,1972],{"class":703},[466,2234,559],{"class":476},[466,2236,758],{"class":757},[466,2238,761],{"class":476},[466,2240,764],{"class":476},[466,2242,2243],{"class":767},"You can only view your own orders.",[466,2245,764],{"class":476},[466,2247,728],{"class":476},[466,2249,2251],{"class":468,"line":2250},31,[466,2252,2074],{"class":476},[466,2254,2256,2258],{"class":468,"line":2255},32,[466,2257,749],{"class":472},[466,2259,2069],{"class":476},[466,2261,2263],{"class":468,"line":2262},33,[466,2264,1638],{"class":476},[466,2266,2268,2270,2272,2274,2276,2278,2280,2282,2284,2286,2288,2290,2292,2294,2296,2298,2300,2302,2304,2306,2308,2310,2312,2314,2316],{"class":468,"line":2267},34,[466,2269,1988],{"class":703},[466,2271,559],{"class":476},[466,2273,842],{"class":757},[466,2275,761],{"class":476},[466,2277,764],{"class":476},[466,2279,1196],{"class":767},[466,2281,764],{"class":476},[466,2283,565],{"class":476},[466,2285,549],{"class":476},[466,2287,553],{"class":552},[466,2289,556],{"class":480},[466,2291,559],{"class":476},[466,2293,562],{"class":480},[466,2295,565],{"class":476},[466,2297,568],{"class":552},[466,2299,571],{"class":476},[466,2301,574],{"class":480},[466,2303,559],{"class":476},[466,2305,579],{"class":480},[466,2307,565],{"class":476},[466,2309,584],{"class":552},[466,2311,587],{"class":480},[466,2313,590],{"class":476},[466,2315,694],{"class":593},[466,2317,697],{"class":476},[466,2319,2321,2323,2325,2327,2329,2331,2333,2335,2337,2340],{"class":468,"line":2320},35,[466,2322,2079],{"class":703},[466,2324,565],{"class":476},[466,2326,709],{"class":703},[466,2328,712],{"class":476},[466,2330,584],{"class":703},[466,2332,717],{"class":476},[466,2334,2092],{"class":480},[466,2336,559],{"class":476},[466,2338,2339],{"class":480},"PlaceOrderRequest",[466,2341,728],{"class":476},[466,2343,2345,2347,2349,2351],{"class":468,"line":2344},36,[466,2346,2041],{"class":472},[466,2348,737],{"class":476},[466,2350,740],{"class":703},[466,2352,743],{"class":476},[466,2354,2356,2358,2360,2362,2364,2366,2368,2370,2372],{"class":468,"line":2355},37,[466,2357,2066],{"class":472},[466,2359,1972],{"class":703},[466,2361,559],{"class":476},[466,2363,758],{"class":757},[466,2365,761],{"class":476},[466,2367,764],{"class":476},[466,2369,768],{"class":767},[466,2371,764],{"class":476},[466,2373,728],{"class":476},[466,2375,2377],{"class":468,"line":2376},38,[466,2378,2074],{"class":476},[466,2380,2382,2384,2386,2388,2391,2393,2396,2398,2400,2402,2404],{"class":468,"line":2381},39,[466,2383,2041],{"class":472},[466,2385,2164],{"class":703},[466,2387,559],{"class":476},[466,2389,2390],{"class":703},"Body",[466,2392,559],{"class":476},[466,2394,2395],{"class":703},"CustomerId ",[466,2397,2184],{"class":476},[466,2399,568],{"class":703},[466,2401,559],{"class":476},[466,2403,2223],{"class":703},[466,2405,743],{"class":476},[466,2407,2409,2411,2413,2415,2417,2419,2421,2424,2426],{"class":468,"line":2408},40,[466,2410,2066],{"class":472},[466,2412,1972],{"class":703},[466,2414,559],{"class":476},[466,2416,758],{"class":757},[466,2418,761],{"class":476},[466,2420,764],{"class":476},[466,2422,2423],{"class":767},"You can only place orders on your own behalf.",[466,2425,764],{"class":476},[466,2427,728],{"class":476},[466,2429,2431],{"class":468,"line":2430},41,[466,2432,2074],{"class":476},[466,2434,2436,2438],{"class":468,"line":2435},42,[466,2437,749],{"class":472},[466,2439,2069],{"class":476},[466,2441,2443],{"class":468,"line":2442},43,[466,2444,1638],{"class":476},[466,2446,2448,2450],{"class":468,"line":2447},44,[466,2449,791],{"class":472},[466,2451,2452],{"class":703}," reg\n",[466,2454,2456],{"class":468,"line":2455},45,[466,2457,803],{"class":476},[448,2459,2460,2461,2464,2465,2468,2469,2472,2473,2475],{},"A generált stub ",[452,2462,2463],{},"New()","-ja paraméter nélküli; ha a policy-nak repository kell (mint itt), bővítsd a szignatúrát, és igazítsd az egyetlen hívóhelyét a ",[452,2466,2467],{},"register.go","-ban (",[452,2470,2471],{},"apipolicy.New(orderRepo)","). A ",[452,2474,1279],{}," függvény a tiéd, a generátor csak létrehozáskor írta.",[448,2477,2478,2479,2482],{},"Így fut le egy ",[452,2480,2481],{},"GET \u002Fapi\u002Fv1\u002Fshop\u002Forders\u002F42"," az egyes esetekben:",[1705,2484,2485,2498],{},[1708,2486,2487],{},[1711,2488,2489,2492,2495],{},[1714,2490,2491],{},"Hívó",[1714,2493,2494],{},"Lefutás",[1714,2496,2497],{},"Válasz",[1721,2499,2500,2513,2535,2554,2573],{},[1711,2501,2502,2505,2508],{},[1726,2503,2504],{},"token nélkül",[1726,2506,2507],{},"taggelt művelet, nincs identity",[1726,2509,2510,2512],{},[504,2511,1746],{}," problem",[1711,2514,2515,2518,2529],{},[1726,2516,2517],{},"a 42-es rendelés gazdája",[1726,2519,2520,2522,2523,2525,2526],{},[452,2521,513],{}," → nem admin → ",[452,2524,2155],{}," → ",[452,2527,2528],{},"UserID == Subject",[1726,2530,2531,2534],{},[504,2532,2533],{},"200",", a handler fut",[1711,2536,2537,2540,2548],{},[1726,2538,2539],{},"másik bejelentkezett user",[1726,2541,2542,2543,2525,2546],{},"ugyanez, de ",[452,2544,2545],{},"UserID != Subject",[452,2547,758],{},[1726,2549,2550,611,2552],{},[504,2551,642],{},[452,2553,2243],{},[1711,2555,2556,2561,2569],{},[1726,2557,2558,2560],{},[452,2559,2055],{}," szerepű user",[1726,2562,2563,2525,2565,2568],{},[452,2564,513],{},[452,2566,2567],{},"HasRole(\"admin\")"," → azonnali engedély",[1726,2570,2571,2534],{},[504,2572,2533],{},[1711,2574,2575,2581,2584],{},[1726,2576,2577,2578,2580],{},"bárki, ha az ",[452,2579,513],{}," nincs regisztrálva",[1726,2582,2583],{},"fail-closed error",[1726,2585,2586,2588,2589],{},[504,2587,1796],{}," + stack, ",[452,2590,2591],{},"policy \"orders.view\" ... is not registered",[448,2593,487,2594,2596,2597,611,2599,2602,2603,611,2605,559],{},[452,2595,1187],{},"-nél ugyanez a lánc egy lépéssel hosszabb: előbb az ",[452,2598,1196],{},[504,2600,2601],{},"permission"," (nincs meg → 403), és csak utána az ",[452,2604,1196],{},[504,2606,454],{},[523,2608,2610],{"id":2609},"új-művelet-policy-val","Új művelet policy-val",[448,2612,1815,2613,2615,2616,925,2619,2622],{},[495,2614,339],{"href":340}," parancs ",[452,2617,2618],{},"--permission",[452,2620,2621],{},"--policy"," flagekkel eleve megjelölt műveletet generál a kontraktusba, és emlékeztet a regisztrációra:",[457,2624,2628],{"className":2625,"code":2626,"language":2627,"meta":462,"style":462},"language-sh shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","go tool gpsystem add handler shop api getOrder --method get --path \"\u002Forders\u002F{orderId}\" \\\n  --policy \"orders.view\"\n# ...\n#   # register policy \"orders.view\" in internal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fapi\u002Fpolicy\u002Fpolicy.go\n","sh",[452,2629,2630,2674,2685,2690],{"__ignoreMap":462},[466,2631,2632,2634,2637,2640,2643,2646,2649,2652,2655,2658,2661,2664,2666,2669,2671],{"class":468,"line":469},[466,2633,461],{"class":480},[466,2635,2636],{"class":767}," tool",[466,2638,2639],{"class":767}," gpsystem",[466,2641,2642],{"class":767}," add",[466,2644,2645],{"class":767}," handler",[466,2647,2648],{"class":767}," shop",[466,2650,2651],{"class":767}," api",[466,2653,2654],{"class":767}," getOrder",[466,2656,2657],{"class":767}," --method",[466,2659,2660],{"class":767}," get",[466,2662,2663],{"class":767}," --path",[466,2665,477],{"class":476},[466,2667,2668],{"class":767},"\u002Forders\u002F{orderId}",[466,2670,764],{"class":476},[466,2672,2673],{"class":703}," \\\n",[466,2675,2676,2679,2681,2683],{"class":468,"line":700},[466,2677,2678],{"class":767},"  --policy",[466,2680,477],{"class":476},[466,2682,513],{"class":767},[466,2684,484],{"class":476},[466,2686,2687],{"class":468,"line":731},[466,2688,2689],{"class":784},"# ...\n",[466,2691,2692],{"class":468,"line":746},[466,2693,2694],{"class":784},"#   # register policy \"orders.view\" in internal\u002Fmodules\u002Fshop\u002Fsurfaces\u002Fapi\u002Fpolicy\u002Fpolicy.go\n",[448,2696,2697,2698,2700,2701,2703,2704,2707,2708,2711],{},"A lánc többi állomása: ",[495,2699,1695],{"href":89}," (honnan lesz identity), ",[495,2702,93],{"href":94}," (szerep- és permission-ellenőrzés), és a ",[495,2705,2706],{"href":234},"codegen-pipeline"," (hogyan lesz a ",[452,2709,2710],{},".tsp","-ből futó kód).",[2713,2714,2715],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}",{"title":462,"searchDepth":700,"depth":700,"links":2717},[2718,2719,2720,2721,2722],{"id":525,"depth":700,"text":526},{"id":907,"depth":700,"text":908},{"id":1699,"depth":700,"text":1700},{"id":1811,"depth":700,"text":1812},{"id":2609,"depth":700,"text":2610},"Kérésenkénti, user-szintű engedélyezés a szerepek fölött: a kontraktusban deklarálva, generált kódból kikényszerítve.","md",null,{},{"icon":101},{"title":98,"description":2723},"cxD-NjsEgjhoTQHCID-Q5Dgk7YlIrAMdW6XVS2EB180",[2731,2733],{"title":93,"path":94,"stem":95,"description":2732,"icon":96,"children":-1},"Szerep- és permission-ellenőrzések a contextben utazó Identity fölött: route-guardokkal és service-rétegbeli lekérdezéssel.",{"title":103,"path":104,"stem":105,"description":2734,"icon":106,"children":-1},"Teljes, futtatható példa, ami az auth-on kívül semmilyen gp-system függőséget nem igényel: HTTP-vel és anélkül is.",1785445877247]